pdf.js 笔记

1.介绍

  • 官方文档,pdf.js是由mozilla开源的js库,用于在web环境中渲染和显示pdf文档
  • 目前,绝大多数PC浏览器都已经内置了pdf阅读器,能够直接预览pdf文件(内置了pdf.js),手机浏览器经测试,多数不能直接预览,要么会弹出下载框,要么调用本地已安装的阅读器进行预览
  • 为了能够兼容更多的设备,可以在项目中集成pdf.js来预览pdf,从而摆脱浏览器版本的限制

2.优点

  • 开源,自带预览UI,使用方便
  • 性能好,支持文档分段加载,能秒开大文件
  • 兼容性强,支持手机浏览器,IE等其他旧浏览器
  • 扩展性好,可基于它做各种定制功能

3.基本使用

  • pdf.js库有两个文件夹(web和build),自带的web/viewer.html文件是自带UI的pdf预览页面,访问页面时传入参数即可
http://127.0.0.1:8096/pdfjs-4.4.168-dist/web/viewer.html?file=http://127.0.0.1:8096/pdf/a.pdf
  • 原理:本质上是通过fecth()获取pdf文档,再转换成canvas进行渲染

  • 默认情况下,不能处理跨域的pdf文档,需要做两个处理:第一,改源码,不做同源判断,第二,处理ajax跨域的问题

4.核心浅析

  • 读取pdf文档,并获取其页码数量
  • 根据页码,获取页码对应的文档信息,并渲染到canvas容器中,可做到局部渲染
<script type="module">
    //引入 pdfjsLib
    var { pdfjsLib } = globalThis
    //设定pdf.worker.mjs地址
    pdfjsLib.GlobalWorkerOptions.workerSrc = './libs/pdfjs-4.4.168-dist/build/pdf.worker.mjs'

    //解析渲染pdf的方法
    async function renderPdf(){
        //文档地址
        var url = 'http://127.0.0.1:8096/_public/pdf/a.pdf'
        try {
            //读取文档
            const pdf = await pdfjsLib.getDocument('./_public/pdf/a.pdf').promise
            //页码数量
            console.log('页码数量',pdf.numPages)
            //获取页码对应的内容
            const page = await pdf.getPage(1)
            //当前页码的视口信息(宽高)
            var viewport = page.getViewport({ scale: 1 })
            //获取canvas
            var canvas = document.getElementById('the-canvas')
            var context = canvas.getContext('2d')
            //根据视口信息设定canvas的宽高
            canvas.width = viewport.width
            canvas.height = viewport.height 
            //将内容渲染到canvas
            page.render({
                canvasContext: context,
                viewport
            })
        } catch (error) {
            console.log(error)
        }
    }
</script>
  • 还可以将canvas转换成图片进行输出渲染,这里搭配element-ui进行示范
<body>
    <div id="app">
        <el-image v-for="(item,index) in img_list" :key="index" style="width: 200px; height: 200px" :src="item"  :preview-src-list="img_list" :initial-index="index"></el-image>
    </div>
</body>
<script type="module">
    var { pdfjsLib } = globalThis
    pdfjsLib.GlobalWorkerOptions.workerSrc = './libs/pdfjs-4.4.168-dist/build/pdf.worker.mjs'


    //转换成图片
    async function pdftoImages(url = ""){
        if(!url){
            return
        }
        try {
            //读取文档
            const pdf = await pdfjsLib.getDocument('./_public/pdf/a.pdf').promise
            //页码数量
            console.log('页码数量',pdf.numPages)
            //所有图片的集合
            const arr = []
            //转换所有页码
            for(var i=1;i<=pdf.numPages;i++){
                //获取页码对应的内容
                const page = await pdf.getPage(i)
                //当前页码的视口信息(宽高)
                var viewport = page.getViewport({ scale: 1 })
                //获取canvas
                var canvas = document.createElement('canvas')
                var context = canvas.getContext('2d')
                //根据视口信息设定canvas的宽高
                canvas.width = viewport.width
                canvas.height = viewport.height 
                //将内容渲染到canvas(同步)
                await page.render({
                    canvasContext: context,
                    viewport
                }).promise
                //转换成图片
                arr.push(canvas.toDataURL("image/png"))
            }
            //返回图片合集(base64)
            return arr
            
        } catch (error) {
            console.log(error)
        }
    }

    new Vue({
        el:"#app",
        data: {
            img_list: []
        },
        mounted(){
            this.getImages()
            
        },
        methods: {
           async getImages(){
                // 转换成图片并保存
                this.img_list = await pdftoImages("http://127.0.0.1:8096/_public/pdf/a.pdf")
           }
        }
    })
</script>
posted @ 2022-08-11 10:19  ---空白---  阅读(656)  评论(0编辑  收藏  举报