套打总偏两毫米:预印刷单据的校准方法和三个误区

财务室的凭证纸是预印刷的,格子、边框、编号都印好了,打印内容必须精确落在框里。

第一次打,整体右移 3mm;改完 CSS,往下偏 1.5mm;再改,右边对上了但底部又压线。折腾一下午,废了三十多张纸。

套打偏移看着像玄学,其实只有四个源头。把四个都量出来,一次就能调对。

一、偏移的四个来源

1. 走纸误差。 打印机进纸时把纸吸进去,第一张和第十张的位置能差 0.5mm。针式机尤其明显。

2. 缩放。 打印对话框里"适应纸张"没关,内容被缩到 97%,边距全部错位。

3. 坐标原点。 CSS 的 @page margin 是相对纸张可打印区,元素定位是相对内容区,两个原点差了一个边距。

4. 打印机自身偏移。 同一个模板,HP 的机器和兄弟的机器打出来能差 2mm,因为两者的可打印区基准不同。

前三个是代码问题,第四个是硬件问题------第四个才是套打真正难的地方。

配图1:偏移来自四个方向,必须分别量,一起调必然越调越乱

二、校准流程:先打标尺,再调参数

别凭感觉挪,先打一张标尺页:

html 复制代码
<div style="position:absolute;top:0;left:0">
  <div style="position:absolute;left:0;top:0;width:1mm;height:100mm;background:#000"></div>
  <div style="position:absolute;left:0;top:0;height:1mm;width:100mm;background:#000"></div>
  <span style="position:absolute;left:10mm;top:2mm;font-size:8pt">10mm</span>
  <span style="position:absolute;left:50mm;top:2mm;font-size:8pt">50mm</span>
</div>

打出来拿尺子量:标尺的 10mm 刻度如果落在纸上 8mm 处,说明整体左偏 2mm,offsetX = +2。

量三张取平均------单张受走纸误差影响,不可信。

三、偏移量按打印机型号存

这是最关键的一条:偏移不能是一套全局值。

json 复制代码
{
  "printerProfiles": {
    "EPSON-LQ-630K": { "offsetX": 1.8, "offsetY": 2.4, "scale": 0.998 },
    "HP-LaserJet-M405": { "offsetX": -0.6, "offsetY": 0.9, "scale": 1.0 },
    "TSC-TTP-244": { "offsetX": 0, "offsetY": 0, "scale": 1.0 }
  }
}

渲染时按当前打印机取对应偏移:

javascript 复制代码
function applyOffset(root, profile) {
  root.style.transform =
    `translate(${profile.offsetX}mm, ${profile.offsetY}mm) scale(${profile.scale})`
}

scale 这个字段容易被忽略。有些打印机把 100% 渲染成 99.6%,打 A4 竖版时底部会差 1mm 左右,只有加一个细微缩放才能对上。

这套结构在 vue-print-designer 的模板里就是 paper 下的字段:偏移、纸张、边距都跟着模板走,换机器只换 profile。

四、三个最常见的调错方向

误区一:用 padding 调偏移。

css 复制代码
/* 错:padding 会挤压内容区,改了它整版都变 */
.paper { padding-left: 3mm; }

/* 对:用 transform 或外层 margin,不影响内部布局 */
.paper { transform: translateX(3mm); }

padding 改变的是可用宽度,原本刚好放下的表格会因为这 3mm 折行。用 transform 只挪位置,不动布局。

误区二:改 @page margin 想调位置。

@page 的 margin 影响的是内容区大小,改大了内容会重新排版,不是平移。想平移就老老实实用 transform。

误区三:只在一台机器上调。

开发机上调好了,客户现场换台打印机又偏。正确做法是从一开始就把偏移做成配置,每台机器首次使用时跑一次标尺校准,把值存进配置。

配图2:预印刷单据的边距余量通常只有 2-3mm,偏移超过就压线

五、多联针式的校准更麻烦

针式机打多联时,偏移不是一套值。第一联(最上面)和第二联(复写层)的位置能差 0.8mm,因为打印针穿过纸张时有厚度衰减。

实测数据(EPSON LQ-630K,三联单):

层 水平偏差 垂直偏差
第一联 0 0
第二联 +0.4mm +0.6mm
第三联 +0.7mm +1.1mm

如果三联都要进各自的框,只能取中间值折中,或者干脆按最差的一联调。业务上通常只要求第一联对齐(存档联),后两联允许 1mm 误差。

