JS - 使用jsPDF-AutoTable库生成带表格的PDF文件3(进阶用法、中文乱码解决)
作者:hangge | 2018-11-23 08:10
五、添加其他文字内容
有时我们导出的 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)运行结果如下,可以看到表格内容区域的中文现在显示正常了。不过可惜的是,标题部分的中文乱码问题目前还没法解决。
全部评论(0)