当前位置:首页 » 《随便一记》 » 正文

vue+pdf.js预览本地pdf文件(可以复制文本,滚动页码展示)

13 人参与  2024年02月10日 08:01  分类 : 《随便一记》  评论

点击全文阅读


1、安装pdfjs-dist插件,推荐使用2.0.943这个版本

npm install pdfjs-dist@2.0.943

2、页面中引入使用

import PDFJS from 'pdfjs-dist'// 文本视图,可复制import { TextLayerBuilder } from 'pdfjs-dist/web/pdf_viewer'import 'pdfjs-dist/web/pdf_viewer.css'PDFJS.workerSrc = require('pdfjs-dist/build/pdf.worker.min')

3、页面标签

<div class="pdfContainer">  <div class="pdfOprate">    <!-- 当前页码/页码总数 -->    <span class="pdfCount">       <span class="pdfPage">{{pdfPage}}</span> / <span class="pdfPageTotal">{{pdfTotalPages}}</span>    </span>  </div>  <!-- pdf视图 -->  <div class="pdfBody" @scroll="pdfScroll($event)">    <div id="pdfBox">      <!-- pdf内容,图片和文本视图 -->      <!-- <div class="divBox">        <canvas ></canvas>        <div class="textLayer"></div>      </div> -->    </div>  </div></div>

3、解析pdf,获取pdf所有页数据,使用canvas渲染,并使用TextLayerBuilder创建文本层,可以复制文本信息

// 使用pdf.js加载和显示PDF文件previewPdf(file){    var that=this    const fileReader = new FileReader();    fileReader.onload = function() {        const typedArray = new Uint8Array(this.result);        // 调用pdf.js的API加载PDF文件        PDFJS.getDocument(typedArray).promise.then(async function(pdf) {            that.viewPdfObject=pdf            // 获取PDF的总页数            const numPages = pdf.numPages;            // 渲染当前显示页码和总页数            this.pdfPage=1            this.pdfTotalPages=numPages            const pdfBox = document.getElementById("pdfBox");            // 循环绘制每个页面            for (let pageNum = 1; pageNum <= numPages; pageNum++) {              // 获取指定页数据              let page = await pdf.getPage(pageNum)              // 获取视图 1是倍率,按照pdf解析出来的原始宽高              const viewport = page.getViewport(1)                            const divBox=document.createElement("div")              divBox.className="divBox"              pdfBox.appendChild(divBox)              const canvasElement=document.createElement("canvas")              const context = canvasElement.getContext("2d");              canvasElement.width = viewport.width;              canvasElement.height = viewport.height;              divBox.appendChild(canvasElement)              // 渲染指定页的内容到canvas上              // 如果你只是展示pdf而不需要复制pdf内容功能,则可以这样写render              // page.render({canvasContext: context,viewport})              // 需要复制内容就使用下面的渲染方式              var textContent=await page.render({                canvasContext: context,                viewport              }).then(() => {                return page.getTextContent();              })              // 创建文本图层div              const textLayerDiv = document.createElement('div')              textLayerDiv.className="textLayer"              textLayerDiv.setAttribute('class', 'textLayer')              textLayerDiv.setAttribute('style', 'margin:auto;'+'width:'+viewport.width+'px;'+'height:'+viewport.height+'px')              // 将文本图层div添加至每页pdf的div中              divBox.appendChild(textLayerDiv)              // 创建新的TextLayerBuilder实例              let textLayer = new TextLayerBuilder({                textLayerDiv: textLayerDiv,                pageIndex: page.pageIndex,                viewport: viewport              })              textLayer.setTextContent(textContent)              textLayer.render()            }        })    }    fileReader.readAsArrayBuffer(file);},

在渲染pdf数据时,当pdf文件很大渲染量很多时,会导致页面卡住,无法执行其他操作;这涉及到队列优先级问题:
在这里插入图片描述
在这里就是因为微任务导致,所以我们这里渲染pdf任务可以每次渲染完一页后等待一定时间才执行下一页的渲染,空出时间给主线程

// 将渲染pdf的代码休眠一定时间,留给主线程sleep(time){  return new Promise((resolve) => {    setTimeout(() => {      resolve(time)    }, time)  })},// 创建一个延时队列的任务 主进程会执行渲染队列任务后在执行延时队列任务等待延时,后再创建渲染pdf下一页的微任务(在循环代码的最后使用)await that.sleep(100)

在滚动时当前是第几页的页码同步更新展示:需要在渲染每页pdf时将每页的高度存起来,以及每页滚动的临界值

// 每页累加的高度this.scrollHeight=[0]// 每页滚动切换值的临界滚动距离this.scrollHalfHeight=[0]this.heightAll=0$(".pdfBody canvas").each(function (i) {// 滚动到前一页高度的70%,即页码自动更改为下一页    that.heightAll+=this.height*that.zoom*0.7    that.scrollHalfHeight.push(that.heightAll)    that.heightAll+=this.height*that.zoom*0.3    that.scrollHeight.push(that.heightAll)})

在滚动时,根据当前滚动距离和每页滚动的临界距离相比较,判断当前是第几页

pdfScroll(e){  var pdfBody=document.querySelector(".pdfBody")  for (let i=0;i<this.scrollHeight.length;i++){    // 在滚动时,根据当前滚动距离和每页滚动的临界距离相比较,判断当前是第几页    if(pdfBody.scrollTop>=this.scrollHeight[i]&&pdfBody.scrollTop<this.scrollHeight[i+1]){      if (this.pdfPage!=i+1){        this.pdfPage=i+1      }    }  }}

效果如下
在这里插入图片描述


点击全文阅读


本文链接:http://zhangshiyu.com/post/67982.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 李成功金嘉兰(产子第二天,月嫂哄我儿子喊她妈)最新章节免费在线阅读_李成功金嘉兰(产子第二天,月嫂哄我儿子喊她妈)全章节在线阅读(笔趣阁)
  • 热推《程辰许清何泽》程辰许清何泽~小说全文阅读~完本【已完结】笔趣阁
  • 被全家害死在哀牢山后,我杀疯了尤向兰赵小燕最新好看小说推荐_最新全本小说被全家害死在哀牢山后,我杀疯了_(尤向兰赵小燕)免费小说在线阅读
  • 免费小说《尤向兰赵小燕》已完结(尤向兰赵小燕)热门小说大结局全文阅读笔趣阁
  • 被全家害死在哀牢山后,我杀疯了尤向兰赵小燕完结版小说全文免费阅读_免费完本小说被全家害死在哀牢山后,我杀疯了(尤向兰赵小燕)完本热门小说
  • 《被负心渣男欺骗后,灵魂互换的我彻底杀疯了》(郑江明明)在哪看免费小说_完整版免费全文阅读《被负心渣男欺骗后,灵魂互换的我彻底杀疯了》郑江明明 -
  • 《我服婚役后,帝君他四海八荒抢新娘!》(金乌昊天泽)免费小说免费阅读_免费完整版小说《我服婚役后,帝君他四海八荒抢新娘!》(金乌昊天泽) -
  • 零基础Java第十九期:认识String(一)
  • C++ —— 以真我之名 如飞花般绚丽 - 智能指针
  • JavaScript 读取及写入本地文件
  • 关于我、重生到500年前凭借C语言改变世界科技vlog.21——动态内存管理
  • 前端流式播放TTS语音:技术细节与实现

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1