在前端导出PDF,解决中文乱码一直是一个头疼的问题。要解决这个问题,需要将ttf等字体文件内容注册到页面PDF生成器中。但是之前网页是没有权限直接获取客户机器字体文件,这时就需要从服务器下载字体文件或者提示用户选择字体文件上传到页面。对于动辄数十兆(M)的中文字体文件,网络不好时并不是一个好的解决方案。

Chrome 103

提高页面性能的一种方法是对当前的使用资源经行提示。例如,预加载文件或连接到不同的服务器。

<link as="font" crossorigin="anonymous"
href="..." rel="preload">
<link as="font" crossorigin="anonymous"
href="..." rel="preload">
<link href="https://web-dev.imgix.net"
rel="preconnect">

但是在服务器发送页面内容之前,浏览器是无法对提示采取行动。

服务器需要几百毫秒才能生成一个请求页面,在浏览器开始接收页面内容之前,服务器是不进行任何处理的。但是在这个等待的过程中,服务器是需要一些固定子资源,例如 CSS 文件、JavaScript 和图像内容,这个时候服务器可以立即响应新的 HTTP 103 Early Hints 状态代码,并询问浏览器预加载那些子资源,以提供高座效率。

一旦服务器生成了页面,它就可以用正常的 HTTP 200 响应发送它。当页面进入时,浏览器已经开始加载所需的资源。作为一个新 HTTP 状态代码,所以它需要更新我们服务器。

本地字体访问

Web 上的字体一直是一个挑战,尤其是允许用户创建自己的图形和设计的应用程序就是一个难点。现在应用程序只能使用网络字体,但无法获得用户在其计算机上安装的字体列表;而且,无法访问完整的字体表数据,如果我们需要实现自己的自定义文本堆栈,就很复杂。

而在新版本中,这个问题得到了很好解决。Chrome 103版本中新的字体API可以让web应用获取到用户在本地电脑上安装的所有字体信息,同时还可以获取到字体内容。

调用window.queryLocalFonts(),会返回用户安装字体的数组。

const pickedFonts = await self.queryLocalFonts();
for (const fontData of pickedFonts) {
console.log(fontData.postscriptName);
console.log(fontData.fullName);
console.log(fontData.family);
console.log(fontData.style);
}

处于安全性的考虑,获取字体信息需要获取到用户的授权。当第一调用queryLocalFonts时,Chrome会弹出权限申请:

权限同意后,就可以获取所有安装字体的信息

使用navigator.permissions.query可以检查权限

async function requestPremission(){
const { state } = await navigator.permissions.query({
name: "local-fonts"
});
console.log(state)
if (state === 'granted') {
query();
} else if (state === 'prompt') {
alert("请授予权限!")
query();
}
else{
alert("没有权限获取字体")
}
}

使用本地字体导出PDF

接下来我们介绍如何使用本地字体进行PDF导出。

选择需要使用的字体内容,注册到PDF生成工具中

使用blob 方法可以获取字体文件内容

let currentFont = fontList[fontListSelect.value];

const blob = await currentFont.blob();

使用字体名称注册

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

接下来导出含有本地字体的PDF:

这里需要注意,使用本地字体风险也是不可避免的,如果用户没有安装对应字体,在网页中浏览器会使用其他字体进行渲染,倒是PDF依旧会有出现乱码的风险。解决方法是需要从服务器中下载目标字体或使用其他字体作为替代。

拓展阅读

React + Springboot + Quartz,从0实现Excel报表自动化

电子表格也能做购物车?简单三步就能实现

使用纯前端类Excel表格控件SpreadJS构建企业现金流量表

最新文章

  1. Linux /proc/$pid部分内容详解
  2. 从txt文件中读取数据放在二维数组中
  3. 使用VS2010在Coding.net上进行代码托管
  4. linux IO调度
  5. jQuery EasyUI DataGrid API 中文文档
  6. Unity 利用Coroutine实现跳动数字效果
  7. sass玩转颜色总结笔记
  8. 深入理解:Linear Regression及其正则方法
  9. 第二章 Java 基本语法1
  10. 基于nginx的WebSocket反向代理
  11. 【SQLite】简单的基本使用步骤
  12. 数据结构与算法之PHP查找算法(顺序查找)
  13. HDU 1710Binary Tree Traversals(已知前序中序,求后序的二叉树遍历)
  14. 蓝牙4.0BLE抓包(一) - 搭建EN-Dongle工作环境 使用EN-Dongle抓包 nRF51822
  15. 用vs调试项目的时候报HTTP 错误 403.14 - Forbidden
  16. 已经上架的app在AppStore上搜不到的解决办法
  17. 利用split方法计算字符串中出现字母最多的次数
  18. 解决win10下微信开发者工具点击错位问题
  19. 【反思】一个价值两天的BUG,无论工作还是学习C语言的朋友都看看吧!
  20. 测试Apache服务器及httpd: Could not reliably determine the server&#39;s fully qualified domain name解决办法

热门文章

  1. 02-MyBatisPlus入门
  2. open-falcon安装配置
  3. Elasticsearch:Index生命周期管理入门
  4. Elasticsearch:Elasticsearch SQL介绍及实例(二)
  5. 第二章:视图层 - 9:动态生成CSV文件
  6. CentOS使用yum方式安装yarn和nodejs
  7. 通过开启swap分区来解决小内存阿里云服务器的内存瓶颈
  8. 2&gt;&amp;1到底是什么意思?
  9. 1_MySQL
  10. JavaScript之无题之让人烦躁的模块化