使用Freemarker制作报表模板如何将多页打印内容合并为单页并排展示
Freemarker 报表单页打印多列合并实现方案
核心思路是先在模板层将超长列表按单页单列最大容纳行数拆分为多组,再通过打印专用CSS将多组列表并排排列,强制所有内容输出到同一页。
1. 先确定单页单列最大行数
先实际测试你的打印场景(比如A4纸、固定字号边距)下,单列最多能放多少行不会超出单页高度,假设测试得到的数值为maxRowsPerCol = 30,可根据实际场景调整。
2. Freemarker 列表分块改造
把原有的一维列表拆分为二维分组列表,每一组的行数不超过最大行数:
<#assign maxRowsPerCol = 30> <#assign colCount = Math.ceil(recordList?size / maxRowsPerCol)?int> <#assign recordGroups = []> <#list 0..colCount-1 as colIndex> <#assign start = colIndex * maxRowsPerCol> <#assign end = Math.min((colIndex+1)*maxRowsPerCol, recordList?size)?int> <#assign recordGroups = recordGroups + [recordList[start..end-1]]> </#list>
3. 多列布局 + 打印样式控制
用CSS的Grid布局实现多列表格并排,同时添加打印专用样式强制内容缩到单页:
<style> @media print { @page { size: A4 portrait; /* 按需调整纸张尺寸和方向 */ margin: 1cm; } body { width: 100%; height: 100%; print-color-adjust: exact; -webkit-print-color-adjust: exact; } /* 强制禁止分页 */ * { page-break-after: avoid !important; page-break-before: avoid !important; page-break-inside: avoid !important; } } /* 多列表格容器 */ .table-container { display: grid; grid-template-columns: repeat(${colCount}, 1fr); gap: 10px; width: 100%; } .record-table { border:1px white; width:100%; border-collapse:collapse; } .record-table td { width:5%; } </style>
4. 渲染多列表格
遍历拆分后的分组,逐列渲染表格:
<div class="table-container"> <#list recordGroups as group> <table class="record-table"> <#list group as item> <tr> <td class="always">${(item.record)!}</td> </tr> </#list> <!-- 不足最大行数的列补空行,保证所有列高度对齐 --> <#if group?size < maxRowsPerCol> <#list 1..(maxRowsPerCol - group?size) as empty> <tr><td> </td></tr> </#list> </#if> </table> </#list> </div>
注意事项
- 最大行数
maxRowsPerCol需要根据你的实际字体大小、单元格边距、页面边距实测调整,避免内容溢出 - 如果需要适配不同纸张尺寸,可将
maxRowsPerCol作为动态参数传入Freemarker模板 - 打印时浏览器可能默认开启「缩放以适应宽度」,建议在打印预览中确认该选项开启,保证多列内容不会超出页面宽度
内容的提问来源于stack exchange,提问作者Berk Çavuş
相关产品推荐
相关产品推荐

