背景:前段时间把Luckysheet集成进了Datart,以实现报表功能,然后发现Luckysheet自己是不带打印功能的,为实现打印,于是就有了这篇…
一、实现思路
- 先利用Luckysheet内置的getSheetData()、setRangeShow() 等api获取表格需要打印的区域(在此我选区的逻辑时:选取表格不为空、且有内容的矩形区域);
- 再根据getScreenshot() 将前面选好的区域生成BASE64图片;
- 最后,利用Lodop的图片打印ADD_PRINT_IMAGE(),打印出我们需要的表格。
二、安装、使用Lodop
1、下载Lodop资源:
2、使用Lodop:
- 前端根目录下的dist/build文件夹里新建lodop文件夹,将前三个.exe文件放入其中;
- 前端根目录下的src文件夹里新建lodop文件夹,将后两个.js文件放入其中(这两个.js文件存放了我配置的打印模板,按需引用,方便维护);
- 业务代码引用依赖:import { getLodop } from ‘lodop/LodopFuncs’;
三、上代码
- 引入Lodop依赖:
import { getLodop } from 'lodop/LodopFuncs'; // Lodop打印
- 打印按钮:
<Button
icon={<PrinterOutlined />}
style={buttonCss}
onClick={() => handlePrint()}
>
打印
</Button>
- 打印方法:
/** 打印 */
const handlePrint = async () => {
printSheet();
};
/** 打印操作 */
const printSheet = () => {
// 获取打印区域的行列
let RowColumn = getPrintSheetArea();
// 因需要打印左边的边框,需重新设置第一列
RowColumn.column[0] = 0 as any;
// 进行选区操作
luckysheet.current.setRangeShow(RowColumn);
// 生成base64图片(*将生成的base64编码复制粘贴到浏览器地址框,是可以预览图片样式的)
let imgSrc = luckysheet.current.getScreenshot();
// * Lodop中的ADD_PRINT_IMAGE,也可以直接输出base64码图片,不用加img标签(如果加了img标签,会被当做超文本对待,受浏览器引擎解析的影响)
// let img = `<img src=${imgSrc} style="width: 100%;position: absolute;left:-20px" />`;
lodopPrintSheet(imgSrc);
}
// 获取打印区域(即表格中有内容、非空白的区域)(用row,column数组表示)
const getPrintSheetArea = () => {
const sheetData = luckysheet.current.getSheetData();
let objRowColumn = {
row: [null, null], //行
column: [null, null], //列
};
// * item是行、index是行索引、it是一行里的一格、itemIndex是这一格在这一行里的列索引
sheetData.forEach((item, index) => {
//行数
item.forEach((it, itemIndex) => {
if (it !== null) {
if (objRowColumn.row[0] == null) objRowColumn.row[0] = index; // row第一位
objRowColumn.row[1] = index; //row第二位
if (objRowColumn.column[0] == null)
objRowColumn.column[0] = itemIndex; //column第一位
objRowColumn.column[1] = itemIndex; //column第二位
}
});
});
return objRowColumn;
};
/** lodop执行打印(BASE64编码输出图片) */
const lodopPrintSheet = (img) => {
console.log('打印的base64图片:' + img);
const LODOP = getLodop();
LODOP.PRINT_INITA(0, 0, '210mm', '297mm', ''); // 初始化(上边距、左边距、宽度、高度、打印任务名)
LODOP.SET_PRINT_PAGESIZE(1, '210mm', '297mm', '') // 设置打印纸张(纵(正)向打印,固定纸张;A4纸)
LODOP.ADD_PRINT_IMAGE(0, 0, "100%", "100%", img); // 打印图片(上边距、左边距、宽度、高度、图片文件)
LODOP.SET_PRINT_STYLEA(0, "Stretch", 2); // 图片截取缩放模式(0:截取图片;1:扩展(可变形)缩放;2:按原图长和宽比例(不变形)缩放)
// LODOP.PRINT_DESIGN(); // 【设计】模式
LODOP.PREVIEW(); // 【预览】模式(*预览界面里点击打印出来的无水印)
// LODOP.PRINT(); // 【打印】模式(*直接打印里点击打出来的左下角会有水印)
}
四、测试
预览页面看着挺好的,可是实际打印出现了奇怪的情况…
实际打印的PDF,右侧和下面的图片被截取了…
假预览?/其实不是
寻求Lodop群客服大大帮助,解决方法:下载虚拟打印机软件再测试打印
下载、安装Doro虚拟打印机(在控制面板中能找到Doro PDF Writer打印机即证明安装好了)
最后再试一次
五、最终打印
报表预览页面点击打印按钮:
弹出Lodop打印预览页面,点击打印、选择Doro打印机、点击确定:
在Doro的弹窗里修改生成PDF的名称,点击创建,然后就会在桌面生成对应的PDF文件:
打开虚拟打印机生成的pdf文件:
纸张打印效果(一般PDF啥样打出来的就是啥样):
杀青~