推荐阅读
准备工作
- 创建 react 项目:
create-react-app
- 在项目中添加 pdf.js 依赖
npm install pdfjs-dist || yarn add pdfjs-dist
使用 pdfjs-dist
关键的两个文件
- pdf.js
- pdf.worker.js
如何使用
import pdfjs from 'pdfjs-dist';
import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry';
pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;
这两个文件包含了获取、解析和展示PDF文档的方法,但是解析和渲染PDF需要较长的时间,可能会阻塞其它JS代码的运行。
为解决该问题,pdf.js依赖了HTML5引入的Web Workers——通过从主线程中移除大量CPU操作(如解析和渲染)来提升性能。
PDF.js的API都会返回一个Promise,使得我们可以优雅的处理异步操作。但是文档甚少,只能查找源码,浏览 github
++题外话:在看别人写的pdf渲染的项目使用 pdfjs-dist 的时候 这么写的++
pdfjs.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.js');
通过 required 引入 pdf.worker 但是使用 create-react-app 创建的 react 项目在使用的时候不能够直接使用 required,如果这么使用会报这个错
[图片上传失败...(https://pic2.zhimg.com/80/v2-75bac6b27ae24f93cfc519c24f2c8e9f_1440w.jpg)]
查看源码就能够定位到问题原因:他的接受的必须是字符串
# 位置 pdf.js/src/display/worker_options.js Lines 27 to 34 in 4fe9260
/**
* A string containing the path and filename of the worker file.
*
* NOTE: The `workerSrc` option should always be set, in order to prevent any
* issues when using the PDF.js library.
* @var {string}
*/
GlobalWorkerOptions.workerSrc =
同样的可以使用 CND 的方式解决这个问题
pdfjs.GlobalWorkerOptions.workerSrc = "https://cdn.bootcss.com/pdf.js/2.2.228/pdf.worker.js";
渲染
- 创建 canvas 以便于渲染pdf
const canvasRef = useRef(null)
<canvas
ref={canvasRef}
width={window.innerWidth}
height={window.innerHeight}
/>
- 添加渲染PDF的 js 代码
# 读取 PDF 文件
const loadingTask = pdfjs.getDocument(url);
# 获得到 PDF 对象
const pdf = await loadingTask.promise;
const firstPageNumber = 1;
# 读取到页面信息
const page = await pdf.getPage(firstPageNumber);
# 设置页面缩放
const scale = 1;
const viewport = page.getViewport({scale: scale});
# 以下写法清晰度更高
# const devicePixelRatio = window.devicePixelRatio;
# const viewport = page.getViewport({scale: scale * devicePixelRatio});
// Prepare canvas using PDF page dimensions
const canvas = canvasRef.current;
const context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
// Render PDF page into canvas context
const renderContext = {
canvasContext: context,
viewport: viewport
};
const renderTask = page.render(renderContext);
这样PDF就渲染到刚才我们写的canvas中,但是这段代码只能渲染第一页,通过改变 firstPageNumber 渲染不同的页面。
getDocument():用于异步获取PDf文档,发送多个Ajax请求以块的形式下载文档。它返回一个Promise,该Promise的成功回调传递一个对象,该对象包含PDF文档的信息,该回调中的代码将在完成PDf文档获取时执行。
getPage():用于获取PDF文档中的各个页面。
getViewport():针对提供的展示比例,返回PDf文档的页面尺寸。
render():渲染PDF。
这也写只能满足简单的翻页需求,如果增加别的需求,放大缩小,文本复制,就不能改满足。我们下节来编写如何能够==文本复制==。
网友评论