jsPdf中文乱码的问题
2023.03.06 Mon

需求是 前端将通过富文本编辑器产生的 rawHtml 发给后端,在展示的时候需要将后端此时传过来的 rawHtml 直接转化成 pdf 下载查看。这里选择使用 jsPdf 在前端利用 html()方法生成 pdf 文件,但是遇到了中文乱码以及在同时使用 TailwindCSS 导致的标签默认样式被覆盖的问题。

字体乱码

  • 通过翻阅官方文档,找到了关于字体乱码的解决方法--手动添加字体。

    Use of Unicode Characters / UTF-8:
    The 14 standard fonts in PDF are limited to the ASCII-codepage. If you want to use UTF-8 you have to integrate a custom font, which provides the needed glyphs. jsPDF supports .ttf-files. So if you want to have for example Chinese text in your pdf, your font has to have the necessary Chinese glyphs. So, check if your font supports the wanted glyphs or else it will show garbled characters instead of the right text.
    To add the font to jsPDF use our fontconverter in /fontconverter/fontconverter.html. The fontconverter will create a js-file with the content of the provided ttf-file as base64 encoded string and additional code for jsPDF. You just have to add this generated js-File to your project. You are then ready to go to use setFont-method in your code and write your UTF-8 encoded text.
    Alternatively you can just load the content of the *.ttf file as a binary string using fetch or XMLHttpRequest and add the font to the PDF file:

    1
    2
    3
    4
    5
    6
    const doc = new jsPDF()
    const myFont = ... // load the \*.ttf font file as binary string
    // add the font to jsPDF
    doc.addFileToVFS("MyFont.ttf", myFont);
    doc.addFont("MyFont.ttf", "MyFont", "normal");
    doc.setFont("MyFont");
  • 方法

    下载中文 ttf 字体(思源宋体),通过插件提供的转换工具将 ttf 字体文件转成 base64 编码.

    将要输出为 pdf 文件 的 dom 元素设置 font-family 为下载的字体。

    • html 页面引入 将上面官方生成的 js 文件通过 script 标签引入

    • 手动导入
      用记事本打开生成的 js 文件,将变量 font 导出,删除 font 变量外无用的代码,在需要的地方引入该变量。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      import { font } from '../assets/SourceHanSansCN'

      const doc = new jsPDF('p', 'pt', 'a4')
      const rawHtml="<div style='font-family:MyFont;'>你好</div>"
      // add the font to jsPDF
      doc.addFileToVFS('MyFont.ttf', font)
      doc.addFont('MyFont.ttf', 'MyFont', 'normal')
      doc.setFont('MyFont')
      doc.html(rawHtml, { callback: (doc) => doc.save(’test‘), x: 10, y: 10 })

TailwindCSS 显示 vanilla HTML 排版

在使用 TailwindCSS 时,它会修改并覆盖标签的默认样式,如 h1/h2 标签默认样式被取消,这会导致在将需要以正常 html 格式排版时(如富文本编辑器里面标题)样式被 TailwindCSS 覆盖。所以 TailwindCSS 官方提供了排版插件,只需要正确安装插件,使用 prose 样式类即可还原默认 HTML 样式。

1
npm install -D @tailwindcss/typography
1
2
3
4
5
6
7
8
9
module.exports = {
theme: {
// ...
},
plugins: [
require('@tailwindcss/typography'),
// ...
],
}
1
2
<!-- 添加prose -->
<h1 class="prose">I Have A Dream</h1>

检测到页面内容有更新,是否刷新页面