自定义打印方法
1. 准备HTML结构
首先,构造了一个基本的HTML页面框架,并设置了页面的字符编码为UTF-8,以确保中文和其他特殊字符能正确显示。页面的标题设置为传入的 title
参数值。
let printStr = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'><title>" + title + '</title></head>'
2. 创建DOM元素与表格内容
接下来,创建了两个 <div>
元素,其中一个被赋予了ID table
,用于容纳后续动态生成的表格内容。根据传入的 data
对象,构建了一个复杂的HTML表格字符串,这个表格包含了产品信息、订单详情、生产过程中的各个步骤(如配料、贴片、测试等)以及备注信息。
const div1 = document.createElement('div')
const div = document.createElement('div')
div.id = 'table'
div1.appendChild(div)// ... 构建表格内容 ...div.insertAdjacentHTML('afterbegin', table)
3. 样式应用
为了确保表格的边框能够正常显示,向页面中插入了简单的CSS样式规则,指定每个单元格 (td
) 的边框为1像素实线黑色。
printStr = printStr + content + '</body><style>td{border:1px solid black}</style></html>'
4. 打印操作
通过 window.open('_blank')
方法打开了一个新的浏览器窗口,并将之前构造好的HTML字符串写入新窗口的文档中。然后利用 setTimeout
确保所有DOM元素渲染完成之后再调用新窗口的 print()
方法来触发浏览器的打印对话框。最后,关闭打印窗口,避免留下不必要的空白标签页。
const pWin = window.open('_blank')
pWin.document.write(printStr)setTimeout(() => {pWin.print()pWin.close()
}, 300)
5. 数据映射与格式化
在构建表格时,对某些字段进行了映射转换,比如 moduleTypeMap
和 yesOrNoMap
,以便将数据库中的数值或代码转换成更具可读性的文本描述。此外,对于可能为空的数据项,使用了空值合并运算符 (??
) 来提供默认值,防止出现未定义的情况。
const moduleTypeMap = {1: '小表-计量',2: '小表-MBUS',// ... 其他映射 ...
}const yesOrNoMap = {0: '否',1: '是'
}
6. 延迟执行
在获取数据后,通过 setTimeout
设置了一个短暂的延迟(500毫秒),然后再调用 saleTrackPrint
函数。这可能是为了确保数据完全加载并处理完毕后再进行打印操作,避免因异步操作导致的数据不完整问题。
getTrackPrint(row.id).then(res => {setTimeout(() => {saleTrackPrint({...res.data, track_no: data.track_no_sub, ob_num: data.ob_num,contract_no: row.contract_no}, '生产跟踪单', 0)}, 500)
})
完整代码
import { saleTrackPrint } from '@/utils'getTrackPrint(row.id).then(res => {setTimeout(() => {saleTrackPrint({...res.data, track_no: data.track_no_sub, ob_num: data.ob_num,contract_no: row.contract_no}, '生产跟踪单', 0)}, 500)})
saleTrackPrint
方法是一个用于生成并打印生产跟踪单的JavaScript函数。它接收三个参数:data
(包含需要打印的数据对象)、title
(文档标题)和type
(未在代码中使用)。以下是该方法的工作流程及其实现细节的深入分析:
export function saleTrackPrint(data, title, type) {// 空页面let printStr = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'><title>" + title + '</title></head>'let content = ''const div1 = document.createElement('div')const div = document.createElement('div')div.id = 'table'div1.appendChild(div)const moduleTypeMap = {1: '小表-计量',2: '小表-MBUS',3: '大表-计量',4: '大表-MBUS',5: '小表-485',6: '大表-485'}const yesOrNoMap = {0: '否',1: '是'}const table = `<table border="1" width="1000" height="500" align="left" cellpadding="10" cellspacing="0"><tr>
<th colspan="7" style="font-size: 30px">${title}(${data.track_no})</th></tr><tr><td rowspan="5">产品信息</td></tr>
<tr>
<td width="150">订单数量</td><td width="150">${data.product_num ?? ''}</td>
<td width="150">贴片数量</td><td width="150">${data.ob_num}</td>
<td width="150">预交货日期</td><td width="150">${data.delivery_time ?? ''}</td></tr>
<tr>
<td>产品型号</td><td>${data.product_model ?? ''}</td>
<td>程序版本</td><td>${data.soft_version ?? ''}</td>
<td>排针尺寸</td><td>${data.pin_height ?? ''}</td></tr>
<tr>
<td>硬件版本号</td><td style="font-weight:bold">${data.hard_version ?? ''}</td>
<td>模块类型</td><td>${moduleTypeMap[data.module_type] ?? ''}</td>
<td>产品名称</td><td>${data.product_name}</td></tr>
<tr>
<td>客户/厂家</td><td>${data.product_buyer ?? ''}</td>
<td>程序方案</td><td>${data.program_scheme ?? '' ?? ''}</td>
<td>合同号</td><td>${data.contract_no ?? ''}</td></tr>
<tr>
<td>BOM单名称</td><td colspan="6">${data.bom_name ?? ''}</td></tr>
<tr><td>配料</td><td>配料人员</td><td colspan="2"></td><td>配料时间</td><td colspan="2"></td></tr>
<tr><td rowspan="4">贴片</td></tr>
<tr><td>1、器件检查</td><td></td><td>2、炉温</td><td></td><td>3、锡膏</td><td></td></tr>
<tr><td>4、推力</td><td></td><td>5、首件测试</td><td></td><td colspan="2"></td></tr>
<tr><td>贴片人员</td><td colspan="2"></td><td>贴片时间</td><td colspan="2"></td></tr>
<tr><td rowspan="7">测试</td></tr>
<tr>
<td rowspan="2">数据来源路径</td>
<td colspan="2" align="center">测试数据</td>
<td colspan="3" align="center">平台数据</td></tr>
<tr>
<td align="center">工序1</td>
<td align="center">工序2</td>
<td align="center">工序1</td>
<td colspan="2" align="center">工序2</td></tr>
<tr>
<td>检测总数</td><td></td><td></td><td></td><td colspan="2"></td></tr>
<tr>
<td>检测合格数</td><td></td><td></td><td></td><td colspan="2"></td></tr>
<tr>
<td>检测不良数</td><td></td><td></td><td></td><td colspan="2"></td></tr>
<tr><td>测试人员</td><td colspan="2"></td><td>测试时间</td><td colspan="2"></td></tr>
<tr>
<td rowspan="2">割板</td><td>割板合格数</td><td colspan="2"></td><td>割板不良数</td><td colspan="2"></td></tr>
<tr><td>割板人员</td><td colspan="2"></td><td>割板时间</td><td colspan="2"></td></tr>
<tr>
<td rowspan="2">包装</td><td>包装合格数</td><td colspan="2"></td><td>外观不良数</td><td colspan="2"></td></tr>
<tr><td>包装人员</td><td colspan="2"></td><td>包装时间</td><td colspan="2"></td></tr>
<tr>
<td rowspan="2">入库</td><td>入库合格数</td><td colspan="2"></td><td>订单不良数登记(不入库)</td><td colspan="2"></td></tr>
<tr><td>入库人员</td><td colspan="2"></td><td>入库时间</td><td colspan="2"></td></tr>
<td colspan="1">订单备注</td><td colspan="6">${data.remark ?? ''}</td></tr>
<tr>
<td colspan="1">客户备注</td><td colspan="6">${data.customer_remark ?? ''}</td></tr>
</table>`
div.insertAdjacentHTML('afterbegin', table)// 拼接空页面+style样式+dom内容content = content + div1.innerHTML// printStr = printStr + tabStyle + content + '</body></html>'printStr = printStr + content + '</body><style>td{border:1px solid black}</style></html>'// 打开新页面const pWin = window.open('_blank')// 将内容赋值到新页面pWin.document.write(printStr)// 使用setTimeout,等页面dom元素渲染完成后再打印。setTimeout(() => {pWin.print() // 调用打印功能。pWin.close() // 关闭 打印创建的当前页面document.getElementById(div1.id) // .setAttribute('style', 'display: none')}, 300)
}
效果展示
当用户触发打印功能时,会弹出一个预览窗口,显示带有详细信息的生产跟踪单。用户可以选择直接打印或保存为PDF文件。此方法实现了无需离开当前页面即可快速生成并打印文档的需求,适用于各种内部管理系统的报表输出场景。