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 相关文章推荐
3Z版基于jquery的图片复选框(asp.net+jquery)
Apr 12 Javascript
JQUERY获取form表单值的代码
Jul 17 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(四)用地图块拼成大地图
Jan 23 Javascript
Jquery网页出现的乱码问题的三种解决方法
Jun 30 Javascript
判断iframe里的页面是否加载完成
Jun 06 Javascript
JavaScript设计模式之代理模式介绍
Dec 28 Javascript
轻松掌握JavaScript装饰者模式
Aug 27 Javascript
js调用屏幕宽度的简单方法
Nov 14 Javascript
详解基于javascript实现的苹果系统底部菜单
Dec 02 Javascript
解决Vue2.0 watch对象属性变化监听不到的问题
Sep 11 Javascript
详解vue-cli3多页应用改造
Jun 04 Javascript
js实现点赞按钮功能的实例代码
Mar 06 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 5.0对象模型深度探索之属性和方法
2008/03/27 PHP
PHP自动选择 连接本地还是远程数据库
2010/12/02 PHP
解析PHP生成静态html文件的三种方法
2013/06/18 PHP
PHP常用技巧汇总
2016/03/04 PHP
php实现base64图片上传方式实例代码
2017/02/22 PHP
PHP通过文件保存和更新信息的方法分析
2019/09/12 PHP
javascript中注册和移除事件的4种方式
2013/03/20 Javascript
JS简单的轮播的图片滚动实例
2013/06/17 Javascript
jQuery下的动画处理总结
2013/10/10 Javascript
NodeJS学习笔记之MongoDB模块
2015/01/13 NodeJs
Javascript实现飞动广告效果的方法
2015/05/25 Javascript
在JavaScript的正则表达式中使用exec()方法
2015/06/16 Javascript
谈谈基于iframe、FormData、FileReader三种无刷新上传文件的方法
2015/12/03 Javascript
BootStrap+Angularjs+NgDialog实现模式对话框
2016/08/24 Javascript
AngularJs 延时器、计时器实例代码
2017/09/16 Javascript
一个基于react的图片裁剪组件示例
2018/04/18 Javascript
微信小程序局部刷新触发整页刷新效果的实现代码
2018/11/21 Javascript
JQuery animate动画应用示例
2019/05/14 jQuery
关于element-ui的隐藏组件el-scrollbar的使用
2019/05/29 Javascript
vue 实现单选框设置默认选中值
2019/11/07 Javascript
解决Layui 表格自适应高度的问题
2019/11/15 Javascript
JavaScript对象原型链原理详解
2020/02/05 Javascript
vue中实现动态生成二维码的方法
2020/02/21 Javascript
vue单应用在ios系统中实现微信分享功能操作
2020/09/07 Javascript
[05:05]给小松五分钟系列 第二期介绍为什么打DOTA2
2014/07/02 DOTA
Python cookbook(数据结构与算法)实现优先级队列的方法示例
2018/02/18 Python
Python中GIL的使用详解
2018/10/03 Python
分享PyCharm的几个使用技巧
2019/11/10 Python
html5使用canvas实现弹幕功能示例
2017/09/11 HTML / CSS
canvas小画板之平滑曲线的实现
2020/08/12 HTML / CSS
小加工厂管理制度
2014/01/21 职场文书
幼儿评语大全
2014/04/30 职场文书
2015军训通讯稿大全
2015/07/18 职场文书
幼儿园小朋友毕业感言
2015/07/30 职场文书
新年寄语2016
2015/08/17 职场文书
Beekeeper Studio开源数据库管理工具比Navicat更炫酷
2022/06/21 数据库