JS - 使用jsPDF-AutoTable库生成带表格的PDF文件3(进阶用法、中文乱码解决)
五、添加其他文字内容
有时我们导出的 pdf 文件中除了表格外,还需显示标题或者一些其他的文字信息。这个关键在于设置好坐标位置,下面通过样例进行演示。
1,添加一个简单的标题
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="jspdf.min.js" charset="utf-8"></script> <script src="jspdf.plugin.autotable.js" charset="utf-8"></script> <script type="text/javascript"> //页面初始化 function init() { //表格列头 var columns = ["ID", "Name", "Country"]; //表格数据 var rows = [ [1, "Shaw", "Tanzania"], [2, "Nelson", "Kazakhstan"], [3, "Garcia", "Madagascar"] ]; //只支持pt(不支持 mm 或 in) var doc = new jsPDF('p', 'pt'); doc.autoTable(columns, rows, { addPageContent: function(data) { doc.text("This is header", 40, 30); } }); doc.save('table.pdf'); } </script> </head> <body onload="init()"> </body> </html>
2,更加复杂的文字样例
var doc = new jsPDF(); //添加表格上方的标题 doc.setFontSize(18); doc.text('This is header', 14, 22); //添加表格上方的文字描述 doc.setFontSize(11); doc.setTextColor(100); var pageWidth = doc.internal.pageSize.width || doc.internal.pageSize.getWidth(); var text = doc.splitTextToSize('Welcome to hangge.com.......', pageWidth - 35, {}); doc.text(text, 14, 30); //添加表格 doc.autoTable(columns, rows, {startY: 50, showHeader: 'firstPage'}); //添加表格下方的文字 doc.text(text, 14, doc.autoTable.previous.finalY + 10); doc.save('table.pdf');
六、同一 pdf 文件中添加多个表格
1,效果图
2,样例代码
注意:由于下方两个表格是并列的,所以这里加个保护:在添加最后一个表格前,将页码重置成上一个表格的页码,防止它自动跳到下一页。var doc = new jsPDF(); //上方表格 doc.autoTable(columns, rows); let first = doc.autoTable.previous; //左下方表格 doc.autoTable(columns, rows, { startY: first.finalY + 10, showHeader: 'firstPage', margin: {right: 107} }); //将页码重置成前面一个表格的页码,保证这两个表格并列显示(加个保护,如果本来就在一页不加也行) doc.setPage(1 + doc.internal.getCurrentPageInfo().pageNumber - doc.autoTable.previous.pageCount); //右下方表格 doc.autoTable(columns, rows, { startY: first.finalY + 10, showHeader: 'firstPage', margin: {left: 107} }); doc.save('table.pdf');
七、将页面上的 table 导出成 pdf 文件
1,效果图
(1)在 html 页面上有一个 table,点击按钮后会在将内容导出成一个 pdf 文件。
(2)生成的 pdf 文件内容如下:
2,样例代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="jspdf.min.js" charset="utf-8"></script> <script src="jspdf.plugin.autotable.js" charset="utf-8"></script> <script type="text/javascript"> //导出按钮点击 function exportPDF() { var doc = new jsPDF(); var elem = document.getElementById("table"); var res = doc.autoTableHtmlToJson(elem); doc.autoTable(res.columns, res.data); doc.save('table.pdf'); } </script> </head> <body> <button type="button" name="button" onclick="exportPDF()">导出</button> <table id="table"> <thead> <tr> <th>ID</th> <th>First name</th> <th>Last name</th> <th>Email</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>Donna</td> <td>Moore</td> <td>dmoore0@furl.net</td> </tr> <tr> <td>2</td> <td>Janice</td> <td>Henry</td> <td>jhenry1@theatlantic.com</td> </tr> </tbody> </table> </body> </html>
八、单元格合并
1,效果图
2,样例代码
(1)横向单元格合并借助 drawRow() 这个钩子函数实现,在第 1、5 行前面插入一个横向长矩形,其他数据行下移。
(2)纵向单元格合并借助 drawCell() 这个钩子函数实现,每 5 行数据创建一个竖直矩形覆盖在第一列位置。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="jspdf.min.js" charset="utf-8"></script> <script src="jspdf.plugin.autotable.js" charset="utf-8"></script> <script type="text/javascript"> //页面初始化 function init() { //表格列头 var columns = [ {title: "ID", dataKey: "id"}, {title: "Name", dataKey: "name"}, {title: "Country", dataKey: "country"} ]; //表格数据 var rows = [ {"id": 1, "name": "Shaw", "country": "Tanzania"}, {"id": 2, "name": "Nelson", "country": "Kazakhstan"}, {"id": 3, "name": "Garcia", "country": "Madagascar"}, {"id": 4, "name": "Shaw", "country": "Tanzania"}, {"id": 5, "name": "Nelson", "country": "Kazakhstan"}, {"id": 6, "name": "Garcia", "country": "Madagascar"}, {"id": 7, "name": "Shaw", "country": "Tanzania"}, {"id": 8, "name": "Nelson", "country": "Kazakhstan"}, {"id": 9, "name": "Garcia", "country": "Madagascar"}, {"id": 10, "name": "Garcia", "country": "Madagascar"} ]; var doc = new jsPDF(); doc.autoTable(columns, rows, { theme: 'grid', //实现横向单元格合并(在第一行、第五行前面增加一个合并行) drawRow: function (row, data) { doc.setFontStyle('bold'); doc.setFontSize(10); if (row.index === 0) { doc.setTextColor(200, 0, 0); doc.rect(data.settings.margin.left, row.y, data.table.width, row.height, 'S'); doc.autoTableText("Group1", data.settings.margin.left + data.table.width / 2, row.y + row.height / 2, { halign: 'center', valign: 'middle' }); data.cursor.y += row.height; } else if (row.index === 5) { doc.rect(data.settings.margin.left, row.y, data.table.width, row.height, 'S'); doc.autoTableText("Group2", data.settings.margin.left + data.table.width / 2, row.y + row.height / 2, { halign: 'center', valign: 'middle' }); data.cursor.y += row.height; } if (row.index % 5 === 0) { var posY = row.y + row.height * 6 + data.settings.margin.bottom; var pageHeight = doc.internal.pageSize.height || doc.internal.pageSize.getHeight(); if (posY > pageHeight) { data.addPage(); } } }, //实现纵向单元格合并 drawCell: function (cell, data) { // Rowspan if (data.column.dataKey === 'id') { if (data.row.index % 5 === 0) { doc.rect(cell.x, cell.y, data.table.width, cell.height * 5, 'S'); doc.autoTableText(data.row.index / 5 + 1 + '', cell.x + cell.width / 2, cell.y + cell.height * 5 / 2, { halign: 'center', valign: 'middle' }); } return false; } } }); doc.save('table.pdf'); } </script> </head> <body onload="init()"> </body> </html>
九、解决中文乱码问题
1,问题描述
由于 jsPDF 默认是不支持中文的。如果表格文字中包含有中文(汉字),那么导出后里面中文部分就会变成乱码:
2,解决办法
(1)首先我们将 jsPDF-CustomFonts-support 这个 jsPDF 的字体扩展库以及中文字体下载到本地,并放到项目文件夹中:
(2)使用方法如下:
注意:字体扩展的两个 js(第 7、8 行)要放在 autotable.js 前面
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="jspdf.min.js" charset="utf-8"></script> <script src="jspdf.customfonts.min.js"></script> <script src="default_vfs.js"></script> <script src="jspdf.plugin.autotable.js" charset="utf-8"></script> <script type="text/javascript"> //页面加载完毕后自动导出pdf function init() { //表格列头 var columns = ["ID", "姓名", "籍贯"]; //表格数据 var rows = [ [1, "小李", "北京"], [2, "小王", "广东"], [3, "小刘", "福建"] ]; //只支持pt(不支持 mm 或 in) var doc = new jsPDF('p', 'pt'); //添加并设置字体 doc.addFont('NotoSansCJKtc-Regular.ttf', 'NotoSansCJKtc', 'normal'); doc.setFont('NotoSansCJKtc'); doc.autoTable(columns, rows, { styles: { font: "NotoSansCJKtc"} //表格里设置为中文字体 }); doc.save('table.pdf'); } </script> </head> <body onload="init()"> </body> </html>
(3)运行结果如下,可以看到表格内容区域的中文现在显示正常了。不过可惜的是,标题部分的中文乱码问题目前还没法解决。