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 相关文章推荐
经常用的图片在容器中的水平垂直居中实例
Jun 10 Javascript
不同浏览器的怪癖小结
Jul 11 Javascript
JS遮罩层效果 兼容ie firefox jQuery遮罩层
Jul 26 Javascript
jQuery 1.9.1源码分析系列(十)事件系统之主动触发事件和模拟冒泡处理
Nov 24 Javascript
javascript实现滚动效果的数字时钟实例
Jul 21 Javascript
原生js仿淘宝网商品放大镜效果
Feb 28 Javascript
JS实现简易刻度时钟示例代码
Mar 11 Javascript
微信小程序开发中的疑问解答汇总
Jul 03 Javascript
JS设计模式之数据访问对象模式的实例讲解
Sep 30 Javascript
javaScript动态添加Li元素的实例
Feb 24 Javascript
前端天气插件tpwidget使用方法详解
Jun 24 Javascript
原生js实现滑块区间组件
Jan 20 Javascript
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动态实现表格跨行跨列实现代码
2012/11/06 PHP
基于wordpress主题制作的具体实现步骤
2013/05/10 PHP
php抽象方法和抽象类实例分析
2016/12/07 PHP
PHP大文件分割上传 PHP分片上传
2017/08/28 PHP
PHP中的Iterator迭代对象属性详解
2019/04/12 PHP
根据地区不同显示时间的javascript代码
2007/08/13 Javascript
JavaScript自定义日期格式化函数详细解析
2014/01/14 Javascript
js无刷新操作table的行和列
2014/03/27 Javascript
AngularJS directive返回对象属性详解
2016/03/28 Javascript
js 弹出对话框(遮罩)透明,可拖动的简单实例
2016/07/11 Javascript
javascript实现的上下无缝滚动效果
2016/09/19 Javascript
jQuery实现右键菜单、遮罩等效果代码
2016/09/27 Javascript
webpack4的迁移的使用方法
2018/05/25 Javascript
React 源码中的依赖注入方法
2018/11/07 Javascript
Vue infinite update loop的问题解决
2019/04/23 Javascript
javascript数组常见操作方法实例总结【连接、添加、删除、去重、排序等】
2019/06/13 Javascript
如何使用CSS3+JQuery实现悬浮墙式菜单
2019/06/18 jQuery
如何基于filter实现网站整体变灰功能
2020/04/17 Javascript
微信小程序学习总结(二)样式、属性、模板操作分析
2020/06/04 Javascript
[02:22]2018DOTA2亚洲邀请赛VG赛前采访
2018/04/03 DOTA
[04:00]黄浦江畔,再会英雄——完美世界DOTA2 TI9应援视频
2019/07/31 DOTA
Python学习笔记(一)(基础入门之环境搭建)
2014/06/05 Python
python中的reduce内建函数使用方法指南
2014/08/31 Python
python 函数内部修改外部变量的方法
2018/12/18 Python
pytorch 自定义数据集加载方法
2019/08/18 Python
关于pycharm中pip版本10.0无法使用的解决办法
2019/10/10 Python
使用Python实现正态分布、正态分布采样
2019/11/20 Python
关于Tensorflow使用CPU报错的解决方式
2020/02/05 Python
英国Boots旗下太阳镜网站:Boots Designer Sunglasses
2018/07/07 全球购物
涉外经济法专业毕业生推荐信
2013/11/24 职场文书
网页设计个人找工作求职信
2013/11/28 职场文书
护理专业毕业生自荐信范文
2014/01/05 职场文书
舞蹈专业大学生职业规划范文
2014/03/12 职场文书
禁毒宣传活动总结
2014/08/26 职场文书
长城英文导游词
2015/01/30 职场文书
2016教师节感恩话语
2015/12/09 职场文书