如何彻底解决SpreadJS导出PDF字体乱码问题

下载SpreadJS最新版本

SpreadJS导出PDF是一个强大的功能,解决了很多用户的实际问题,但是在导出PDF时有些问题始终困扰着很多开发者,例如排版、字体乱码等问题。那么本文就着重讲解一下字体乱码的解决办法。

问题分析

有些朋友会有疑问,同样是使用了printInfo实例来调整样式,为什么浏览器打印看着好好的字体,导出到PDF就乱码了呢?

这是由PDF文件的特殊性造成的。PDF是Portable Document Format的简称,意为“便携式文档格式”,它原生仅仅带有英文字体,不包含任何中文字体,因此当导出的内容中含有中文字体编码时,一定会显示乱码,所以通常情况下,我们都需要为PDF进行字体注册操作。

Spread JS 对于导出PDF时的字体乱码的处理方式,分为两个部分,一是表格内容,二是页眉页脚。下面我将利用一个代码示例来说明如何处理乱码。

示例下载与部署

点此下载字体文件,下载文件如下图所示:

SpreadJS

下载完毕后,将得到的zip包解压到您系统的任意目录下,本例是直接解压到D盘根目录下。 这个示例是纯前端工程,可以直接运行,但是JS访问目录下的字体文件时,很大概率会被浏览器的安全策略所限制,这是前端语言无法避免的问题,所以我们先把项目部署到服务器。 本例直接采用了Win10系统的IIS服务器来部署。

部署成功后,访问localhost:[port num]/index.html即可访问到示例页面,本例设置端口是8899,即:http://localhost:8899/index.html

SpreadJS

示例分析

为了把问题考虑得更全面,本例采用了多种字体和多种注册方法来全面展示如何解决导出PDF的乱码问题,字体包括微软雅黑和宋体,注册方法分为前端注册和Ajax访问后端字体文件注册两种方式。

1、前端字体注册:

要实现前端注册字体,需要获取到对应字体文件的base64编码字符串,示例目录下的data/fonts.js中有两种字体的base64编码,分别是MTCORSVA和simkai,代码如下:

function addFontsToFontManager(fontsObj) {
    var fonts = {
        normal: fontsObj["simkai.ttf"]
    };
    GC.Spread.Sheets.PDF.PDFFontsManager.fallbackFont = function (font) {
        var fontInfoArray = font.split(' ');
        var fontName = fontInfoArray[fontInfoArray.length - 1];
        if (fontName === 'mtcorsva') {
            return fonts.normal;
        }
    }
}

其中参数fontsObj就是fonts.js中定义的字体编码实例。此处实现了将simkai注册到PDF中,除此之外还将默认字体设置为mtcorsva。

2、 访问后台字体文件执行注册:

由于字体文件通常比较大,而前端注册字体的方法要求在页面加载时就要加载进来,这会导致前端加载时间长,影响性能。而且字体文件的base64编码通常也需要事先生成,这给开发同学们带来了不小的麻烦。

后台字体文件注册可以解决这些问题,字体文件在服务器上存储,只有当需要导出PDF时才执行加载操作,简直完美解决问题!

先看代码:

function registerServerFont(name, type, serverPath) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', serverPath, true);
    xhr.responseType = 'blob';

    xhr.onload = function (e) {
        if (this.status == 200) {
            // get binary data as a response
            var blob = this.response;

            //将Blob 对象转换成 ArrayBuffer
            var reader = new FileReader();
            reader.onload = function (e) {
                var fontrrayBuffer = reader.result;
                var fonts = GC.Spread.Sheets.PDF.PDFFontsManager.getFont(name) || {};
                fonts[type] = fontrrayBuffer;
                GC.Spread.Sheets.PDF.PDFFontsManager.registerFont(name, fonts);
            }
            reader.readAsArrayBuffer(blob);
        }
    };

    xhr.send();
}

OK,熟悉Ajax的同学就明白了这里实际上采用了XMLHttpRequest对象的数据流读取了blob格式的字体文件,然后把这个流直接注册到PDFFontsManager中,实现了字体注册操作。 调用方法很简单,如下:

registerServerFont('微软雅黑', 'normal', 'font/msyh.ttf');

第一个参数对应了PDF中的字体名称,最后一个参数指定了字体文件的相对路径(这就是为什么要先部署后才能访问)。

如果设置的字体在后台字体库中没有怎么办?其实解决方法也很简单,我们的客户需要的首先应该是一个能够阅读的PDF文件,当服务器端没有对应的字体文件时,可以指定别的字体库来代替,例如:

registerServerFont('Times New Roman', 'normal', 'font/simsun.ttf');

这是我们小伙伴遇到的一个实际的问题,客户的Excel中显示的中文字体是Times New Roman,但是Times New Roman本身是英文字体库,并不包含中文,在这种情况下浏览器会自动指定一个字体,比如简宋,那么我们在注册PDF字体时也可以灵活应用。

3、页眉页脚乱码怎么办:

有同学发现,导出PDF时如果设置了页眉页脚,这里出现乱码怎么解决呢?其实学习指南里有代码示例,只是不在PDF导出里,而是在自定制打印的“描述”标签页的最下边,如图:

SpreadJS

其中的printInfo.headerCenter("&\"Comic Sans MS\"System Information");的参数中是以“ & ”开头,后面的Comic Sans MS被双引号引起来了,这里就制定了字体名称。 在本例中,我们稍稍修改一下代码,验证一下这个方法: 在432行处添加一行:

<input type="text" id="headerCenter" value="表头内容" class="input" style="font-size: 16px">

在168行处添加一行:

printInfo.headerCenter('&"simsun"' + $("#headerCenter").val());

再执行导出

SpreadJS

注意:导出的PDF中仍会有一处乱码,这是有意留下的,这里的字体示例中没有注册,留给同学们练手。

SpreadJS

纯前端表格控件SpreadJS,是市面上布局与功能都与 Excel 高度类似的一款表格控件,全中文操作界面,适用于.NET、Java、移动端等多个平台的类 Excel 数据开发,备受华为、中通、民航飞行学院等国内知名企业客户青睐。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值