返回 导航

其他

hangge.com

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() 这个钩子函数实现,在第 15 行前面插入一个横向长矩形,其他数据行下移。
(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(第 78 行)要放在 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)

回到顶部