V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
GrapeCityChina
V2EX  ›  推广

Chrome 103 支持使用本地字体,纯前端导出 PDF 优化

  •  
  •   GrapeCityChina · 2022-11-24 17:10:49 +08:00 · 621 次点击
    这是一个创建于 763 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5333 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 07:25 · PVG 15:25 · LAX 23:25 · JFK 02:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.