JavaScript JSON 数据转 pdf 下载

1,468 阅读2分钟

下载 jspdf jspdf-autotable

yarn add jspdf -S / npm install jspdf yarn add jspdf-autotable -S / npm install jspdf-autotable

jsPDF jspdf-autotable

生成 pdf

import jsPDF from 'jspdf'
import 'jspdf-autotable'

const doc = new jsPDF()

doc.autoTable({
  head: [['Name', 'Email', 'Country']],
  body: [
    ['David', 'david@example.com', 'Sweden'],
    ['Castille', 'castille@example.com', 'Spain']
  ],
})

doc.save('table.pdf')

就这么简单、pdf就生成了,如需要改变 pdf 的样式可以通过修改 styles 来处理

坑点: 如果导出的内容中含有中文,则会乱码

解决乱码问题

乱码问题官方也有说明解决方案,但是比较模糊、这里总结下

下载官方源代码

jsPDF 源代码

打开 fontconverter/fontconverter.html 文件 会看到如下页面

下载需要的字体

免费字体库

生成 base64 格式的字体文件

  • 选择刚下载的字体文件
  • 点击 create 按钮就可以生成 base64 格式的字体文件(生成的是一个js文件,还不小😫)

【font-normal.js 文件内容如下:】

import jsPDF from 'jspdf'
var font = 'xxx'
const callAddFont = function () {
  this.addFileToVFS('font-normal.ttf', font);
  this.addFont('font-normal.ttf', 'font', 'normal');
};
jsPDF.API.events.push(['addFonts', callAddFont])

使用生成的字体图标

import jsPDF from 'jspdf'
import 'jspdf-autotable'
import 'font-normal.js' // 生成的字体文件

const doc = new jsPDF()

doc.autoTable({
  head: [['Name', 'Email', 'Country']],
  body: [
    ['David', 'david@example.com', 'Sweden'],
    ['Castille', 'castille@example.com', 'Spain']
  ],
  styles: { font: 'font'} // 注意这里必须配置,不然不生效
})

doc.save('table.pdf')

打开页面试试,嗯下载pdf成功、乱码问题也好了,但出现了一个新问题,页面加载[超慢]

😄、以这种形式提交测试肯定会被砍死的,继续优化

解决加载字体文件过大影响页面加载问题

改造下载的字体文件

【改造前】

import jsPDF from 'jspdf'
var font = 'xxx'
const callAddFont = function () {
  this.addFileToVFS('font-normal.ttf', font);
  this.addFont('font-normal.ttf', 'font', 'normal');
};
jsPDF.API.events.push(['addFonts', callAddFont])

【改造后】

var font = 'xxx'

js 预加载

App.vue

mounted() {
  setTimeout(() => {
    const preloadLink = document.createElement('link')
    preloadLink.href = '/static/font-normal.js'
    preloadLink.rel = 'preload'
    preloadLink.as = 'script'
    document.head.appendChild(preloadLink)
  }, 500)
}

需要的时候在执行

需要导出的 .vue 文件里面执行

mounted() {
  if (typeof font === 'undefined') { // 防止重复执行
    const preloadedScript = document.createElement("script");
    preloadedScript.src = "/static/font-normal.js";
    document.body.appendChild(preloadedScript)
  }
}

生成 pdf 代码

import jsPDF from 'jspdf'
import 'jspdf-autotable'

let styles = { valign: 'middle' }

if (typeof font !== 'undefined') {
  const callAddFont = function () {
    this.addFileToVFS('font-normal.ttf', font);
    this.addFont('font-normal.ttf', 'font', 'normal');
  };
  jsPDF.API.events.push(['addFonts', callAddFont])
  styles = { font: 'font', valign: 'middle' }
}

const doc = new jsPDF()

doc.autoTable({
  head: [['Name', 'Email', 'Country']],
  body: [
    ['David', 'david@example.com', 'Sweden'],
    ['Castille', 'castille@example.com', 'Spain']
  ],
  styles
})

doc.save('table.pdf')
现在打开页面看看,基本上对页面加载就没有影响了

博文推荐

【笔记不易,如对您有帮助,请点赞,谢谢】