使用jspdf和jspdf-autotable制作pdf中的嵌套表格

4
如何使用jspdf和jspadf-autotable在PDF中实现嵌套表格?类似下面的图片:

Nested tables in pdf

2个回答

14

在 jspdf-autotable 中没有原生支持嵌套表格的功能,但可以通过 didDrawCell 钩子来绘制任何内容(包括其他 autotables)。

var elem = document.getElementById("generate");
elem.onclick = function () {
var doc = new jsPDF();
doc.autoTable({
    html: '#table',
    didDrawCell: function (data) {
        if (data.column.dataKey === 5 && data.cell.section === 'body') {
            doc.autoTable({
                head: [["One", "Two", "Three", "Four"]],
                body: [
                    ["1", "2", "3", "4"],
                    ["1", "2", "3", "4"],
                    ["1", "2", "3", "4"],
                    ["1", "2", "3", "4"]
                ],
                startY: data.cell.y + 2,
                margin: {left: data.cell.x + data.cell.padding('left')},
                tableWidth: 'wrap',
                theme: 'grid',
                styles: {
                    fontSize: 7,
                    cellPadding: 1,
                }
            });
        }
    },
    columnStyles: {
        5: {cellWidth: 40}
    },
    bodyStyles: {
        minCellHeight: 30
    }
});
doc.save('table.pdf');
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.2.3/jspdf.plugin.autotable.min.js"></script>
<button id="generate">Generate PDF</button>

<table id="table" style="display: none;">
    <thead>
    <tr>
        <th>ID</th>
        <th>First name</th>
        <th>Last name</th>
        <th>Email</th>
        <th>Country</th>
        <th>Table</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td align="right">1</td>
        <td>Donna</td>
        <td>Moore</td>
        <td>dmoore0@furl.net</td>
        <td>China</td>
        <td></td>
    </tr>
    <tr>
        <td align="right">2</td>
        <td>Janice</td>
        <td>Henry</td>
        <td>jhenry1@theatlantic.com</td>
        <td>Ukraine</td>
        <td></td>
    </tr>
    <tr>
        <td align="right">3</td>
        <td>Ruth</td>
        <td>Wells</td>
        <td>rwells2@constantcontact.com</td>
        <td>Trinidad and Tobago</td>
        <td></td>
    </tr>
    <tr>
        <td align="right">4</td>
        <td>Jason</td>
        <td>Ray</td>
        <td>jray3@psu.edu</td>
        <td>Brazil</td>
        <td></td>
    </tr>
    <tr>
        <td align="right">5</td>
        <td>Jane</td>
        <td>Stephens</td>
        <td>jstephens4@go.com</td>
        <td>United States</td>
        <td></td>
    </tr>
    <tr>
        <td align="right">6</td>
        <td>Adam</td>
        <td>Nichols</td>
        <td>anichols5@com.com</td>
        <td>Canada</td>
        <td></td>
    </tr>
    </tbody>
</table>


谢谢Simon,我相信它会满足我的需求。 - Prince
太好了!对于目前实现这个功能的混乱代码感到抱歉。将在库中的某个时刻进行改进。 - Simon Bengtsson
了不起的回答 @SimonBengtsson - Beckham_Vinoth
@SimonBengtsson如果内部表格大小不同,如何更改行高? - rena
嘿@SimonBengtsson,这似乎是我的问题的解决方案,但在尝试并重写代码后,我仍然无法让它做我想要的事情。当一个表格(内嵌另一个表格)的内容不适合单个页面并被分成多个页面时,你认为像那样的表格是否仍然将其标题复制到下一页?我试图实现的是有一个“主”表格,其标题显示在每一页上,并将第二个autotable嵌入其正文中(当它被分割时,也会在每一页上显示其标题)。这可行吗,还是我要求太多了? - Andrew Cyrul
显示剩余2条评论

0
使用jspdf和jspdf-autotable添加嵌套表格,并使其动态化,以便表格和嵌套表格中的数据来自服务或用户: 我正在使用React,但您可以在vanila JS或任何其他库或框架中实现它。
1.在“html页面”或“jsx”中添加主表格,您可以通过数组映射而不是添加静态表格行:
<div className="App">
        <button
            onClick={downloadPDF}
            style={{
                marginTop: 20,
                background: 'blue',
                color: 'white',
                width: '200px',
                height: '50px',
            }}
        >
            Download as PDF
        </button>
        <table id="table" style={{ display: 'none' }}>
            <thead>
                <tr>
                    <th align="center">Column1</th>
                    <th align="center">Column2</th>
                    <th align="center">Column3</th>
                    <th align="center">Column4</th>
                    <th align="center">Column5-Table</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td align="center">1</td>
                    <td>row1</td>
                    <td>row1</td>
                    <td>row1</td>
                    <td></td>
                </tr>
                <tr>
                    <td align="center">2</td>
                    <td>row2</td>
                    <td>row2</td>
                    <td>row2</td>
                    <td></td>
                </tr>
                <tr>
                    <td align="center">1</td>
                    <td>row3</td>
                    <td>row3</td>
                    <td>row3</td>
                    <td></td>
                </tr>
                <tr>
                    <td align="center">3</td>
                    <td>row4</td>
                    <td>row4</td>
                    <td>row4</td>
                    <td></td>
                </tr>
            </tbody>
        </table>
    </div>
  1. 在这里的downloadPDF函数中,我们需要跟踪索引以为嵌套表提供正确的数据,而不是静态或相同的数据用于所有嵌套表:
const downloadPDF = () => {
        const doc = new jsPDF();
        doc.autoTable({
            headStyles: {
                valign: 'middle',
                halign: 'center',
            },
            html: '#table',
            didDrawCell: function (data) {
                let neastedTableData = [
                    [
                        ['32423423', 'ady arabiat-1', 'false', '2022-07-07'],
                        ['32423423', 'ady arabiat-1', 'false', '2022-07-07'],
                    ],
                    [
                        ['32423423', 'ady arabiat-2', 'false', '2022-07-07'],
                        ['32423423', 'ady arabiat-2', 'false', '2022-07-07'],
                    ],
                    [
                        ['32423423', 'ady arabiat-3', 'false', '2022-07-07'],
                        ['32423423', 'ady arabiat-3', 'false', '2022-07-07'],
                        ['32423423', 'ady arabiat-3', 'false', '2022-07-07'],
                        ['32423423', 'ady arabiat-3', 'false', '2022-07-07'],
                        ['32423423', 'ady arabiat-3', 'false', '2022-07-07'],
                    ],
                    [
                        ['32423423', 'ady arabiat-4', 'false', '2022-07-07'],
                        ['32423423', 'ady arabiat-4', 'false', '2022-07-07'],
                        ['32423423', 'ady arabiat-4', 'false', '2022-07-07'],
                        ['32423423', 'ady arabiat-4', 'false', '2022-07-07'],
                        ['32423423', 'ady arabiat-4', 'false', '2022-07-07'],
                    ],
                    [
                        ['32423423', 'ady arabiat-5', 'false', '2022-07-07'],
                        ['32423423', 'ady arabiat-5', 'false', '2022-07-07'],
                        ['32423423', 'ady arabiat-5', 'false', '2022-07-07'],
                    ],
                    [
                        ['32423423', 'ady arabiat-6', 'false', '2022-07-07'],
                        ['32423423', 'ady arabiat-6', 'false', '2022-07-07'],
                        ['32423423', 'ady arabiat-6', 'false', '2022-07-07'],
                    ],
                ];
                if (data.column.dataKey === 4 && data.cell.section === 'body') {
                    let index = data.row.index; //check the index so you add the data for the nested Table dynamically depends on which row you are in
                    doc.autoTable({
                        head: [
                            [
                                'N-Column1',
                                'N-Column2',
                                'N-Column3',
                                'N-Column4',
                            ],
                        ],
                        body: neastedTableData[index], //index here
                        startY: data.cell.y + 2,
                        margin: {
                            left: data.cell.x + data.cell.padding('left'),
                        },
                        tableWidth: 'wrap',
                        theme: 'grid',
                        styles: {
                            fontSize: 7,
                            cellPadding: 2,
                        },
                    });
                }
            },
            columnStyles: {
                4: { cellWidth: 85 },
            },
            bodyStyles: {
                minCellHeight: 45,
            },
        });
        doc.save('table.pdf');
    };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接