• JS DataTable中导出PDF中文乱码


    JS DataTable中导出PDF中文乱码

    一. 问题

    在这里插入图片描述

    二. 原因

    DataTable使用pdfmake,pdfmake默认字体为Roboto,不支持中文字体。添加自己的字体,需要引入对应的vfs_fonts.js文件,修改pdfmake.js。
    (在我的项目中,对应datatable文件夹下的vfs_fonts.js和pdfmake.min.js,也有人是改三个文件,vfs_fonts.js,pdfmake.js和dataTable.buttons.min.js,思路对了就没问题)
    主要思路依据:官网上对于添加字体的方法指导
    前端页面的js内dataTable不需要改,PDF导出按钮由前端界面的JS文件中DataTable设置。
    在这里插入图片描述

    三. vfs_fonts.js

    获取中文版的vfs_fonts.js主要有两种方法:自己生成和寻找资源。

    1. 自己生成vfs_fonts.js文件
      首先需要准备字体的ttf文件。官网上对于如何生成有以下三种方法:
      (1)安装pdfmake
      在这里插入图片描述
      (2)通过shell脚本
      官网对于使用shell脚本生成vfs_fonts.js文件的方法指导
      (3)通过php脚本
      我使用的是这种方法,所以前面两种没有详细介绍。
      官网对于使用php脚本生成vfs_fonts.js文件的方法指导
      将字体ttf文件和该php文件放置同一目录下,生成的vfs_fonts.js文件也会在该目录中。
    <?php
        $output = "this.pdfMake = this.pdfMake || {}; this.pdfMake.vfs = {";
        $phpDir=dir('.');
        while (($file=$phpDir->read())!==false) {
            if ($file!='..' && $file!='.' && $file!='makefont.php' && $file!='vfs_fonts.js') {
                $output .= '"';
                $output .= $file;
                $output .= '":"';
                $output .= base64_encode(file_get_contents($file));
                $output .= '",';
            }
        }
        $output=substr($output,0,-1);
        $output .= "};";
    
        if (isset($_REQUEST['tofile'])) {
    	$fh = fopen('vfs_fonts.js', 'w') or die("CAN'T OPEN FILE FOR WRITING");
    	fwrite($fh,$output);
    	fclose($fh);
            echo 'vjs_fonts.js created';
        } else {
            echo $output;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    如果在目录下未生成vfs_fonts.js文件,在浏览器中显示文件内容,可以去掉if (isset($_REQUEST['tofile'])) {}这个判断条件。
    生成的vfs_fonts.js文件如图所示:
    在这里插入图片描述
    需要将前面的"run.php"内容删除,得到:
    在这里插入图片描述
    对比原来Roboto字体的vfs_fonts.js文件,发现要设置normal、bold、italics、bolditalics样式,也是在同一个vfs_fonts.js文件中:
    this.pdfMake = this.pdfMake || {}; this.pdfMake.vfs = {
    "xxx-Italic.ttf":"xxxxxxxxxxxxxxxx",
    "xxx-Medium.ttf":"xxxxxxxxxxxxxxxx",
    "xxx-MediumItalic.ttf":"xxxxxxxxxxxxxxxx",
    "xxx-Regular.ttf":"xxxxxxxxxxxxxxxx"
    }

    使用该方法我导出的pdf能显示部分中文字体,也只能显示部分英文字体,不知道是生成方式有问题还是我字体ttf文件有问题。于是去找现成的资源了。

    1. 在网上寻找vfs_fonts.js资源
      资源下载地址
    四. pdfmake.js

    (以下内容找不到可以去dataTable.buttons.min.js找,找的时候找相似格式,主要讲个思路)

    1. 设置字体
      搜索Roboto,找到它设置字体样式部分,在后面添加自己的字体Chinese(这里四个样式用同一份字体文件):
    pdfMake.fonts = {
      Roboto: {
        normal: 'Roboto-Regular.ttf',
        bold: 'Roboto-Medium.ttf',
        italics: 'Roboto-Italic.ttf',
        bolditalics: 'Roboto-MediumItalic.ttf'
      },
      Chinese: {
      	normal: 'Chinese.ttf',
        bold: 'Chinese.ttf',
        italics: 'Chinese.ttf',
        bolditalics: 'Chinese.ttf'
      }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. 检查createPdf()函数
      在这里插入图片描述
      确保形式是pdfMake.createPdf(docDefinition, tableLayouts, fonts, vfs)
    2. 修改defaultStyle
      在这里插入图片描述
      找如下格式:
      在这里插入图片描述
      此外,将pdfmake.js里除了pdfmake.fonts = {}外所有的“Roboto”改成自己的字体“Chinese”。
    五. 解决

    在这里插入图片描述

    六.参考资料

    一些有用的参考资料:
    导出PDF按钮在前端界面设置,而非Datatable中设置的
    官网中关于非英文字符导出PDF乱码的讨论
    datatable 导出无乱码中文pdf文件
    pdfmake实现中文支持,解决中文乱码问题

  • 相关阅读:
    Sentinel实战(待完善)
    Linux下IIC子系统和触摸屏驱动
    C语言和Rust语言的互相调用(2)(Rust调用C)
    @Async注解
    Vue前端项目运行
    1012 The Best Rank
    IP&TCP知识
    【前端】js下载url文件
    Linux——ansible剧本
    高通410 随身WiFi 5分钟自动重启解决方案
  • 原文地址:https://blog.csdn.net/X_To_Y/article/details/134026399