首页/新闻资讯/正文详情

web打印插件四选一:从浏览器打印到可视化模板设计器

发布时间:2026/11/3 19:32:24 来源:云帆数科 栏目:资讯中心
web打印插件四选一:从浏览器打印到可视化模板设计器
后台系统做到一定阶段打印一定会变成最脏的活。业务最初说能打印就行上线三个月后需求变成表头要在每页重复、这张单要套打、批量打 200 张、不要弹框、能不能让业务自己改模板。等你把这些都补上代码里已经堆了三千行排版逻辑还没人敢动。问题往往不在实现而在第一步方案选错了。项目地址https://gitee.com/theGreatOldFive/vue-print-designer一、四条路线的本质区别先说结论这四条路线的差异不在能不能打出纸而在排版逻辑放在哪、模板归谁维护。配图1四条打印路线的取舍路线排版在哪分页谁控制模板谁维护典型接入成本window.print浏览器排版引擎CSS前端0.5-2 人天html2canvas jsPDF前端 canvas手动切片前端2-5 人天Puppeteer服务端 Chromium引擎控制前端 后端5-10 人天模板设计器渲染引擎模板内置业务自己3-8 人天成本不在开发在变更。前三条路线业务每改一次版式都要走一遍需求 → 开发 → 测试 → 发版第四条只改配置。一年改 10 次模板前三条累计要吃掉 20-40 人天。二、window.print能走多远最短路径也是最适合内部单据的一条。media print { page { size: A4; margin: 12mm 10mm; } /* 表头每页重复 */ thead { display: table-header-group; } /* 行不要被劈开 */ tr { break-inside: avoid; page-break-inside: avoid; } /* 交互元素不打印 */ .no-print, .toolbar, .pagination { display: none !important; } }它的边界很清楚必须弹打印对话框用户要自己选打印机、点确认边距受浏览器影响不同浏览器默认页边距不一致套打基本不可行毫米级定位会被浏览器默认边距吃掉静默打印做不到这是浏览器安全模型决定的。所以它适合内部审批单、对账单、报表——用户点一下、选打印机、确认这个流程可以接受。如果业务只是把页面打出来这条路能覆盖 60% 的需求别过度设计。三、截图方案一页以内才划算用户要的不是打印而是下载一个 PDF 文件时html2canvas jsPDF 最快。import html2canvas from html2canvas import { jsPDF } from jspdf async function exportPdf(el, filename) { const canvas await html2canvas(el, { scale: 2, // 关键至少 2 倍否则模糊 useCORS: true, // 跨域图片 backgroundColor: #ffffff, logging: false, }) const pdf new jsPDF(p, mm, a4) const pageW 210 const imgH (canvas.height * pageW) / canvas.width pdf.addImage(canvas.toDataURL(image/jpeg, 0.95), JPEG, 0, 0, pageW, imgH) pdf.save(filename) }三个硬伤必须提前知道文字变成图片不可搜索、不可复制、放大就糊长内容撞 canvas 上限Chrome 单边最大 32767px几十页的报告直接崩切页会把字劈成两半因为它是按图片高度硬切不认行边界。结论一页以内能用超过两页就该换路。它最适合电子回单、短凭证这类打完就存档、不会二次编辑的场景。四、服务端渲染最准也最重Puppeteer 出 PDF 的好处是分页、页码、页眉页脚全部交给 Chromium 的排版引擎const browser await puppeteer.launch({ args: [--no-sandbox] }) const page await browser.newPage() await page.setContent(html, { waitUntil: networkidle0 }) await page.evaluate(() document.fonts.ready) await page.pdf({ path: out.pdf, format: A4, printBackground: true, displayHeaderFooter: true, headerTemplate: div stylefont-size:9px;width:100%;text-align:center合同编号 {{no}}/div, footerTemplate: div stylefont-size:9px;width:100%;text-align:center 第 span classpageNumber/span / span classtotalPages/span 页/div, }) await browser.close()代价也很实在服务器要装 Chromium镜像 400MB 起步并发高时内存吃紧一台 2C4G 的机器同时跑 5 个渲染任务就开始排队前端还要额外维护一套给后端用的 HTML和页面样式容易漂移调试链路长改一个像素要重新部署才能看到。适合医院报告、检验单、对账单这类必须归档、分页严格的场景。五、模板设计器把排版从代码里拿出来前三条路线的共同点是模板写死在代码里。业务想加一列规格、换一下公司抬头、把表头字体改大都要提需求、排期、发版、回归测试。一个中型 ERP这类需求一年能有几十条。模板设计器的思路是把排版抽出来业务在页面上拖字段、设字号、画表格线导出 JSON渲染时用同一套引擎填数据、算分页、出纸。{ schemaVersion: 3, paper: { width: 210, height: 297, unit: mm }, bands: [ { type: pageHeader, height: 25, repeat: true }, { type: detail, height: 8, repeat: true, source: items }, { type: summary, height: 40, repeat: false } ], elements: [ { type: text, x: 10, y: 8, w: 80, h: 8, binding: title }, { type: barcode, x: 8, y: 220, w: 84, h: 20, binding: orderNo } ] }关键要求只有一条设计态和打印态共用一套渲染。如果设计器用一套 DOM、打印用另一套设计稿和成品永远差两毫米用户会觉得这工具不靠谱。配图2模板市场里现成的单据模板这套结构我参考的是 vue-print-designer 的实现模板 JSON 统一渲染器 带band分页三块都开源优点是可以照着它的字段设计自己复刻一个渲染器不用担心被锁死。六、六个维度横向对比维度window.print截图方案Puppeteer模板设计器输出质量矢量位图矢量矢量分页可控性中靠 CSS差高高静默打印不支持不支持需配合客户端需配合客户端套打精度低低中高mm 定位模板维护前端前端前端后端业务自助运维成本无低高Chromium低七、选型决策流程按顺序问四个问题问完基本就定了模板一年改几次0-2 次 → 走前三条5 次以上 → 直接看设计器。内容会不会超过一页会 → 排除截图方案。要不要归档 PDF要 → 服务端渲染或设计器渲染。有没有套打/标签有 → 必须能控制毫米级坐标前两条直接排除。四个问题里只要有一个落在设计器那侧就说明你的系统已经进入打印是长期成本的阶段了。八、从 window.print 迁移到设计器的路径很多团队不是从零开始而是已经有一堆media print的样式。迁移可以分三步不用推倒重来第一步把版式数据化。把现在写死的表格列、字段抽成一份配置先不用做成可视化设计器。第二步统一渲染入口。所有打印走同一个PrintRenderer :template :data先只支持配置渲染不支持拖拽编辑。第三步接设计器。业务方开始自己改模板前端只维护渲染器。这三步每步都能独立上线风险可控。跳过前两步直接上设计器通常会在老模板怎么兼容上卡住。九、几个容易忽略的细节纸张尺寸必须在打印机驱动里建好否则会回退到 A4 并缩放套打全废打印缩放必须 100%浏览器适应纸张会破坏毫米级布局字体要随应用分发别赌用户机器装了什么page { margin: 0 }之后要自己用 padding 撑内容区否则内容贴着纸边条码一律 SVG位图在 203dpi 下会糊。配图3热敏小票——最常见的打印形态之一十、一张决策表收尾你的处境选它理由内部审批单模板不改window.print半天干完别过度设计要下载 PDF一页内html2canvas jsPDF前端自足不用服务端必须归档分页严格Puppeteer分页页码最稳模板由业务维护模板设计器改版式不发版既要套打又要多联设计器 mm 定位手写坐标维护不动选型的关键不是技术先进而是你愿意为模板变更付多少成本。前期省下的接入时间后期会以排期的形式还回去。

