The second table is most likely printed on top of the first one. You would have to specify the start position of the second table like so:
var res = doc.autoTableHtmlToJson(document.getElementById('tbl1'));
doc.autoTable(res.columns, res.data);
var res2 = doc.autoTableHtmlToJson(document.getElementById('tbl2'));
doc.autoTable(res2.columns, res2.data, {
startY: doc.lastAutoTable.finalY + 50
});
Answer from Simon Bengtsson on Stack Overflow
» npm install jspdf-autotable
Videos
The second table is most likely printed on top of the first one. You would have to specify the start position of the second table like so:
var res = doc.autoTableHtmlToJson(document.getElementById('tbl1'));
doc.autoTable(res.columns, res.data);
var res2 = doc.autoTableHtmlToJson(document.getElementById('tbl2'));
doc.autoTable(res2.columns, res2.data, {
startY: doc.lastAutoTable.finalY + 50
});
Example with latest jspdf version
var doc = new jsPDF("landscape");
var header = function () {
doc.setFontSize(14);
doc.setTextColor(40);
doc.setFontStyle('bold');
doc.text("Article", 15, 10);
};
doc.autoTable({html:"#table1", didDrawPage: header});
doc.autoTable({html:"#table2", didDrawPage: header});
doc.autoTable({html:"#table3", didDrawPage: header});
doc.autoTable({html:"#table4", didDrawPage: header});
doc.autoTable({html:"#table5", didDrawPage: header});
doc.save('myPDF.pdf')
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 () {
const doc = new jsPDF();
autoTable(doc, {
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>
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>
- downloadPDF Function in here we need to track the index to give the nested table the right data "not to be static or same data for all the nested tables":
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');
};