Reputation: 75
How to achieve nested tables in a PDF using jspdf and jspadf-autotable? Something similar to the picture below:
Upvotes: 4
Views: 14313
Reputation: 1279
To add nested table using jspdf and jspdf-autotable and to make it dynamic so the data in both table and nested table are coming from a service or from the user: I am using React but you can implement it in vanila JS or any other library or framework.
1.add the main table in the "html page" or "jsx" you can map through array instead of adding static table rows:
<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>
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');
};
Upvotes: 0
Reputation: 8151
There is no native support for having nested tables in jspdf-autotable but you can draw any content (including other autotables) with the didDrawCell hook.
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>[email protected]</td>
<td>China</td>
<td></td>
</tr>
<tr>
<td align="right">2</td>
<td>Janice</td>
<td>Henry</td>
<td>[email protected]</td>
<td>Ukraine</td>
<td></td>
</tr>
<tr>
<td align="right">3</td>
<td>Ruth</td>
<td>Wells</td>
<td>[email protected]</td>
<td>Trinidad and Tobago</td>
<td></td>
</tr>
<tr>
<td align="right">4</td>
<td>Jason</td>
<td>Ray</td>
<td>[email protected]</td>
<td>Brazil</td>
<td></td>
</tr>
<tr>
<td align="right">5</td>
<td>Jane</td>
<td>Stephens</td>
<td>[email protected]</td>
<td>United States</td>
<td></td>
</tr>
<tr>
<td align="right">6</td>
<td>Adam</td>
<td>Nichols</td>
<td>[email protected]</td>
<td>Canada</td>
<td></td>
</tr>
</tbody>
</table>
Upvotes: 14