vue使用pdfjs显示PDF可复制的实现方法


Posted in Javascript onDecember 14, 2018

pdf显示的方法

方法一

使用embed标记来使用浏览器自带的pdf工具。

这种实现方式优缺点都很明显:

优点:自带“打印”,“搜索”,“翻页”等功能,强大且实现方便。

缺点:不同浏览器的pdf工具样式不一,且无法满足个性化需求,比如:禁止打印,下载等。

方法二

使用Mozilla的PDF.js,自定义展示PDF。

  • 基础功能集成
  • 使用Text-Layers渲染(可实现pdf内容复制)

什么是PDF.JS

PDF.js是基于HTML5技术构建的,用于展示可移植文档格式的文件(PDF),它可以在现代浏览器中使用且无需安装任何第三方插件。

安装:

npm install pdfjs-dist

基础功能有两个必须引用的文件:

  • pdf.js
  • pdf.worker.js

如果使用CDN的方式,直接引用如下对应文件即可:

  • https://mozilla.github.io/pdf.js/build/pdf.js
  • https://mozilla.github.io/pdf.js/build/pdf.worker.js

如果使用npm的方式,则在需要使用PDF.js的文件中如下引用:

import PDFJS from 'pdfjs-dist';

PDFJS.GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker.js';

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

为解决该问题,pdf.js依赖了HTML5引入的Web Workers——通过从主线程中移除大量CPU操作(如解析和渲染)来提升性能。

PDF.js的API都会返回一个Promise,使得我们可以优雅的处理异步操作。

使用

本文章只介绍在vue中的使用, 下面是自己写的展示pdf的组件可以直接拿去用

注:具体解释请看下面代码中的注释

<template>
  <!--<button @click="scalBig">放大</button>-->
  <!--<button @click="scalSmall">缩小</button>-->
  <!--<p>页码:{{`${pageNo}/${totals.length}`}}</p>-->
  <div class="drag-box" id="dragBox" @scroll="scrollfun($event)">
   <el-scrollbar style="height: 100%;overflow-y: hidden;">
   <div class="wrapper" id="pdf-container">
    <div v-for="item in totals" :id="`page-${item}`" :key="item" class="pdf-box">
     <canvas :id="'canvas-pdf-' + item" class="canvas-pdf"></canvas>
    </div>
   </div>
   </el-scrollbar>
  </div>
</template>

<script>
import PDFJS from 'pdfjs-dist'
import { TextLayerBuilder } from 'pdfjs-dist/web/pdf_viewer'
import 'pdfjs-dist/web/pdf_viewer.css'
export default {
 name: 'showPdf',
 props: ['pdfUrl'],
 data () {
  return {
   scale: 1.4,
   totals: [],
   pageNo: 1,
   viewHeight: 0
  }
 },
 mounted () {
  this.renderPdf(this.scale)
 },
 watch: {
  scale (val) {
   this.totals = []
   this.renderPdf(val)
  }
 },
 methods: {
  renderPdf (scale) {
   PDFJS.workerSrc = require('pdfjs-dist/build/pdf.worker.min')
   // 当 PDF 地址为跨域时,pdf 应该已流的形式传输,否则会出现pdf损坏无法展示
   PDFJS.getDocument(this.pdfUrl).then(pdf => {
    // 得到PDF的总的页数
    let totalPage = pdf.numPages
    let idName = 'canvas-pdf-'
    // 根据总的页数创建相同数量的canvas
    this.createCanvas(totalPage, idName)
    for (let i = 1; i <= totalPage; i++) {
     pdf.getPage(i).then((page) => {
      let pageDiv = document.getElementById(`page-${i}`)
      let viewport = page.getViewport(scale)
      let canvas = document.getElementById(idName + i)
      let context = canvas.getContext('2d')
      canvas.height = viewport.height
      canvas.width = viewport.width
      this.viewHeight = viewport.height
      let renderContext = {
       canvasContext: context,
       viewport
      }
      // 如果你只是展示pdf而不需要复制pdf内容功能,则可以这样写render
      // page.render(renderContext) 如果你需要复制则像下面那样写利用text-layer
      page.render(renderContext).then(() => {
       return page.getTextContent()
      }).then((textContent) => {
       // 创建文本图层div
       const textLayerDiv = document.createElement('div')
       textLayerDiv.setAttribute('class', 'textLayer')
       // 将文本图层div添加至每页pdf的div中
       pageDiv.appendChild(textLayerDiv)
       // 创建新的TextLayerBuilder实例
       let textLayer = new TextLayerBuilder({
        textLayerDiv: textLayerDiv,
        pageIndex: page.pageIndex,
        viewport: viewport
       })
       textLayer.setTextContent(textContent)
       textLayer.render()
      })
     })
    }
   })
  },
  createCanvas (totalPages) {
   for (let i = 1; i <= totalPages; i++) {
    this.totals.push(i)
   }
  },
  // 分页
  scrollfun (e) {
   let scrollTop = e.target.scrollTop
   if (scrollTop === 0) {
    this.pageNo = 1
   } else {
    this.pageNo = Math.ceil(scrollTop / this.viewHeight)
   }
  },
  // 放大
  scalBig () {
   this.scale = this.scale + 0.1
  },
  // 缩小
  scalSmall () {
   if (this.scale > 1.2) {
    this.scale = this.scale - 0.1
   }
  }
 }
}
</script>

