pdf在线预览解决方案——pdf.js使用

Posted 大唐荣华

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pdf在线预览解决方案——pdf.js使用相关的知识,希望对你有一定的参考价值。

业务背景

在C端的前端项目中,针对用户会有多种规则需要展示,之前的处理方案是将这些规则写成一个个的静态页面,用户来访问这些页面。但如果这些规则需要变更的话,就需要前端修改对应的规则页面的文案,重新发版。为了避免这种因为规则文案修改而频繁发版的情况,现改用pdf方式来渲染,只需要在后台上传、配置需要展示的pdf规则文件,前端通过动态获取文件url在线预览pdf规则。

实现方式

针对pdf的渲染,为了更好的兼容ie浏览器和m端,采用了PDF.js库。
PDF.js 由 Mozilla 提供支持。目标是创建一个通用的、基于 Web 标准的平台,用于解析和呈现pdf。前端动态获取url后,通过PDF.js渲染出文件。官网下载链接:http://mozilla.github.io/pdf.js/

pdf.js 的使用

资源引入

**html文件:**

<!DOCTYPE html>
<html lang="en">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="default">
    <meta name="keywords" content="">
    <title>pdf预览</title>
</head>

<body>
    <div id="app"></div>
</body>
<script src="//j1.58cdn.com.cn/escstatic/youxinpai/js/pdf/pdf.min.js"></script>
<script src="//j1.58cdn.com.cn/escstatic/youxinpai/js/pdf/axios.min.js"></script>

</html>

预览实现

**js文件:**

import React,  useEffect  from 'react';

pdfjsLib.GlobalWorkerOptions.workerSrc = "//j1.58cdn.com.cn/escstatic/youxinpai/js/pdf/pdf.worker.js"

const PdfViewer = (props) => 
    const devicePixelRatio = window.devicePixelRatio, clientWidth = document.body.clientWidth;
    let scale = 1;
    let PDFDocument;
    let pageTotalNum = 0, //总页面数
        firstRenderNum = 4, //初次渲染页面数
        renderedNum = 0; //已经渲染的页面数
    let canvasWidth, canvasHeight;

    useEffect(() => 
        let loadingTask = pdfjsLib.getDocument( url: props.fileUrl );
        loadingTask.promise.then(function (pdf) 
            PDFDocument = pdf;
            pageTotalNum = pdf.numPages;
            // 一进入页面,默认渲染最多4页
            for (let i = 1; (i <= firstRenderNum && i <= pdf.numPages); i++) 
                renderPDF(i)
            
        )
    , []);

    const renderPDF = (pageNum) => 
        if (pageNum > pageTotalNum || pageNum <= renderedNum) return;

        PDFDocument.getPage(pageNum).then(function (page) 
            if (pageNum === 1)  //初次渲染时,将分辨率以及渲染区块大小等数据保存
                let originViewport = page.getViewport( scale: scale );
                scale = clientWidth / originViewport.width;
            
            let viewport = page.getViewport( scale: scale * devicePixelRatio );

            if (pageNum === 1) 
                canvasWidth = viewport.width;
                canvasHeight = viewport.height;

                // 监听页面滚动 提前渲染后面两页的pdf
                window.onscroll = (e) => 
                    let currentIndex = Math.floor(window.pageYOffset / (canvasHeight / devicePixelRatio)) + 1; //当前位置
                    if (currentIndex === renderedNum) 
                        renderPDF(currentIndex + 1);
                    
                
            
            renderedNum = pageNum;
            let canvas = document.createElement('canvas');
            canvas.id = `canvas$pageNum`;
            canvas.width = canvasWidth;
            canvas.height = canvasHeight;
            canvas.style.width = canvasWidth / devicePixelRatio + 'px';
            canvas.style.height = canvasHeight / devicePixelRatio + 'px';
            document.querySelector('#app').appendChild(canvas);
            page.render(
                canvasContext: canvas.getContext('2d'),
                viewport: viewport
            )
        );
    


export default PdfViewer;

以上是关于pdf在线预览解决方案——pdf.js使用的主要内容,如果未能解决你的问题,请参考以下文章

java实现word转pdf在线预览(前端使用PDF.js;后端使用openofficeaspose)

vue-pdf.js 在线预览问题

pdf.js实现图片在线预览

文档在线预览使用js前端实现wordexcelpdfppt 在线预览

WEB在线预览PDF,WORD方案总结

WEB在线预览PDF,WORD方案总结