相关推荐

数仓方法论(二):指标设计与规范化——让经营目标成为共同的衡量规则
数仓方法论(二):指标设计与规范化——让经营目标成为共同的衡量规则

一、指标设计与规范化方法论 指标设计与规范化的作用,是把经营目标转化成相互关联、能够指导行动,而且业务定义与实际计算一致的衡量规则。 例如,经营者想提高销售额,需要知道增长来自订单数量还是平均金额;而多个部门… · 2026/11/3 19:32:24

个人知识库建设 - 路线
个人知识库建设 - 路线

文章目录写在前面一、先回答三个问题,路线基本就定了问题一:你主要问什么类型的问题问题二:语料有多大、有多脏问题三:结果能不能错,资料能不能出网二、六条路线2.1 云端托管:把资料交出去,换一… · 2026/11/3 19:32:24

stm32寄存器编程--AFIO、EXTI、NVIC
stm32寄存器编程--AFIO、EXTI、NVIC

先讲讲AFIO,其实这个不难,主要功能就是复用重映射引脚和链接外部中断引脚。1、先讲讲复用引脚重映射,我们的板子上有许多引脚,也有许多外设,也有对应的外设引脚,未免会有一些引脚拥有多种功能,比如说定时器… · 2026/11/3 19:31:24

基于遗传算法的自适应PID控制在二阶系统中的应用
基于遗传算法的自适应PID控制在二阶系统中的应用

