关于 PDF.js

免费开源的 JavaScript 读取、显示 PDF 文档的工具库_相对路径

pdf.js 是一款 Mozilla 开发的、用于网页上显示 pdf 文档的 Javascript 库, 提供 pdf 文件的在线阅读。

pdf.js 在支持 js 的服务器上就能运行, 所以各种网站上的 Pages 服务均支持, 无须 php、java 等动态语言环境的支持。

pdf.js是一个免费的开源软件。除了提取文章和转成图片,PDF.js 还很多强大的功能,比如可以实现页面导航,预览时加入缩放、滚动、旋转和手写等注释以及实现打印、另存为等操作。

支持谷歌、火狐浏览器,支持pc手机端浏览器。

Git地址:GitHub - mozilla/pdf.js: PDF Reader in JavaScript

官网地址:PDF.js

下载地址:Getting Started

文件布局概述

请注意,我们只提到最相关的文件和文件夹。

├── build/
│   ├── pdf.js                             - display layer
│   ├── pdf.js.map                         - display layer's source map
│   ├── pdf.worker.js                      - core layer
│   └── pdf.worker.js.map                  - core layer's source map
├── web/
│   ├── cmaps/                             - character maps (required by core)
│   ├── compressed.tracemonkey-pldi-09.pdf - PDF file for testing purposes
│   ├── debugger.js                        - helpful debugging features
│   ├── images/                            - images for the viewer and annotation icons
│   ├── locale/                            - translation files
│   ├── viewer.css                         - viewer style sheet
│   ├── viewer.html                        - viewer layout
│   ├── viewer.js                          - viewer layer
│   └── viewer.js.map                      - viewer layer's source map
└── LICENSE

├── docs/                                  - website source code
├── examples/                              - simple usage examples
├── extensions/                            - browser extension source code
├── external/                              - third party code
├── l10n/                                  - translation files
├── src/
│   ├── core/                              - core layer
│   ├── display/                           - display layer
│   ├── shared/                            - shared code between the core and display layers
│   ├── interfaces.js                      - interface definitions for the core/display layers
│   └── pdf.*.js                           - wrapper files for bundling
├── test/                                  - unit, font, reference, and integration tests
├── web/                                   - viewer layer
├── LICENSE
├── README.md
├── gulpfile.js                            - build scripts/logic
├── package-lock.json                      - pinned dependency versions
└── package.json                           - package definition and dependencies

使用Demo案例

有两种显示 pdf 文件的方式, 一种是传入 pdf 文件的路径参数, 可以为 URL, 但是采用这种方式会在网址栏看到 pdf 的 URL 地址。另外一种方法是直接修改默认文件。

1. 传入参数(不推荐)

在地址栏后面传 ?file=test.pdf 即可完成对默认路径的修改:

http://localhost:8080/pdfjs/web/viewer.html?file=test.pdf //这种最好不要传输中文, 具体我没用试过

这里的 test.pdf 取与 viewer.html 的相对路径即可(整个服务器的绝对路径也行, 跨域的 URL 也可)。

2.修改默认文件

<!DOCTYPE html>
<html>
<head>
<!-- 以下方式定时转到其他页面 -->
<meta http-equiv="refresh" content="0;url=web/viewer.html">
</head>
</html>

修改文件 web/viewer.js 里面的 DEFAULT_URL 的值, 可以是相对路径, 也可以是跨域的 URL(当然这个由于安全原因默认没打开, 想要打开看下面的问题):

var DEFAULT_URL = 'https://xxx.pdf'

完整示例:

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../build/pdf.js"></script>
    <style>
        html,
        body {
            padding: 0px;
            margin: 0px;
            overflow-x: hidden;
        }
    </style>
</head>
 
<body>
    <div id="container"></div>
 
    <script>
        var container, pageDiv, pdfDoc;
        var winWidth = window.innerWidth;
        function getPDF(url) {
            pdfjsLib.getDocument(url).promise.then((pdf) => {
                pdfDoc = pdf;
                container = document.getElementById('container');
                for (var i = 1; i <= pdf.numPages; i++) {
                    renderPDF(i);
                }
            })
        }
        function renderPDF(num) {
            pdfDoc.getPage(num).then((page) => {
                var scale = winWidth / (page.getViewport({ scale: 1 }).width);
 
                var viewport = page.getViewport({ scale: scale });
                console.info(viewport);
                pageDiv = document.createElement('div');
                pageDiv.setAttribute('id', 'page-' + (page.pageIndex + 1));
                pageDiv.setAttribute('style', 'position: relative');
                container.appendChild(pageDiv);
                var canvas = document.createElement('canvas');
                pageDiv.appendChild(canvas);
                var context = canvas.getContext('2d');
                canvas.height = viewport.height;
                canvas.width = viewport.width;
 
                var renderContext = {
                    canvasContext: context,
                    viewport: viewport
                };
 
                page.render(renderContext);
            });
        }
 
        getPDF('compressed.tracemonkey-pldi-09.pdf');
    </script>
</body>
 
</html>

 在线使用案例

在线阅读器预览:

https://mozilla.github.io/pdf.js/web/viewer.html

使用方案:file=(指定自己的pdf文件地址即可)

下载源码后viewer.html文件就是在线阅读器。

https://mozilla.github.io/pdf.js/web/viewer.html?file=指定自己的pdf地址

Vue项目示例

npm 安装

npm i pdfjs-dist -S

在 Vue 页面中引入 PDF.js,注意这里的引入方式,需要在包名后加上 /webpack ,否则会报错。

<template>
<div class="hello">
    <input
      type="file"
      name="file"
      id="file"
      accept="application/pdf"
      single
      placeholder="请选择pdf文件"
      @change="handleFile"
    />
    <canvas id="viewer" ref="viewer" :width="width" :height="height"></canvas>
  </div>
</template>
<script>
import { getDocument } from "pdfjs-dist/webpack"; // 注意这里的引入方式

// 省略无关代码...
// methods:
    handleFile(e) {
      const reader = new FileReader();
      reader.onload = (evt) => {
        this.init(evt.target.result);
      };

      reader.readAsDataURL(e.target.files[0]);
    },
    async init(path) {
      // 读取pdf
      let pdf = await getDocument(path).promise; //返回一个pdf对象
      const page = await pdf.getPage(0); // 获取第一页
      const viewport = page.getViewport({ scale: 1 });
      const textContent = await page.getTextContent();
      console.log(textContent.items); // 页面的文章内容在这

      const context = this.canvas.getContext("2d");
      // 设置canvas的尺寸
      this.width = viewport.width;
      this.height = viewport.height;
      await page.render({ canvasContext: context, viewport: viewport }).promise; // 渲染第一页内容
    },

</script>

可以实现读取 PDF 文档中的页面和文字,代码的末尾把第一页渲染到了 canvas 中,想要转成图片,只要把 canvas 中的内容转成 PNG 图片即可

免费开源说明

Mozilla 组织本身是一个非营利性组织,成立以来一直致力于推动浏览器的良好发展,PDF.js 也不例外,是一个免费开源的项目,源码基于 Apache 2.0 许可托管在 Github 上,任何人都可以免费下载来使用,用在商业项目也完全没问题。