在前端导出 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 构建企业现金流量表