还有一个针式特有的坑:色带磨损会让字迹变淡,但位置不变。所以"看起来偏了"和"字淡了"是两件事,别混着调。

六、校准功能要做进产品

如果每个客户都要你远程调一次偏移,这个产品就没法规模化。校准应该做成界面:

javascript 复制代码
// 打印一张带十字线的测试页,让用户填偏差
function calibrate(printerName) {
  printTestPage()                       // 打测试页
  const dx = Number(prompt('水平偏差(mm),右偏为正'))
  const dy = Number(prompt('垂直偏差(mm),下偏为正'))
  saveProfile(printerName, { offsetX: dx, offsetY: dy })
}

交互糙一点没关系,关键是让客户自己完成,而不是每次都找你。

更友好的做法是给 8 个方向键,用户边打边微调,每次 0.2mm:

javascript 复制代码
let offset = { x: 0, y: 0 }
function nudge(dx, dy) {
  offset.x += dx * 0.2
  offset.y += dy * 0.2
  repaint(offset)      // 只重绘预览,不重打
}

预览对上了再打样张确认,能省一半纸。

六、验收标准

套打验收不能只看"大概齐"。建议按这三条:

  1. 十字线落在框内:内容边界与预印刷框的偏差 ≤ 1mm;
  2. 连打十张稳定:第 1 张和第 10 张的偏差 ≤ 0.5mm;
  3. 换纸不跑偏:同一批纸抽 3 张,位置一致。

第二条最容易挂。针式机连打时走纸会累积误差,解决办法是每张之间留 200ms 间隔,别让队列堆积。

配图3:套打对位要在真机上验证,屏幕上再准也不作数

七、模板化是套打的前提

套打对精度的要求,决定了它不能靠手写 CSS 硬调。坐标必须是数据:

json 复制代码
{
  "paper": { "width": 240, "height": 140, "unit": "mm", "margin": 0 },
  "calibration": { "offsetX": 1.8, "offsetY": 2.4, "profile": "EPSON-LQ-630K" },
  "elements": [
    { "type": "text", "x": 12.5, "y": 8.0, "binding": "invoiceNo" },
    { "type": "text", "x": 12.5, "y": 16.0, "binding": "customerName" }
  ]
}

坐标写死在 CSS 里,换一台机就要改一次代码;写成数据,换机只换 calibration。

这也是 vue-print-designer 把 paper 和元素坐标都放进模板的原因------套打场景下,"版式"和"机器校准"必须分开维护。改版式的人不该关心打印机型号,反之亦然。

一个团队如果在套打上反复返工,八成是因为这两个东西混在一起:模板里既写了业务字段,又写了某台机器的偏移,换机时只能整份复制再改。

八、一句话总结

套打偏了不要急着挪,先量清楚是走纸、缩放、原点、机器里的哪一个。四个来源混在一起调,一定越调越偏。

量准了之后,把偏移存成按机型区分的配置,让客户自己能校准------这是套打能不能规模化的分界线。

相关推荐
徐小夕5 小时前
JitKnow知识库4.8发布:本体+知识图谱检索引擎,让AI回答不再“一本正经地胡说八道”
前端·vue.js·github
tryCbest5 小时前
Vue3——第 11 篇:组合式 API(上)——setup 与响应式 API 深度解析
前端·javascript·vue.js
tryCbest6 小时前
Vue3——第 13 篇:计算属性与侦听器——computed 与 watch 的进化
前端·javascript·vue.js
闲来没事抠鼻屎6 小时前
标签打印 8 个尺寸公式:小票、价签、吊牌、面单通用
vue.js
时间的情敌7 小时前
Vue3 + Cesium 实战:本地上传 GLB 模型、模型上叠加 GLB、点击控制透明度
前端·vue.js·cesium
小蒜学长9 小时前
基于SpringBoot+Vue的云南地区扶贫助农系统的设计与实现(代码+数据库+LW)
java·vue.js·spring boot·后端·乡村振兴
雪芽蓝域zzs10 小时前
WebStorm Uniapp Support + Uniapp Tool + Uniappx Language Service讲解
vue.js·uni-app·webstorm
OpenTiny社区11 小时前
AI 生成的 Vue 代码,终于能直接用了!
前端·vue.js·github
tryCbest11 小时前
Vue3——第 12 篇:组合式 API(下)——Composables 与逻辑3
vue.js