一张 80×80mm 标签,为什么会打印出两页?

一个下载按钮牵出了业务标识、文件命名、浏览器分页与物理尺寸的同一性问题;真正的修复不是缩小标签,而是让打印文档只剩下那一张标签。

最初的需求很小:把标签编辑器里的“下载 PNG”,改成一次真正的 Save As。用户点击之后,应该能看到有意义的建议文件名,选择保存位置,然后得到可以直接识别的文件。

可是第一个文件名实现就暴露了问题。它用了 SKU-001 这类内部 SKU,而标签上真正让用户识别这批货的,是可见的 Batch No: 30267-0914。下载动作本身没有失败,但数据语义失败了:系统选了一个技术上存在、业务上却不对的标识。

生产路由
/tools/label/
文件名业务标识
可见 Batch No(存在时)
示例
30267-0914-BQ.png · 30267-0914-BQ.pdf
物理尺寸
不缩放,80×80mm 仍是 80×80mm
分页验证
6 种尺寸在 Chromium 中均为 1 页

文件名是数据模型的一部分

正确做法不是为下载再造一套“看起来对”的命名逻辑,而是让文件名和画面上的 Batch No 使用同一个 canonical 数据源。屏幕上显示 30267-0914,PNG 就建议保存为 30267-0914-BQ.png,PDF 就是 30267-0914-BQ.pdf。如果两者不同,那么至少有一处并没有在表达用户眼前的那批货。

这个原则也适用于 PDF,只是浏览器的接口不一样。macOS 上从浏览器进入 Print → Save as PDF 时,建议的 PDF 名称来自打印文档的标题。所以打印路径会在发起打印前,短暂把 document.title 替换成 Batch No 派生的名称;打印结束、取消或窗口恢复后,再可靠地还原正常页面标题。这不是 SEO 标题的修改,而是一个有明确进入和退出边界的打印会话状态。

刚好一页,反而多了一页

文件名闭环之后,更有意思的故障出现了:一张 80×80mm 的标签,打印预览显示两页,第二页是空白的。

直觉上,如果纸张和标签都是 80×80mm,它就应该刚好放下。但浏览器排版并不是把两个整数毫米直接比较。CSS 中的毫米会转换成 CSS 像素,打印管线又会把它映射到设备和分页单位。在页面边界上,子像素舍入、默认行盒或 body 的微小参与,都可能让一个“数值上刚好”的底边落入下一个 pagination fragment。

原实现里,打印 sheet 虽然设为与页面完全同尺寸,但它仍留在普通文档流的分页计算中。只隐藏 #root 也不够严格:它假设除了这个节点之外,body 里没有任何会占据打印布局的元素。这个假设在精确尺寸分页中太宽松了。

修复分页,不是修改标签尺寸

真正的修复是把那张 print sheet 从普通分页流里隔离出来。打印样式严格移除所有非打印的 body 子元素,清零 html 和 body 的 margin、padding 以及可能参与高度计算的行盒,再把唯一的 sheet 绝对定位到页面原点。同时保留根据当前标签动态生成的精确规则:

@page { size: <width-mm> <height-mm>; margin: 0; }

这里刻意没有用 99% 缩放,没有从宽高里各减 1mm,也没有把它塞进 A4 再选“适应页面”。这些做法可能让空白页消失,但也会改变最重要的输出合同。80×80mm 必须保持物理上的 80×80mm。

编辑器和导出预览可以放大到 150% 以方便操作,但那只是展示层。canonical geometry 和输出像素没有变:100×100mm 仍导出 1000×1000px,70×20mm 仍是 700×200px。屏幕上看得更大,不等于打印物理尺寸变大。

怎样证明是分页修复,而不是一次巧合

验证不能只回看 80×80mm,因为只对一个尺寸特殊处理,也能制造出“已修复”的假象。Chromium 分页验证覆盖了 70×20、70×40、80×60、80×80、100×100mm,以及自定义 93×57mm;六种情况都只生成 1 页。这个自动化环境无法直接读取 macOS 原生打印预览里的页数计数器,所以证据边界也应该说清楚:证明的是 Chromium 打印文档在这个尺寸矩阵中的单页结果,不是自动读取了 macOS 原生 UI。

最后一步不在浏览器里。打印 hotfix 在 Production 验证后,那个已验证的分支内容被对账回 GitHub main,最终 source 和 Production 的 tree 一致。这个结尾很重要:否则线上已经解决的问题,下一次从不完整源码发布时还会回来。

“能下载”不是完成,“能打印”也不是完成。数据来源、文件命名、物理尺寸、分页行为和生产源码都一致,才算完成。

WEOUR / BUILD

参与构建

如果你正在处理真实的跨境贸易、库存、仓储、履约或自动化问题,可以把需求告诉我们。

提交需求 关注 WEOUR / 交流入口 —— 即将开放