Vue2项目中print.js的进阶打印功能实战指南

张开发
2026/4/14 22:15:47 15 分钟阅读

分享文章

Vue2项目中print.js的进阶打印功能实战指南
1. 为什么选择print.js实现Vue2打印功能第一次在Vue2项目里遇到打印需求时我试过好几种方案。原生window.print()功能太简陋直接打印整个页面根本没法用PDF生成又太重需要后端配合。直到发现print.js这个轻量级库实测下来简直不要太香——它完美解决了前端开发中最头疼的局部打印问题。print.js最大的优势是支持多种打印类型。比如上周我做的后台管理系统需要同时实现表格导出、图片打印和HTML内容打印。用这个库只需要几行代码就能搞定而且打印效果跟设计稿完全一致。它的工作原理其实很简单通过JavaScript动态创建一个iframe把要打印的内容放进去然后调用浏览器的打印接口。在Vue2项目中集成特别方便不管是全局引入还是按需加载都很灵活。我比较推荐npm安装方式npm install print-js --save然后在需要的地方引入import printJS from print-js2. 五种常见打印场景实战2.1 图片打印的坑与技巧打印单张图片是最基础的需求但这里有几个容易踩的坑。第一次使用时我直接传了本地图片路径结果打印出来是空白。后来发现print.js处理图片有两种方式使用base64编码的图片数据使用网络可访问的URL推荐的做法是提前把图片转成base64printJS({ type: image, printable: [base64Data], documentTitle: 产品示意图, style: img { max-width: 100%; } // 防止图片溢出 })如果要打印多张图片更聪明的做法是给容器设置IDdiv idgallery img v-forimg in images :srcimg.url /divprintJS({ type: html, printable: gallery, style: page { size: A4 landscape; margin: 0 } })2.2 表格打印的进阶玩法后台系统最常遇到的就是表格打印需求。print.js支持直接打印JSON数据比导出Excel还方便。这是我优化过的配置printJS({ type: json, printable: tableData, properties: [ { field: name, displayName: 姓名 }, { field: age, displayName: 年龄 } ], gridStyle: border: 1px solid #ddd; padding: 8px;, gridHeaderStyle: background-color: #f5f5f5; font-weight: bold;, repeatTableHeader: true // 每页重复表头 })遇到复杂表格时我推荐先用el-table渲染然后打印整个HTMLprintJS({ type: html, printable: tableContainer, style: page { size: A4; margin: 1cm } table { width: 100%; border-collapse: collapse } th { background: #f0f0f0 } })2.3 自定义HTML打印方案有时候需要打印复杂的页面内容比如订单详情页。这时候要注意几个关键点隐藏不需要打印的元素强制分页控制打印专用样式覆盖这是我的标准配置printJS({ type: html, printable: orderDetail, style: page { size: A4; margin: 0 } .no-print { display: none !important } .page-break { page-break-after: always } body { padding: 15px } , scanStyles: false // 禁用原有样式 })2.4 PDF文件的打印技巧虽然print.js主要处理前端打印但也可以配合PDF.js实现文件打印。我常用的模式是printJS({ printable: /files/document.pdf, type: pdf, showModal: true, // 显示打印预览 modalMessage: 正在生成打印预览... })2.5 特殊格式处理方案最近遇到个需求要打印条形码解决方案是// 先使用jsbarcode生成SVG JsBarcode(#barcode, 123456, { format: CODE128 }) // 打印时转换SVG为图片 const svg document.querySelector(#barcode svg) const svgData new XMLSerializer().serializeToString(svg) printJS({ type: image, printable: data:image/svgxml;base64, btoa(svgData) })3. 深度优化与性能调优3.1 样式隔离最佳实践打印样式冲突是最常见的问题。我的解决方案是使用page规则控制页面边距添加print-only样式表媒体查询覆盖/* print.css */ media print { body * { visibility: hidden; } .print-area, .print-area * { visibility: visible; } .print-area { position: absolute; left: 0; top: 0; } }3.2 大表格性能优化打印超长表格时容易卡死我是这样解决的分批次处理数据使用虚拟滚动技术添加加载状态async function printLargeTable(data) { const CHUNK_SIZE 100 for (let i 0; i data.length; i CHUNK_SIZE) { const chunk data.slice(i, i CHUNK_SIZE) printJS({ type: json, printable: chunk, // ...其他配置 }) await new Promise(resolve setTimeout(resolve, 500)) } }3.3 打印配置预设方案项目中经常需要复用打印配置我的做法是封装presetsconst PRESETS { A4_PORTRAIT: { type: html, style: page { size: A4; margin: 1cm } }, A4_LANDSCAPE: { type: html, style: page { size: A4 landscape; margin: 0.5cm } } } function smartPrint(content, preset A4_PORTRAIT) { printJS({ ...PRESETS[preset], printable: content }) }4. 常见问题解决方案4.1 打印内容截断问题这个问题困扰了我很久最终找到的解决方案是检查容器是否有固定高度添加overflow: visible使用CSS打印属性控制分页.print-content { height: auto !important; overflow: visible !important; } media print { .avoid-break { page-break-inside: avoid; } }4.2 图片模糊问题高DPI打印时图片容易模糊需要准备2倍尺寸图片使用矢量图(SVG)设置打印DPIprintJS({ type: image, printable: highResImage, style: img { width: 100%; height: auto; image-rendering: crisp-edges; } })4.3 跨浏览器兼容方案不同浏览器打印表现不一致我的应对策略检测浏览器类型动态调整边距添加浏览器前缀const isFirefox navigator.userAgent.includes(Firefox) const config { style: isFirefox ? -moz-document url-prefix() { page { margin: 0.5cm } } : page { margin: 1cm } }4.4 打印回调与事件处理需要精确控制打印流程时可以使用这些技巧printJS({ // ...配置 onLoadingStart: () console.log(开始加载), onLoadingEnd: () console.log(加载完成), onPrintDialogClose: () console.log(对话框关闭), onError: (err) console.error(打印错误, err) })5. 企业级项目实战经验在最近的后台管理系统项目中我开发了一套完整的打印解决方案打印服务工厂class PrintService { constructor(type) { this.config { type } } setContent(content) { this.printable content return this } setStyle(style) { this.style style return this } print() { printJS(this) } }Vue指令封装Vue.directive(print, { bind(el, binding) { el.addEventListener(click, () { new PrintService(binding.arg) .setContent(binding.value.content) .setStyle(binding.value.style) .print() }) } })打印队列管理系统 对于批量打印任务我实现了优先级队列class PrintQueue { constructor() { this.queue [] this.isPrinting false } add(task) { this.queue.push(task) this.process() } async process() { if (this.isPrinting) return this.isPrinting true while (this.queue.length) { const task this.queue.shift() await new Promise(resolve { printJS({ ...task, onPrintDialogClose: resolve }) }) } this.isPrinting false } }这些方案在我们公司的订单管理系统、报表系统中运行稳定日均处理打印请求超过5000次。特别是在Chrome浏览器环境下打印速度比传统方案快3倍以上。

更多文章