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

Chrome 103


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生成工具中

应用blob 办法能够获取字体文件内容

  let currentFont = fontList[fontListSelect.value];  const blob = await currentFont.blob();

应用字体名称注册

//将Blob 对象转换成 ArrayBuffervar 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可能还会乱吗,这时还须要从服务器下载字体或者用其余字体文件代替。