如何让DataTables的pdfHtml5导出解析Ajax数据中的HTML与CSS样式
DataTables pdfHtml5导出无法解析HTML标签与CSS样式的解决办法
问题场景
通过Ajax加载到DataTable的数据包含HTML标签(如带font-weight-bold、text-success类的<span>),但使用pdfHtml5导出PDF时,无法解析这些内容,仅显示原始HTML代码。已配置exportOptions实现选择行导出,DataTable从后端Ajax获取数据。
相关代码示例
JS导出配置(exportOptions)
var thisExportOptions = { exportOptions: { rows: function(idx, data, node) { var checkedB = sontCoches(".dt-class-checkbox", "entireRow"); var dt = new $.fn.dataTable.Api('#datatable-configuration'); $(checkedB).each(function(i, v) { dt.row(this).select(); }); var selected = dt.rows({ selected: true }).indexes().toArray(); if (selected.length === 0 || $.inArray(idx, selected) !== -1) return true; return false; }, columns: ':visible' } };
JS DataTable初始化配置
var table = $('#datatable-configuration').DataTable({ "ajax": { "url": "/backend/index.php", "dataType": "json", "type": "GET", "data": { "app": get["app"], "module": get["module"], "element": cElement, "action": "serverside", "actionParent": get["action"], //"get": get, } }, "buttons": [ $.extend(true, {}, thisExportOptions, { text: '打印', extend: 'print' }), $.extend(true, {}, thisExportOptions, { text: 'PDF', extend: 'pdfHtml5' }), { extend: 'colvis', text: '导出列', className: 'btn-primary', columns: ":not(.notConcernedByColvis)" } ], "fnStateLoad": function(oSettings) { return JSON.parse(localStorage.getItem('dataTableStore')); }, "stateSaveParams": function(settings, data) { data.columns.forEach(function(column) { delete column.visible; }); } });
PHP后端生成带HTML的数据
$datas[$key]['nom'] = "<span class='font-weight-bold text-success'>" . $brute->raison_sociale . "</span>"; $datas[$key]['nom'] .= (!empty($brute->rcs_siret)) ? "<br /><small><span class='font-weight-bold'>RCS : </span><span class='right'>" . $brute->rcs_siret . "</span></small>" : ""; $datas[$key]['autres'] = '';
解决方法
方法1:通过导出回调解析HTML并转换为pdfMake支持格式
pdfHtml5依赖pdfMake生成PDF,需将HTML标签转换为pdfMake可识别的结构。修改thisExportOptions配置,添加格式处理和自定义样式:
var thisExportOptions = { exportOptions: { rows: function(idx, data, node) { var checkedB = sontCoches(".dt-class-checkbox", "entireRow"); var dt = new $.fn.dataTable.Api('#datatable-configuration'); $(checkedB).each(function(i, v) { dt.row(this).select(); }); var selected = dt.rows({ selected: true }).indexes().toArray(); if (selected.length === 0 || $.inArray(idx, selected) !== -1) return true; return false; }, columns: ':visible', // 处理HTML内容的回调 format: { body: function(data, column, row) { let tempDiv = document.createElement('div'); tempDiv.innerHTML = data; // 将font-weight-bold转换为pdfMake的粗体标记 tempDiv.querySelectorAll('.font-weight-bold').forEach(el => { el.innerHTML = `<b>${el.textContent}</b>`; }); // 替换<br>为换行符 let processedContent = tempDiv.innerHTML.replace(/<br\s*\/?>/gi, '\n'); // 移除无用标签,保留文本和粗体标记 processedContent = processedContent.replace(/<span[^>]*>(.*?)<\/span>/gi, '$1'); return processedContent; } } }, // 自定义pdfMake样式,匹配text-success的绿色 customize: function(doc) { doc.styles = Object.assign(doc.styles, { success: { color: '#28a745' }, small: { fontSize: 10 } }); // 对带text-success的内容单独处理(需在format.body中标记) doc.content.forEach(item => { if (item.table) { item.table.body.forEach(row => { row.forEach(cell => { if (typeof cell === 'string' && cell.includes('text-success')) { cell = { text: cell.replace('text-success', ''), style: 'success' }; } }); }); } }); } };
方法2:后端提供双份数据,前端按需切换
在PHP后端同时返回页面显示用的HTML和导出用的结构化数据:
// 页面显示用HTML $datas[$key]['nom_display'] = "<span class='font-weight-bold text-success'>" . $brute->raison_sociale . "</span>"; $datas[$key]['nom_display'] .= (!empty($brute->rcs_siret)) ? "<br /><small><span class='font-weight-bold'>RCS : </span><span class='right'>" . $brute->rcs_siret . "</span></small>" : ""; // 导出用结构化数据(适配pdfMake格式) $exportNom = [ ['text' => $brute->raison_sociale, 'style' => ['bold', 'success']] ]; if (!empty($brute->rcs_siret)) { $exportNom[] = '\n'; $exportNom[] = ['text' => 'RCS : ', 'style' => 'bold']; $exportNom[] = $brute->rcs_siret; } $datas[$key]['nom_export'] = $exportNom; $datas[$key]['autres'] = '';
然后在DataTable中配置列的渲染规则,导出时使用结构化数据:
var table = $('#datatable-configuration').DataTable({ "ajax": "/backend/index.php", "columns": [ // 其他列配置... { data: 'nom_display', name: 'nom' } ], "columnDefs": [ { targets: 'nom-column', // 给nom列添加对应class render: function(data, type, row) { // 导出时切换为结构化数据 if (type === 'export') { return row.nom_export; } return data; } } ], "buttons": [ $.extend(true, {}, thisExportOptions, { text: '打印', extend: 'print', exportOptions: { orthogonal: 'export' } }), $.extend(true, {}, thisExportOptions, { text: 'PDF', extend: 'pdfHtml5', exportOptions: { orthogonal: 'export' }, customize: function(doc) { doc.styles.success = { color: '#28a745' }; } }), { extend: 'colvis', text: '导出列', className: 'btn-primary', columns: ":not(.notConcernedByColvis)" } ], // 其他原有配置... });
关键说明
- pdfHtml5导出默认会忽略HTML标签,必须通过
format回调或orthogonal数据转换为pdfMake支持的格式。 - 自定义样式需在
customize回调中定义,遵循pdfMake的样式规则。
内容的提问来源于stack exchange,提问作者aicha
相关产品推荐
相关产品推荐

