You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将多个DataTable导出为PDF并打包成单个压缩文件夹

多DataTable批量导出PDF并打包为ZIP下载方案

问题背景

在分组报表系统中实现了多个隐藏渲染的DataTable,单表PDF下载通过触发对应按钮点击可正常工作:

let singlePDFdownload = function (table_id) {
    $(`.toolbar${table_id} .custom-pdf`).trigger('click')
}

但实现批量下载时,直接触发所有.custom-pdf按钮的点击事件,会导致浏览器弹出多个下载窗口甚至触发安全警告,现有批量代码如下:

const $massPDFExport = $('#massPDFExport')
$massPDFExport.on('click', () => {
    $(`.custom-pdf`).trigger('click')
})

需要实现将所有DataTable的PDF导出文件合并为单个ZIP压缩包下载,避免多弹窗问题。以下是可复现的示例代码:

<link rel="stylesheet" href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.3.6/css/buttons.dataTables.min.css">

<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.3.6/js/dataTables.buttons.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
<script src="https://cdn.datatables.net/buttons/2.3.6/js/buttons.html5.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.3.6/js/buttons.print.min.js"></script>


<script>
    $(document).ready(function () {
        $('#example_1').DataTable({
            dom: 'Bfrtip',
            buttons: [
                'copy', 'csv', 'excel', 'pdf', 'print'
            ]
        });
        $('#example_2').DataTable({
            dom: 'Bfrtip',
            buttons: [
                'copy', 'csv', 'excel', 'pdf', 'print'
            ]
        });
        $('#export_all').on('click', () => {
            $('.buttons-pdf').each(function (a) {
                console.log(9888)
                $(this).trigger("click");
            });
        });
    });
</script>

<a id='export_all' class=''> Export All As PDF</a>

<table id="example_1" class="display nowrap" style="width:100%">
    <thead>
    <tr>
        <th>Name</th>
        <th>Position</th>
        <th>Office</th>
        <th>Age</th>
        <th>Start date</th>
        <th>Salary</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>Tiger Nixon</td>
        <td>System Architect</td>
        <td>Edinburgh</td>
        <td>61</td>
        <td>2011-04-25</td>
        <td>$320,800</td>
    </tr>
    <tr>
        <td>Garrett Winters</td>
        <td>Accountant</td>
        <td>Tokyo</td>
        <td>63</td>
        <td>2011-07-25</td>
        <td>$170,750</td>
    </tr>
    </tbody>
</table>

<table id="example_2" class="display nowrap" style="width:100%">
    <thead>
    <tr>
        <th>Name</th>
        <th>Position</th>
        <th>Office</th>
        <th>Age</th>
        <th>Start date</th>
        <th>Salary</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>Tiger Nixon</td>
        <td>System Architect</td>
        <td>Edinburgh</td>
        <td>61</td>
        <td>2011-04-25</td>
        <td>$320,800</td>
    </tr>
    <tr>
        <td>Garrett Winters</td>
        <td>Accountant</td>
        <td>Tokyo</td>
        <td>63</td>
        <td>2011-07-25</td>
        <td>$170,750</td>
    </tr>
    </tbody>
</table>

解决方案

核心思路是绕过直接触发下载按钮的方式,主动获取每个DataTable的PDF生成数据,将其转换为Blob对象,再用JSZip将所有PDF文件打包为单个ZIP压缩包后下载。

修改后的完整代码

<link rel="stylesheet" href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.3.6/css/buttons.dataTables.min.css">

<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.3.6/js/dataTables.buttons.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
<script src="https://cdn.datatables.net/buttons/2.3.6/js/buttons.html5.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.3.6/js/buttons.print.min.js"></script>


