pdfMake向content中push多个表格时出现渲染异常Bug
pdfMake多表格渲染异常问题
问题现象
使用pdfMake生成包含3个表格的PDF文档时出现排版异常:
- 第一个表格(展示排名前三的最优设备数据)可正常渲染
- 第二个表格(展示排名前三的最差设备数据)、第三个表格(展示全量设备数据)无法按预期展示
- 复现规律:注释第一个表格后第二个表格可正常渲染;注释前两个表格后第三个表格可正常渲染
- 异常渲染效果参考:

相关实现代码
const tableHeader = [ setTableHeader("Código"), setTableHeader("OEE"), setTableHeader("Disponibilidade"), setTableHeader("Performance"), setTableHeader("Qualidade"), ] const equipmentsTable = [ tableHeader, ...sortedEquipsInfos.map((equip)=>[ equip.eECode, equip.oee.toLocaleString('pt-BR', {maximumFractionDigits: 2}) + '%', equip.availability.toLocaleString('pt-BR', {maximumFractionDigits: 2}) + '%', equip.performance.toLocaleString('pt-BR', {maximumFractionDigits: 2}) + '%', equip.quality.toLocaleString('pt-BR', {maximumFractionDigits: 2}) + '%', ]) ]; const contentAux = []; contentAux.push({ table: { body: [ equipmentsTable[0], //header equipmentsTable[equipmentsTable.length - 3], equipmentsTable[equipmentsTable.length - 2], equipmentsTable[equipmentsTable.length - 1], ] } }); contentAux.push({ table: { body: [ equipmentsTable[0], equipmentsTable[1], equipmentsTable[2], equipmentsTable[3], ] } }) contentAux.push( { table: { body: equipmentsTable }, } ) var pdfDoc = printer.createPdfKitDocument({ // ...其他配置 content: contentAux })
触发原因
pdfMake渲染表格时,会直接修改传入的行、单元格对象,在上面挂载内部计算用的布局属性、定位标记、宽高缓存等元数据。
代码里三个表格直接复用了equipmentsTable数组里的同一个行引用(尤其是三个表格都用了同一个表头数组引用equipmentsTable[0]),第一个表格渲染完成后,这些共享的数组对象已经被写入了第一个表格的渲染元数据,后续表格读取到这些被修改过的对象时,布局计算逻辑会被干扰,最终出现排版错位、重叠的异常。
解决方法
构造每个表格的body时,不要直接传入原数组的引用,对用到的行数据做拷贝,切断不同表格间的对象引用关联即可。
由于当前代码里单元格都是基础字符串类型,用浅拷贝就可以满足需求,修改示例:
// 单行拷贝工具方法 const copyRow = (row) => [...row]; const contentAux = []; // Top3最优设备表 contentAux.push({ table: { body: [ copyRow(equipmentsTable[0]), copyRow(equipmentsTable[equipmentsTable.length - 3]), copyRow(equipmentsTable[equipmentsTable.length - 2]), copyRow(equipmentsTable[equipmentsTable.length - 1]), ] } }); // Top3最差设备表 contentAux.push({ table: { body: [ copyRow(equipmentsTable[0]), copyRow(equipmentsTable[1]), copyRow(equipmentsTable[2]), copyRow(equipmentsTable[3]), ] } }) // 全量设备表 contentAux.push({ table: { body: equipmentsTable.map(row => copyRow(row)) } })
如果后续单元格包含复杂嵌套的样式对象,可替换为深拷贝实现,注意避开循环引用、函数丢失等深拷贝常见问题即可。
内容的提问来源于stack exchange,提问作者Guilherme Pontarolo
相关产品推荐
相关产品推荐

