张春成

V2

2022/06/04阅读:47主题:默认主题

PDF的前端实现

PDF的前端实现

本文试图说明 PDF 文件的前端实现过程,以及该过程中可能会最先遇到的大坑。即,PDF 文件应该如何解释和展示。


PDF是什么

PDF可以是很多东西,比如说,它可以随便创造的词

偏微分函数:Partial Differential Function

或者是数学概念

概率密度函数:Probability Density Function

它也可以是文件格式

便携文档格式:Portable Document Format

本文中的PDF专指后一种,即 Adobe 公司创造的一种文档格式

What does PDF mean?

PDF is an abbreviation that stands for Portable Document Format. It's a versatile file format created by Adobe that gives people an easy, reliable way to present and exchange documents - regardless of the software, hardware, or operating systems being used by anyone who views the document.

The PDF format is now an open standard, maintained by the International Organ zation for Standardization (ISO). PDF docs can contain links and buttons, form fields, audio, video, and business logic. They can be signed electronically and can easily be viewed on Windows or MacOS using the free Adobe Acrobat Reader software.

而发明它的 Adobe 公司只声明了它的编码方式,却无法控制大家如何解释它。

[图片]

[图片]

https://resources.infosecinstitute.com/topic/pdf-file-format-basic-structure/

因此,我们总可以将 PDF 文件视为具有固定数据结构的数据体。而拿到这些数据之后,如何对它们进行解释和呈现,就完全是自己的事情了。当然 Adobe 公司提供了免费的 Adobe PDF Reader 来读取这些文件。

但在用浏览器上网时,显然不能要求浏览器集成一个 PDF Reader 在里面。这就要求前端程序自己实现 PDF 文件的解析和呈现。

前端实现PDF呈现的两类方案

由于 PDF 格式是固定的,因此对它进行解析似乎没有什么争议。而目前前端却有两种方法达到 PDF 呈现的目的。一是嵌套方案;二是渲染方案。

嵌套方案

嵌套方案就是使用 HTML 的内置标签,对 PDF 文件进行“包裹”

<!-- Display .pdf using Iframe -->
<iframe src='[pdfUrl]'></iframe>

<!-- Display .pdf using Embed -->
<embed src='[pdfUrl]'></embed>

它的效果有点像这样

[图片]

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#try_it

这样做非常方便,但嵌套的内容有一个极大的隐患,就是它是独立于页面的“国中之国”

Each embedded browsing context has its own session history and document. The browsing context that embeds the others is called the parent browsing context. The topmost browsing context — the one with no parent — is usually the browser window, represented by the Window object.

如果查看网页元素,你就会注意到其中的内容完全无法控制

[图片]

在很多情况下,还会遇到跨域资源的问题,让人异常头痛。

更不要说我们可爱的 APPLE 开发的 Safari 对 Adobe 天生的”敌意“

[图片]

https://github.com/search?o=desc&q=safari+iframe&s=&type=Issues

因此,我觉得嵌套方案是一种十分方便的”替代方案“,可以用于快进快出的临时开发,但不是长久之计。

渲染方案

渲染方案是较为麻烦的方案,它是在解析 PDF 文件的基础上,将它渲染成 canvas ,而 canvas 是 HTML 的标准标签。换成方便理解的说法, canvas 就相当于一张画布,前端程序根据文件内容将 PDF 页面“画”在 canvas 上。

我们将 canvas 渲染这一步当作是一层缓冲,

  1. 后台程序将 PDF 字节流传递给它;
  2. 它加工成 canvas 画布(渲染);
  3. 将 canvas 画布传递给 HTML 页面进行显示。

也就是说, HTML 页面并不知道(也无须知道)它给的 canvas 画布是由 PDF 文件得来的。因此也就无须采用专门的方式来处理它,只当它是普通的 canvas 画布就可以了。各个厂商、各种规范之间的摩擦自然地就在此终止。 这样,问题的关键就是充当缓冲器的渲染程序了。干这种事的好像也只能是开源社区,比如 Mozilla 的 PDF.js

[图片]

https://mozilla.github.io/pdf.js/

分类:

后端

标签:

后端

作者介绍

张春成
V2