目前是直接使用npm install pdfjs-dist方式(目录如下图),

其中以下两个文件必须引入:

import pdfJS from 'pdfjs-dist';
import 'pdfjs-dist/build/pdf.worker';

这两个文件包含了获取、解析和展示PDF文档的方法,但是解析和渲染PDF需要较长的时间,可能会阻塞其他JS代码的运行。

为解决这个问题,pdf.js使用了Web Workers

考虑到用户可能不会使用该文件预览功能,咱们可以使用按需加载的方式:

components: {
    pdfViewer: r => require.ensure([], () => r(require('./pdfViewer')), '../pdfViewer')
}

其中pdfViewer就是咱们实现的pdf预览组件。

<canvas id="pdf-canvas"></canvas>

js代码

var url = 'test.pdf';

let loadingTask = pdfJS.getDocument(path); // 返回的是一个promise
loadingTask.promise.then(pdf => {
    return pdf.getPage(1); 
}).then(page => {
    // 设置展示比例
    var scale = 1.5;
    // 获取pdf尺寸
    var viewport = page.getViewport(scale);
    // 获取需要渲染的元素
    var canvas = document.getElementById('pdf-canvas');
    var context = canvas.getContext('2d');
    // 设置canvas宽高
    canvas.height = viewport.height;
    canvas.width = viewport.width;
    
    var renderContext = {
        canvasContext: context,
        viewport: viewport
    };
    
    page.render(renderContext);
});

但如果要实现PDF文档中文本可被选中及复制功能则还需要引入:

import { TextLayerBuilder } from 'pdfjs-dist/web/pdf_viewer';
import 'pdfjs-dist/web/pdf_viewer.css';

具体代码如下(实现了文本复制的功能) 

<div id="pdfViewer"></div>

主要JS 

let path = 'https://cdn.chime.me/doc/fs/upload/2019122/22/c215b689-a3d6-4d6d-9e6b-2219fdc85552/test.pdf';
let container = document.getElementById('pdfViewer');
            pdfJS.getDocument(path).then((pdf) => {
                for (let i = 1; i <= pdf.numPages; i++) {
                   pdf.getPage(i).then((page) => {
                        let viewport = page.getViewport({scale: 1});
                        let pageDiv = document.createElement('div');
                        pageDiv.setAttribute('id', 'page-' + (page.pageIndex + 1));
                        container.appendChild(pageDiv);
                        let canvas = document.createElement('canvas');
                        pageDiv.appendChild(canvas);
                        let context = canvas.getContext('2d');
                        canvas.height = viewport.height;
                        canvas.width = viewport.width;
                        
                        let renderContext = {
                            canvasContext: context,
                            viewport: viewport
                        };
                        
                        page.render(renderContext).then(function () {
                            return page.getTextContent();
                        }).then((textContent) => {
                            // 创建文本图层div
                            const textLayerDiv = document.createElement('div');
                            textLayerDiv.setAttribute('class', 'textLayer');
                            // 将文本图层div添加至每页pdf的div中
                            document.getElementById(`page-${i}`).append(textLayerDiv);
                                            
                            // 创建新的TextLayerBuilder实例
                            let textLayer = new TextLayerBuilder({
                                textLayerDiv: textLayerDiv,
                                pageIndex: page.pageIndex,
                                viewport: viewport
                            });
                                            
                            textLayer.setTextContent(textContent);
                            textLayer.render();
                        });
                    }, (err) => {
                        console.log(err, '-------err---------');
                    });
                }
            }, (reason) => {
                console.error(reason);
            });

css 

#pdfViewer > div {
        position: relative;
        margin: 0 auto;
    }

我们可以看下DOM结果:

完整代码请看https://github.com/zxl925768661/fileViewer 

参考资料: PDF.js实现个性化PDF渲染(文本复制)

https://github.com/mozilla/pdfjs-dist

Logo

前往低代码交流专区

更多推荐