hiprint实现承前过次(跨页累计)核心思想

承前过次(跨页累计)


一句话总览

读懂模板开关 → 复印模板并关掉原生合计、定下"每页 N 行" → 把数据按 N 行切页、头尾插承前行、跨页把金额累加好 → 拿复印模板 + 处理好的数据交给 hiprint,它老老实实每 N 行翻一页,合计/承前行自然落在页尾/页首。


一、行数断页(核心思想)

问题:会计账本跨好几页打印,每页末尾要写"本页合计/过次页",下一页开头写"承前页"。hiprint 本身是"按纸张高度自动分页"的——哪行排到纸底了就换页。这种方式你控制不了,而且因为字号、显示器分辨率的影响,差个一两行就会抖,合计行可能就被挤到页中间去了。

思路:我们不让 hiprint 自己决定在哪断页,而是替它规定"每页必须正好 N 行"。hiprint 有个现成功能叫 maxRows——排满 N 行就强制翻页。我们算出 N,告诉 hiprint "满 N 行你给我换页",它就听话了。

关键点:我们在数据里提前把每一页结构上排好(数据行 + 插入的承前/合计/过次行加起来正好 N 行),然后让 hiprint 按 N 行断页。两边对上了,合计行必然在页尾,承前行必然在页首。

一句话总结:与其求着 hiprint 把合计行排到页尾,不如直接命令它"每页 N 行,排满就翻页",我们自己把 N 行的内容拼好。


二、配置解析

问题:代码怎么知道"这个模板要不要承前过次?累计哪些金额?余额算不算?"

思路:模板的表格上有几个开关字段(写在 options 里),代码像读说明书一样解析它们:

  • carryForward: true → 这个表要承前过次
  • carryForwardFields: "借方金额,贷方金额" → 这两个字段要逐页累加
  • carryForwardBalanceFields: "余额" → 余额只"照搬上一页末行的数",不累加(余额是滚存,加总会变成天文数字)
  • carryForwardTotals: all/carryOnly/none → 决定插哪些行(全插 / 只插承前+过次 / 都不插只分页)

几个坑点

  • 如果没显式写字段,代码会"猜":先看列上有没有设过合计,再看列名/标题里有没有"金额、借方、余额"这类字眼,自动识别。
  • hiprint 存模板时,列可能是"套了娃的二维数组",代码会先把它拍平,不然认不出字段。
  • 代码会记住"这个表在第几个面板、第几个元素",后面只改这一个表,不误伤同模板里的其他表。

一句话总结:代码当翻译,把模板上的人话开关读成自己能用的配置(累计啥、余额咋算、每页几行)。


三、模板副本处理(给 hiprint 定规矩,但不动原稿)

问题:原模板上 hiprint 自带的"每页合计"功能要关掉(不然会和我们的"本页合计"重复算),还要注入"每页 N 行"的规矩。但设计器里正在画的那个模板不能动。

思路:先复印一份模板(深拷贝),只在复印件上动手术:

  1. 删掉原生的 tableSummary 合计设置(避免重复累加);
  2. 写上 maxRows = N(就是上面说的"每页 N 行翻页")。

原件(设计器画布)纹丝不动。我们拿复印件去建打印实例。

为什么必须复印而不是改原件:模板是层层嵌套的结构,普通复制只复制第一层,里面的内容还是和原件共享的,改复印件会连原件一起改坏。所以用了 JSON.parse(JSON.stringify()) 这种"序列化再反序列化"的办法,彻底断开引用,得到一份全新独立的副本。

一句话总结:复印模板 → 只在复印件上关掉原生合计、写上"每页 N 行" → 拿复印件打印,原件不动。


四、数据切分 + 跨页累计(往数据里"插行 + 算账")

问题:原始数据是平平的一长串明细(比如 50 行),我们要把它切成"一页一页"的结构,在每页头尾插入承前/合计/过次行,还要把金额跨页连续算对。

思路

① 算每页放几行数据

设每页总共 N 行(和上面的 maxRows 同一个数)。每页除了数据,还要占几行给"承前/合计/过次"这些特殊行,所以:

  • 首页:数据 (N-2) 行 + 本页合计 + 过次页
  • 中间页:承前页 + 数据 (N-3) 行 + 本页合计 + 过次页
  • 末页:承前页 + 剩下的数据 + 本页合计

代码用一个 pieces 数组记录"每一页放几行数据",保证每页总数恰好 N 行。

② 逐页遍历,边插行边算账

准备两个账本:

  • 总账 total:从第一页一直加到当前页(比如借方累计到 80 万),写进"过次页",下一页的"承前页"就接着这个数往下算 → 这就是"跨页连续"。
  • 本页账 pageTotal:只算当前这一页的小计,写进"本页合计"。

③ 余额的特殊处理(重点)

余额不是加总,而是"照搬这一页最后一行的余额数"。所以另外用一个 carriedBalance,只记录末值,绝不累加

④ 精度收尾

金额带小数,电脑算加法会有 20999.300000000003 这种误差,会计受不了。所以每加一笔都用 round2 收回到分位(加个极小值抵消浮点误差)。另外,数据里金额常以 "2,944.26" 这种带逗号的字符串进来,hiprint 会误判成数字算成 NaN,所以进来的第一步先把这些字符串洗成真正的数字。

一句话总结:把一长串明细按 N 行一页切开,每页头尾插好承前/合计/过次行,同时维护"总账(跨页累)"和"本页账(本页小计)",余额只搬末值不累加,金额每步收精度、先洗成数字防 NaN。


五、两个小提醒

  • 换行内容不一定错位:承前过次是"按行数 N 分页",只要某页没被撑爆到触发 hiprint 的高度自然断页,行数分页就和高度分页重合,换行内容也能正常显示。"固定行高不折行"是保守前提,不是换行一定错。
  • 两个函数必须成对用prepareTemplateForCarryForward(出模板复印件)必须先于 applyCarryForward(出处理好的数据),且打印实例必须建在复印件上。漏掉任一步,原生合计会重复、断页会错位。

相关文档

  • 实现规范(接入契约):承前过次实现说明.md
  • 深度解析:承前过次深度解析.md
  • 源码:src/utils/print/carryForward.tssrc/utils/print/normalizeAmount.ts
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容