1. 二阶系统与PID控制的基础原理在工业控制领域,二阶系统是最常见的被控对象模型之一。这类系统的动态特性可以用二阶微分方程来描述,其传递函数通常表现为:G(s) K / (s 2ζωₙs ωₙ)其中,K为系统增益,ζ为阻尼比… · 2026/11/3 20:11:45

Python标识符命名规范与工程实践指南
Python标识符命名规范与工程实践指南

1. 从一道期末真题看标识符命名的陷阱去年期末考场上的一道Python基础题让不少同学栽了跟头。题目要求判断以下哪个是合法的Python标识符:2nd_place_internal_dataclassprice$正确答案是2,但考场上有近40%的同学选择了包含1或3的选项。这个结果让我意识到… · 2026/11/3 20:11:45

云端部署Qwen-Image-2.1:20分钟搞定,成本不到5毛
云端部署Qwen-Image-2.1:20分钟搞定,成本不到5毛

云端部署Qwen-Image-2.1,20分钟搞定,花费不到5毛 前阵子有个做独立开发的朋友找我吐槽,说他接了个小活,客户要批量生成一批电商主图,量不大,几百张,但要求风格统一、出图质量得过关。他第一反应… · 2026/11/3 20:11:45

联合概率分布在贝叶斯统计推断中的应用与实践
联合概率分布在贝叶斯统计推断中的应用与实践

1. 联合概率分布在统计推断中的核心地位统计推断的本质是从观测数据中反推生成这些数据的概率模型参数。当我们面对多个未知参数时,联合概率分布就成为了连接先验知识与观测数据的桥梁。这种多参数场景在实际问题中极为常见:从医学诊断中的多项生理指标关… · 2026/11/3 20:11:45

AI提示系统架构演进:从单体到分布式实践
AI提示系统架构演进:从单体到分布式实践

1. 项目概述:AI提示系统的架构演进需求最近在重构公司核心的AI提示系统时,我深刻体会到架构演进的重要性。这个系统最初只是一个简单的单体应用,但随着业务量激增和功能复杂度提升,原有的架构已经难以支撑。每天处理上百万次的AI提… · 2026/11/3 20:11:45

AUC、ROC、ACC区别:分类模型评估指标与阈值选择指南
AUC、ROC、ACC区别:分类模型评估指标与阈值选择指南

前阵子帮一个做信贷评分的朋友复盘模型,他发过来的评估报告上写着 ACC 0.97,语气相当轻松,觉得这版可以直接上线了。我让他把混淆矩阵和标签分布一起贴出来,结果正样本占比不到 2%,也就是说一个把所有样本都判成“负”… · 2026/11/3 20:10:44

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46

STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码