需求:勾选多条数据,点击‘打印’按钮,可以生成多页内容,打印出多页。打印界面可以点击‘上一页’、‘下一页’等功能。
参考了这篇文章
我的实现:写一个单独的组件,即想要打印的内容,在Index页面中引入,但隐藏不显示。(可以设置最外层样式为:z-index=-1,position:absolute,visibility:hidden)
//Index.tsx
import React, { useState } from 'react'
import { Button } from 'antd'
import Detail from './Detail'
const dataList = [{
name: '测试打印111',
date: '2022-4-1',
children: [{
name: '111'
}, {
name: '222'
}]
}, {
name: '测试打印222',
date: '2022-4-2'
},]
export default function IndexPage() {
const printPageView = () => {
let LODOP = window.getLodop();
if (LODOP) {
// http://www.c-lodop.com/blogs/Blog002.html
// SET_PRINT_PAGESIZE(intOrient,intPageWidth,intPageHeight,strPageName)设置参考:https://blog.csdn.net/weixin_34023982/article/details/91559966
// intOrient---指定打印方向 0--可通过打印机选择纵向或横向,1--锁定为纵向打印,2---锁定为横向,3---纵向打印,宽度固定,高度按打印内容的高度自适应;
// intPageWidth---第一个0 打印纸张的宽度 为0 ,可自定义宽
// intPageHeight---第二个0 打印纸张的高度 为 0 ,可自定义高
// strPageName---A4 指定用 A4 纸打印
// 当宽度和高度都设为 0 的时候,才能指定用特定的纸型打印,如:A4 ,B5 等。
LODOP.PRINT_INIT("");//初始化在循环外
LODOP.SET_PRINT_PAGESIZE(1, 300, 500, "");
for (let i = 0; i < dataList.length; i++) {
LODOP.NewPage();
let strStyle = `<style></style> `;
LODOP.ADD_PRINT_HTM(10, "5%", "90%", 450, strStyle + document.getElementById(i.toString()).innerHTML);
}
LODOP.PREVIEW();
}
};
return (<div>
<Button type='primary' onClick={printPageView}>打印</Button>
{
dataList.map((it, index) => {
return <Detail key={index} data={it} index={index.toString()} />
})
}
<div>其他内容区</div>
</div>
);
}
//Detail.tsx
import React from 'react'
import styles from './print.less'
const contentStyle = {
warp: {
width: 595,
height: 842
},
title: {
width: '100%',
textAlign: 'center'
},
row: {
display: 'flex'
},
col: {
flex: 1
},
table: {
width: '100%',
borderRight: '1px solid #000',
borderBottom: '1px solid #000'
},
td: {
textAlign: 'center',
height: 32
}
}
export default function Detail(props: any) {
const { data, index } = props;
const { children } = data
return (
<div style={contentStyle.warp} id={index} className={styles.content}>
<div style={contentStyle.title}>{data.name}</div>
</div>
)
}
此时页面看不到你要打印的页面,但是存在的。
(因为打印方法要获取dom节点,来获取打印区)
到这里,打印实现了,但是发现一个问题,如果未安装clodop或者版本太低,出现提示文字后,页面就完全不能操作了。(原因不详)
解决方案:把提示文字暴露到页面,自己渲染。
//Index.tsx
import React, { useState } from 'react'
import { Button } from 'antd'
import Detail from './Detail'
const dataList = [{
name: '测试打印111',
date: '2022-4-1',
children: [{
name: '111'
}, {
name: '222'
}]
}, {
name: '测试打印222',
date: '2022-4-2'
},]
export default function IndexPage() {
const [message, setMessage] = useState('')
const printPageView = () => {
//1、传入一个接受提示内容的方法
let LODOP = window.getLodop(getMsg);
if (LODOP) {
LODOP.PRINT_INIT("");//初始化在循环外
LODOP.SET_PRINT_PAGESIZE(1, 300, 500, "");
for (let i = 0; i < dataList.length; i++) {
LODOP.NewPage();
let strStyle = `<style></style> `;
LODOP.ADD_PRINT_HTM(10, "5%", "90%", 450, strStyle + document.getElementById(i.toString()).innerHTML);
}
LODOP.PREVIEW();
}
};
// 2、获取提示内容
const getMsg = (val:string) => {
setMessage(val)
}
return (<div>
//3、展示提示内容
<div dangerouslySetInnerHTML={{ __html: message }} ></div>
<Button type='primary' onClick={printPageView}>打印</Button>
{
dataList.map((it, index) => {
return <Detail key={index} data={it} index={index.toString()} />
})
}
<div>其他内容区</div>
</div>
);
}
同时,需要改造LodopFuncs.js
有好的方法欢迎交流