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

内卷时代下的前端技术-使用 JavaScript 在浏览器中生成 PDF 文档

  •  
  •   GrapeCityChina · 2022-09-08 16:32:55 +08:00 · 601 次点击
    这是一个创建于 810 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    在计量领域中,计量检定是一种重要形式,主要用于评定计量器具的计量性能,确定其量值是否准确一致,实现手段包括计量检验、出具检定证书和加封盖印等。 在检定证书这一环节,存在一个难点,就是无法在线预览以及智能生成。

    1 、证书管理不能满足用户精准打印、特殊字符或多页打印的需求。因为在计量行业中,精密仪器较多,往往会存在一些特殊字符的应用或者会使用某些较为复杂的测量单位。 2 、系统不支持批量证书更新以及批量打印等功能,在常见的场景中,出具证书是需要进行批量导出的过程。 3 、无法满足实时打印预览或者 PDF 预览,这样直至打印前都无法确定打印的格式、范围等是否符合需求。 在这篇分享中,我们将帮助大家着重解决两个问题:

    1 、在浏览器中生成 PDF 文件; 2 、解决中文以及特殊字符导出 PDF 乱码的问题。

    在浏览器中生成 PDF 文件。前端生成 PDF 文件纯依赖于客户端的浏览器资源,对于不同的终端,导出 PDF 的难度会比服务端有所增加。市面上主流的浏览器有三四家,例如 Chrome 、Safari 、FireFox 等,每个浏览器对于文字内容、CSS 属性处理都不一致,有可能某些配置在某个浏览器上可行,换了一个浏览器之后就有可能天差地别。另外,对于原生的 PDF 文件来说,仅包含英文字体,不包含任何中文字体,因此当导出的内容中含有中文字体编码时,就会显示乱码,所以通常情况下,我们都需要为 PDF 进行字体注册操作。

    前端常见导出 PDF 方法

    目前常用的前端生成 PDF 文件的方法大致有以下几种。 1 、HTML2Canvas 的方法将 HTML 转换成图片后,在将图转 PDF 文件。这种方法比较适合单一页面。 2 、jsPDF 直接 H5 转成 PDF 。

    除了上述的方案之后,使用 SpreadJS 直接在线设计布局,并且可以直接生成 PDF 文件。 带来的好处是什么呢?可视化的操作、代码量少并且可以适配不同的浏览器环境。当然也会有一定的缺点,对于字体较多的文件,需要注册不同的字体,字体文件越大,占用的带宽就越大。另外,当文件比较大的时候,有可能会存在性能问题,不过这个也几乎是前端导出 PDF 文件的一个瓶颈。那么较为理想的方案便是可以在前端( SpreadJS )设计、展示,最后交由后端来单独导出或者批量导出。

    在浏览器中生成 PDF 文件

    介绍了那么多,我们还是回到本篇文章的主题,如何通过前端来生成 PDF 文件。需要用到 SpreadJS 以及导出 PDF 相关的功能,首先需要在页面上引入相关的资源。

    然后创建一个用于承载表格实例的 DOM 。

    初始化表格控件并加载已设计好的表单,或者也可以通过 setValue 的接口实现简单的赋值操作。

    想要表单按照指定的要求导出,可以通过代码设置打印相关的配置,也可以用设计器来进行设计。下面是配置打印信息相关的代码。

    最后,通过调用 savePDF 方法,将工作簿对象转为 blob ,我们可以通过 window.open 来进行 pdf 的预览或者通过一些保存文件的插件直接将这个 blob 保存为 PDF 文件。

    这是 open 之后的效果,我们可以直接通过浏览器导出 PDF 文件或者是调用浏览器的打印接口实现打印。(demo 在附件名为 PDF 文件夹)

    解决中文以及特殊字符导出 PDF 乱码

    正如前面所说的,在国内,使用中文的报告是一件再常见不过的事,在计量检测等相关场景,特殊字符的使用也较多。在没注册对应的字体之前,导出的中文字体和特殊字体都显示的是乱码。因此,还需要处理导出中文以及特殊字符 PDF 乱码的问题。

    前面提到了注册字体,那我们的字体应该怎么来?要什么格式的字体呢?首先,先确认我们的表单需要用到哪些字体,然后去找对应字体的 ttf 文件(电脑上或者是一些字体网站上都有,需注意版权问题)。找到之后将其转为 base64 格式的文件。具体如何转,可以找一些在线的文件转换器,不过在线的有可能会因为字体文件太大而崩溃,或者有能力的大佬可以自己写一个转换的工具。然后通过下面的方式去把我们的字体文件存储为一个 js 文件放到我们的项目中。

    初始化表单这些就和上面的操作基本一致了,下面就是关键的注册字体步骤了。我们定义了一个 font 对象,里面只定义了常规( normal )的字体,里面的 simkai.ttf 就是我们上面的创建的字体文件。

    还有一点需要注意的是,虽然注册了字体,但是要设置对应的中文字体。或者换过来说,你需要在表单上设置什么字体,就去注册对应的字体。 那我们再来看看特殊字符,注册字体与中文字体的步骤是一致的,特殊在于为了想要在页面上显示特殊字符,我们需要通过 css 的 font-face 来指定一个 font-family 。例如创建了一个叫 sunway-font 的特殊字体,想要在页面上显示。

    最后就是通过 savePDF 方法导出 PDF 文件,可以看到 PDF 的中文和特殊字符都可以正常显示。

    怎么样?学“废”了吗?不妨试试,“卷”起来。

    本文所用代码下载地址: https://gcdn.grapecity.com.cn/forum.php?mod=attachment&aid=MjI5OTEyfDdlNmI2YmExfDE2NjIwMjE0MTd8NjI2NzZ8OTk3MTg%3D

    更多在线 demo 示例代码: https://demo.grapecity.com.cn/spreadjs/gc-sjs-samples/index.html

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