
本文介绍通过自定义 pdf 导出样式与结构,在 datatables 中实现“第6列后换行”的视觉效果,解决宽表导出 pdf 时内容横向溢出的问题,核心方案是结合 `pdfmake` 的 `customize` 钩子动态拆分行数据并插入空白行。
DataTable 默认的 pdfHtml5 导出(基于 pdfMake)会将整行作为单个表格行渲染,当列数过多(如12列)且未做响应式适配时,极易超出 PDF 页面宽度(尤其是 LEGAL 纸型仍可能不足)。仅靠 CSS @media print .d-none 并不能实现“第6列后换行”——因为该方式只能隐藏元素,无法改变表格物理结构。
✅ 正确解法:利用 pdfHtml5 的 customize 回调函数,手动重构 content.table.body,将每行原始数据拆分为两行(前6列 + 后6列),并在二者之间插入一个空行(含空单元格)以实现视觉分隔:
{
extend: 'pdfHtml5',
orientation: 'landscape',
pageSize: 'LEGAL',
text: 'PDF',
customize: function (doc) {
// 确保 doc.content.table 存在且有 body
if (doc.content && doc.content.table && doc.content.table.body) {
const originalBody = doc.content.table.body;
const newBody = [];
originalBody.forEach((row, rowIndex) => {
// 跳过表头(通常第一行是 header)
if (rowIndex === 0) {
newBody.push(row);
return;
}
// 拆分普通数据行:前6列 + 后6列
const cols = row.length;
if (cols > 6) {
const firstHalf = row.slice(0, 6);
const secondHalf = row.slice(6);
// 补齐长度,确保每行单元格数一致(pdfMake 要求每行列数相同)
const padCell = { text: '', style: 'tableBody', border: [false, false, false, false] };
const paddedFirst = [...firstHalf, ...Array(cols - 6).fill(padCell)];
const paddedSecond = [...Array(6).fill(padCell), ...secondHalf];
newBody.push(paddedFirst);
// 插入空行(可选:添加细微分隔效果)
newBody.push([
{ text: '', colSpan: cols, style: 'tableBody', border: [false, false, false, false], margin: [0, 4, 0, 4] }
]);
newBody.push(paddedSecond);
} else {
newBody.push(row);
}
});
doc.content.table.body = newBody;
}
}
}⚠️ 注意事项:
- customize 函数在 pdfMake 文档对象生成后、渲染前执行,是修改 PDF 结构最可靠的入口;
- 拆分后务必对齐列数(用空单元格 padCell 填充),否则 pdfMake 会报错 Row must have same number of cells as header;
- 若表头也需适配(如前6列标题+后6列标题),可在 customize 中单独处理 originalBody[0];
- 如需更精细控制(如合并单元格、自定义字体/间距),可进一步扩展 style 属性或使用 layout 选项;
- 测试时建议先启用 debug: true 查看原始 doc 结构:pdfHtml5: { debug: true, ... }。
此方案不依赖 CSS 打印媒体查询,而是从数据层重构 PDF 表格结构,真正实现“逻辑换行”,兼顾可读性与专业排版需求。