<script>
    $(document).ready(function () {
        // 初始化表格,保存表格实例
        const table1 = $('#example_1').DataTable({
            dom: 'Bfrtip',
            buttons: [
                'copy', 'csv', 'excel', 'pdf', 'print'
            ]
        });
        const table2 = $('#example_2').DataTable({
            dom: 'Bfrtip',
            buttons: [
                'copy', 'csv', 'excel', 'pdf', 'print'
            ]
        });

        // 批量导出逻辑
        $('#export_all').on('click', async () => {
            const zip = new JSZip();
            const tables = [
                { instance: table1, fileName: '报表1.pdf' },
                { instance: table2, fileName: '报表2.pdf' }
            ];

            // 遍历所有表格,生成PDF并添加到ZIP
            for (const tableInfo of tables) {
                const pdfBlob = await generateTablePDF(tableInfo.instance);
                zip.file(tableInfo.fileName, pdfBlob);
            }

            // 生成ZIP并下载
            zip.generateAsync({ type: 'blob' }).then(function(content) {
                const link = document.createElement('a');
                link.href = URL.createObjectURL(content);
                link.download = '所有报表.zip';
                link.click();
                URL.revokeObjectURL(link.href);
            });
        });

        // 生成单个表格的PDF Blob
        function generateTablePDF(tableInstance) {
            return new Promise((resolve) => {
                // 获取表格导出数据
                const exportData = tableInstance.button(0).exportData();
                // 构建PDF文档定义
                const docDefinition = {
                    content: [
                        { text: '报表数据', style: 'header' },
                        {
                            table: {
                                headerRows: 1,
                                body: [exportData.header].concat(exportData.body)
                            }
                        }
                    ],
                    styles: {
                        header: { fontSize: 16, bold: true, margin: [0, 0, 0, 10] }
                    }
                };

                // 生成PDF并转换为Blob
                pdfMake.createPdf(docDefinition).getBlob((blob) => {
                    resolve(blob);
                });
            });
        }
    });
</script>

<a id='export_all' class=''> Export All As PDF</a>

<table id="example_1" class="display nowrap" style="width:100%">
    <thead>
    <tr>
        <th>Name</th>
        <th>Position</th>
        <th>Office</th>
        <th>Age</th>
        <th>Start date</th>
        <th>Salary</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>Tiger Nixon</td>
        <td>System Architect</td>
        <td>Edinburgh</td>
        <td>61</td>
        <td>2011-04-25</td>
        <td>$320,800</td>
    </tr>
    <tr>
        <td>Garrett Winters</td>
        <td>Accountant</td>
        <td>Tokyo</td>
        <td>63</td>
        <td>2011-07-25</td>
        <td>$170,750</td>
    </tr>
    </tbody>
</table>

<table id="example_2" class="display nowrap" style="width:100%">
    <thead>
    <tr>
        <th>Name</th>
        <th>Position</th>
        <th>Office</th>
        <th>Age</th>
        <th>Start date</th>
        <th>Salary</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>Tiger Nixon</td>
        <td>System Architect</td>
        <td>Edinburgh</td>
        <td>61</td>
        <td>2011-04-25</td>
        <td>$320,800</td>
    </tr>
    <tr>
        <td>Garrett Winters</td>
        <td>Accountant</td>
        <td>Tokyo</td>
        <td>63</td>
        <td>2011-07-25</td>
        <td>$170,750</td>
    </tr>
    </tbody>
</table>

关键说明

  1. 保存表格实例:初始化DataTable时保存实例,方便后续调用导出API
  2. 自定义PDF生成:通过exportData()获取表格的表头和数据,手动构建pdfmake的文档定义,生成PDF Blob而不是直接下载
  3. ZIP打包:使用JSZip将所有PDF Blob添加到压缩包,最后生成单个ZIP文件触发下载
  4. 异步处理:因为PDF生成是异步操作,使用async/await确保所有PDF都生成完成后再打包

这种方式只会触发一次下载弹窗,完美解决多窗口和警告问题。

内容的提问来源于stack exchange,提问作者ViaTech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 10:32:03