react封装一个打印功能
1创建一个utils文件夹 下的打印js文件 printUtils
const JsBarcode = require('jsbarcode'); // 条形码
//创建打印iframe框架
const createPrintIframe = () => {
if (document.getElementById('printIframe')) {
document.body.removeChild(document.getElementById('printIframe'));
}
let iframe = document.createElement('iframe');
iframe.id = 'printIframe';
iframe.style.width = '100%';
iframe.style.height = '100%';
iframe.style.display = 'none';
return iframe;
};
//创建table表头
const createCaption = (title) => {
let caption = document.createElement('div');
caption.innerText = title;
return caption;
};
//根据倍数拆分数组
const sliceArry = (num, data) => {
let submitData = [];
let tempNum = 0;
for (let i = 0; i < data.length; i++) {
if (i % num == 0 && i != 0) {
submitData.push(data.slice(tempNum, i));
tempNum = i;
}
if (i + 1 == data.length) {
submitData.push(data.slice(tempNum, i + 1));
}
}
return submitData;
};
// //创建table基础信息
// const createThead = (data, columns) => {
// let thead = document.createElement('thead');
// let tr = document.createElement('tr');
// console.log('tempData', data);
// let dataLength = data.length;
// data.forEach((row, index) => {
// let tempTh = document.createElement('th');
// tempTh.style.width = row.width + 'px' || '160px';
// // tempTh.style.
// // style="white-space: nowrap"
// tempTh.setAttribute('nowrap', 'nowrap');
// tempTh.innerText = row.label;
// let tempTd = document.createElement('td');
// if (index == dataLength - 1) {
// tempTd.setAttribute('colspan', columns.length);
// }
// tempTd.innerText = row.value;
// tr.appendChild(tempTh);
// tr.appendChild(tempTd);
// });
// thead.appendChild(tr);
// return thead;
// };
//创建基础信息
const createThead = (data, baseInfoDataBox, span) => {
//根据传过来的每行展示多少个动态设置每个元素的宽度
let tempwidth = Math.round((10 / span) * 10);
data.map((row) => {
let tempDom = document.createElement('div');
tempDom.setAttribute('class', 'printBase_box_content');
tempDom.style.width = tempwidth + '%';
let labeldom = document.createElement('div');
labeldom.setAttribute('class', 'printBase_box_title');
labeldom.innerText = row.label + ':';
let textdom = document.createElement('div');
textdom.setAttribute('class', 'printBase_box_text');
textdom.innerText = row.value;
tempDom.appendChild(labeldom);
tempDom.appendChild(textdom);
baseInfoDataBox.appendChild(tempDom);
});
};
//创建表格表头内容
const createTableThead = (coluns) => {
let thead = document.createElement('thead');
let tr = document.createElement('tr');
coluns.map((row) => {
let tempTh = document.createElement('th');
tempTh.style.width = row.width + 'px' || '160px';
tempTh.innerText = row.title;
tr.appendChild(tempTh);
});
thead.appendChild(tr);
return thead;
};
//创建表格里面数据
const createTableData = (columns, tableData) => {
let tbody = document.createElement('tbody');
tableData.map((row, index) => {
let tr = document.createElement('tr');
columns.map((rows) => {
let tempTd = document.createElement('td');
tempTd.innerText = row[rows.dataIndex];
tr.appendChild(tempTd);
});
// tableData[columns[index].dataIndex]
tbody.appendChild(tr);
});
return tbody;
};
//创建底部签名
const createFoot = (footData) => {
let tDom = document.createElement('div');
tDom.setAttribute('class', 'printFoot');
footData.map((row) => {
let tDiv = document.createElement('div');
tDiv.setAttribute('class', 'printFoot-content');
tDiv.style.width = Math.round((10 / footData.length) * 10) + '%';
let tSpanTitle = document.createElement('span');
tSpanTitle.innerText = row.title;
let tSpanValue = document.createElement('span');
tSpanValue.innerText = row.value || '';
tDiv.appendChild(tSpanTitle);
tDiv.appendChild(tSpanValue);
tDom.appendChild(tDiv);
});
return tDom;
};
//创建打印模版
const createPrintTem = () => {
let iframe = createPrintIframe(); // 上边写的框架
document.body.appendChild(iframe);
let style = document.createElement('style');
style.type = 'text/css';
style.innerHTML =
'* {padding:0px;margin:0px}' +
'@page { size: landscape;margin: 0mm; }' +
'table{border-collapse: collapse;font-size:12px}' +
'table tr th { border: 1px solid;padding:8px 8px;}' +
'table tr td { border: 1px solid;padding: 8px 8px;}' +
' .print { width: 1100px;display: flex;flex-direction: column;align-items: center;padding:50px}' +
' .printTitle {align-items: center;width: 100%;margin-bottom: 20px;}' +
' .printBase {display: flex;flex-direction: column;align-items: center;width: 100%}' +
' .printBase_box {display: flex;flex-direction: row;width: 100%; line-height:22px;margin-bottom: 10px}' +
' .printBase_box_content {display: flex;flex-direction: row;}' +
' .printBase_box_text {padding-left:5px}' +
' .printFoot {display:flex;flex-direction:row;width:100%;margin-top: 10px;}' +
' .titleContent {text-align: center;}' +
' .barcodeimg {float:right}';
//创建大盒子
let box = document.createElement('div');
box.setAttribute('class', 'print');
//创建标题盒子
let titlebox = document.createElement('div');
titlebox.setAttribute('class', 'printTitle');
//创建标题盒子内容容器
let titleContent = document.createElement('div');
titleContent.setAttribute('class', 'titleContent');
titlebox.appendChild(titleContent);
// 创建基础信息盒子
let basebox = document.createElement('div');
basebox.setAttribute('class', 'printBase');
box.appendChild(titlebox);
box.appendChild(basebox);
iframe.contentWindow.document.head.appendChild(style);
iframe.contentWindow.document.body.appendChild(box);
return { iframe, box, titlebox, basebox, titleContent };
};
//打印完成后触发
const afterPrint = () => {
console.log('afterPrintafterPrintafterPrintafterPrint');
};
// 打印 重点
const printFn = (config, baseInfo, columns, tableData, footData) => {
let { iframe, box, titlebox, basebox, titleContent } = createPrintTem(); //模板
let footdom = createFoot(footData);
let tempDiv = document.createElement('div');
tempDiv.style.width = '100%';
// tempDiv.style.border = '1px solid';
iframe.contentWindow.document.body.children[0].appendChild(tempDiv); // 增加table
iframe.contentWindow.document.body.children[0].appendChild(footdom); // 增加底部
//给table增加标题
titleContent.appendChild(createCaption(config.proTitle));
titleContent.appendChild(createCaption(config.title));
//如果需要条形码
if (config.barcode) {
let barcodeDiv = document.createElement('div');
barcodeDiv.setAttribute('class', 'barcodeimg');
let barcode = document.createElement('img');
barcode.id = 'barcode';
barcodeDiv.appendChild(barcode);
titlebox.appendChild(barcodeDiv);
console.log('createBarcode', config);
JsBarcode(
iframe.contentWindow.document.getElementById('barcode'),
config.orderNum || '未配置编码',
{
width: 2,
height: 40
});
}
//创建打印table
let table = document.createElement('table');
// 设置属性
table.setAttribute('width', '100%');
table.setAttribute('cellspacing', '0');
table.setAttribute('cellpadding', '0');
//处理有多少个theard,创建table基础信息
let tempData = sliceArry(config.span, baseInfo);
console.log('tempData', tempData);
tempData.map((row, index) => {
let baseInfoDataBox = document.createElement('div');
baseInfoDataBox.setAttribute('class', 'printBase_box');
createThead(row, baseInfoDataBox, config.span);
basebox.appendChild(baseInfoDataBox);
});
//创建table数据
let tableThead = createTableThead(columns);
table.appendChild(tableThead);
let tableTbody = createTableData(columns, tableData);
table.appendChild(tableTbody);
tempDiv.appendChild(table);
iframe.contentWindow.onafterprint = afterPrint;
//延迟打印 todo
setTimeout(() => {
//打印
iframe.contentWindow.print();
}, 1000);
};
export { createPrintIframe, createPrintTem, printFn };
2在要打印的文件里引入封装的打印js文件
如下图
import { printFn } from '@/utils/printUtils';// 引入打印操作
//打印
print = async ({ selectedRows }) => { // 选中的行
console.log('dsadsd', selectedRows);
if (selectedRows[0]?.docType === 'STKO') { // 调整单状态为IA-期初调整 就提示错误
return ElNotification({
type: 'error',
message: '请选择<调整单类型>不为【IA-期初调整】的单据!'
});
}
// 表头
const config = {
proTitle: 'OU_中燃宝电器(深圳)公司',
title: '领料出库单',
span: 3
};
//表格信息
const columns = [
{ title: '行号', dataIndex: 'lineNo' },
{ title: '商品编码', dataIndex: 'itemCode' },
{ title: '商品名称', dataIndex: 'itemName' },
{ title: '申请数量', dataIndex: 'qty' },
{ title: '出库数量', dataIndex: 'qty' },
{ title: '单位', dataIndex: 'uomName' },
{ title: '备注', dataIndex: 'remark' } ];
// 底部信息
let tableData = [];
const footData = [
{ title: '领料人:' },
{ title: '复核人:' },
{ title: '仓管员:' }];
this.setState({
pageLoading: true
});
const res = await service.findOneInvAj(selectedRows[0]?.id); // 请求接口
this.setState({
pageLoading: false
});
if (res.success) {
const baseInfo = [
{ label: '调整单', value: res.data.docNo },
{ label: '申请部门', value: '' },
{
label: '申请日期',
value: asserts.isExist(res.data?.applyDate)
? dayjs(res.data.applyDate).format('YYYY-MM-DD')
: ''
},
{ label: '原因码', value: res.data?.reasonCodeName },
{ label: '仓库', value: res.data?.whName },
{ label: '功能库区', value: res.data?.deter2Name },
{ label: '项目编号', value: '' },
{ label: '项目名称', value: '' },
{ label: '项目类型', value: '' },
{ label: '施工队', value: '' },
{ label: '户外/庭院', value: '' },
{ label: '服务商', value: '' },
{
label: '执行时间(交易时间)',
value: asserts.isExist(res.data?.ioDate)
? dayjs(res.data.ioDate).format('YYYY-MM-DD')
: ''
},
{ label: '执行货位', value: '' },
{ label: '备注', value: res.data?.remark }
];
// 过滤大于等于0的
tableData = res.data.invAjDVOList?.filter((val) => +val.qty < 0);
if (!tableData.length) {
return ElNotification({
type: 'error',
message: '请选择<调整单调整数>【小于0】的单据!'
});
}
tableData.forEach((row) => {
row.qty = Math.abs(row.qty);
});
tableData = res.data.invAjDVOList;
printFn(config, baseInfo, columns, tableData, footData);
} else {
ElNotification({
type: 'error',
message: res.message || res.data || '打印失败'
});
}
};