<style scoped lang="scss">
 .drag-box {
  height: 800px;
 }
 .pdf-box {
  position: relative;
 }
 .el-scrollbar__wrap {
  overflow-x: hidden;
 }
</style>

pdf.js实现展示和复制PDF内容介绍到这里,后续会继续更新实现下载、打印等功能

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
最短的IE判断代码
Mar 13 Javascript
jQuery异步上传文件插件ajaxFileUpload详细介绍
May 19 Javascript
js获取新浪天气接口的实现代码
Jun 06 Javascript
a标签置灰不可点击的实现方法
Feb 06 Javascript
手机注册发送验证码倒计时的简单实例
Nov 15 Javascript
vue动态删除从数据库倒入列表的某一条方法
Sep 29 Javascript
Vue使用.sync 实现父子组件的双向绑定数据问题
Apr 04 Javascript
微信小程序实现多行文字超出部分省略号显示功能
Oct 23 Javascript
JavaScript数组排序功能简单实现
May 14 Javascript
通过js随机函数Math.random实现乱序
May 19 Javascript
vue设置全局访问接口API地址操作
Aug 14 Javascript
vue实现列表拖拽排序的示例代码
Apr 08 Vue.js
antd Upload 文件上传的示例代码
Dec 14 #Javascript
Vue源码解析之Template转化为AST的实现方法
Dec 14 #Javascript
JavaScript模板引擎实现原理实例详解
Dec 14 #Javascript
Angular2 自定义表单验证器的实现方法
Dec 14 #Javascript
JavaScript模板引擎应用场景及实现原理详解
Dec 14 #Javascript
详解React 服务端渲染方案完美的解决方案
Dec 14 #Javascript
JS/HTML5游戏常用算法之路径搜索算法 A*寻路算法完整实例
Dec 14 #Javascript
You might like
在PHP中利用XML技术构造远程服务(上)
2006/10/09 PHP
ThinkPHP模板IF标签用法详解
2014/07/01 PHP
PHP函数rtrim()使用中的怪异现象分析
2017/02/24 PHP
经典海量jQuery插件 大家可以收藏一下
2010/02/07 Javascript
基于jquery的内容循环滚动小模块(仿新浪微博未登录首页滚动微博显示)
2011/03/28 Javascript
23个超流行的jQuery相册插件整理分享
2011/04/25 Javascript
jquery插件validate验证的小例子
2013/05/08 Javascript
BootStrap网页中代码显示用法详解
2016/10/21 Javascript
bootstrap 下拉多选框进行多选传值问题代码分析
2017/02/14 Javascript
jQuery为某个div加入行样式
2017/06/09 jQuery
vue-router单页面路由
2017/06/17 Javascript
vue语法之拼接字符串的示例代码
2017/10/25 Javascript
原生javascript实现文件异步上传的实例讲解
2017/10/26 Javascript
基于javascript中的typeof和类型判断(详解)
2017/10/27 Javascript
vue使用jsonp抓取qq音乐数据的方法
2018/06/21 Javascript
angular将html代码输出为内容的实例
2018/09/30 Javascript
vue全局使用axios的方法实例详解
2018/11/22 Javascript
JS利用prototype给类添加方法操作详解
2019/06/21 Javascript
Js生成随机数/随机字符串的方法小结【5种方法】
2020/05/27 Javascript
谈谈JavaScript中的垃圾回收机制
2020/09/17 Javascript
vue 基于abstract 路由模式 实现页面内嵌的示例代码
2020/12/14 Vue.js
vue登录页实现使用cookie记住7天密码功能的方法
2021/02/18 Vue.js
Flask实现图片的上传、下载及展示示例代码
2018/08/03 Python
python多线程与多进程及其区别详解
2019/08/08 Python
tensorflow使用range_input_producer多线程读取数据实例
2020/01/20 Python
Python3读写Excel文件(使用xlrd,xlsxwriter,openpyxl3种方式读写实例与优劣)
2020/02/13 Python
PyQt5中向单元格添加控件的方法示例
2020/03/24 Python
css sprite简单实例
2016/05/23 HTML / CSS
css3 transform 3d 使用css3创建动态3d立方体(html5实践)
2013/01/06 HTML / CSS
美国创意礼品网站:UncommonGoods
2017/02/03 全球购物
美国电视购物:QVC
2017/02/06 全球购物
DOUGLAS荷兰:购买香水和化妆品
2020/10/24 全球购物
上课迟到检讨书100字
2014/01/11 职场文书
高三体育教学反思
2014/01/29 职场文书
党校毕业个人总结
2015/02/28 职场文书
慰问信的写作格式及范文!
2019/06/24 职场文书