IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 超详细的vue3使用pdfjs教程(1)- 渲染单页pdf -> 正文阅读

[JavaScript知识库]超详细的vue3使用pdfjs教程(1)- 渲染单页pdf

vue3中如何使用pdfjs来展示pdf文档

在项目开发中碰到一个需求是在页面中展示pdf预览功能,本人的项目使用的是vue3,实现pdf预览使用的是pdf预览神器 pdfjs

以下,将详细介绍如何在项目中使用pdfjs,主要包括以下内容:

  • 单页pdf加载
  • 多页pdf加载
  • pdf放大/缩小/大小重置
  • pdf分页展示以及上下翻页
  • pdf添加水印
  • 动态添加pdf
  • 从服务端获取pdf文件

参考资料: pdfjs源码及使用文档

1. 准备工作

1.1 pdfjs-dist 安装

百度搜索 npm pdfjs-dist,进入npm官方网站,即可查看pdfjs的安装方法:

安装命令:

npm i pdfjs-dist

2. 在vue3中使用pdfjs-dist查看pdf文档

2.1 基本页面代码

首先把基本的页面代码准备起来,具体代码如下:

<template>
  <div class="pdf-container">
    <canvas id="pdf-canvas"></canvas>
  </div>
</template>
<script lang="ts">
import { Options,  Vue } from 'vue-class-component'
import * as PdfJs from 'pdfjs-dist/legacy/build/pdf.js' // 注意导入的写法
import Pdf from '@/assets/js.pdf'

@Options({})
export default class SinglePage extends Vue {

}
</script>

以上是使用的 vue3 的 class模式编写vue代码的方式,对于此种使用方式不清楚的,可以查看我的这篇文章:

超全的Vue中的Class Component使用总结

Vue中的Class Component使用指南

2.2 pdfjs工作原理简述

pdfjs展示pdf文档的原理,实际上是将pdf中的内容渲染到解析,然后渲染到 canvas 中进行展示,因此我们使用pdfjs渲染出来的pdf文件,实际上是一张张canvas图片。

2.3 pdf文件展示(单页

pdfjs的使用主要涉及到2个方法,分别是loadFile()renderPage()

  • loadFile()
    主要用来加载pdf文件,其实现如下:
loadFile (url: string): void {
  // 设定pdfjs的 workerSrc 参数
  // NOTE: 这一步要特别注意,网上很多关于pdfjs的使用教程里漏了这一步,会出现workerSrc未定义的错误
  PdfJs.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.entry')

  const loadingTask = PdfJs.getDocument(url)
  loadingTask.promise.then((pdf) => {
    this.pdfDoc = pdf // 保存加载的pdf文件流
    this.pdfPages = this.pdfDoc.numPages // 获取pdf文件的总页数
    this.$nextTick(() => {
      this.renderPage(1) // 将pdf文件内容渲染到canvas,
    })
  })
}

以上代码因为使用了 ts ,有部分函数参数类型的设定,在使用过程中,如遇到ts的报错,可以直接把类型设置为 any.

需要注意:
以上部分的 workerSrc 赋值部分,需要特别注意,在pdfJs的使用示例中明确指出,
workerSrc 的值要手动指定,如果没有指定此值,则会出现 workerSrc 未定义的bug,
另外,要注意,赋值时一定要赋值为 pdf.worker.entry (以entry结尾,表示入口)

  • renderPage() 方法
    主要用来将pdf文件的内容渲染到canvas上,其实现如下:
  // num 表示渲染第几页
  renderPage (num: any): void {
    this.pdfDoc.getPage(num).then((page: any) => {
      const canvas: any = document.getElementById('pdf-canvas') // 获取页面中的canvas元素
      // 以下canvas的使用过程
      const ctx: any = canvas.getContext('2d')
      const dpr = window.devicePixelRatio || 1
      const bsr = ctx.webkitBackingStorePixelRatio ||
                  ctx.mozBackingStorePixelRatio ||
                  ctx.msBackingStorePixelRatio ||
                  ctx.oBackingStorePixelRatio ||
                  ctx.backingStorePixelRatio ||
                  1
      const ratio = dpr / bsr
      const viewport = page.getViewport({ scale: this.pdfScale }) // 设置pdf文件显示比例
      canvas.width = viewport.width * ratio
      canvas.height = viewport.height * ratio
      canvas.style.width = viewport.width + 'px'
      canvas.style.height = viewport.height + 'px'
      ctx.setTransform(ratio, 0, 0, ratio, 0, 0) // 设置当pdf文件处于缩小或放大状态时,可以拖动
      const renderContext = {
        canvasContext: ctx,
        viewport: viewport
      }
      // 将pdf文件的内容渲染到canvas中
      page.render(renderContext)
    })
  }

2.4 完整实现代码

<template>
  <div class="pdf-container">
    <canvas id="pdf-canvas"></canvas>
  </div>
</template>
<script lang="ts">
import { Options, Vue } from 'vue-class-component'
import * as PdfJs from 'pdfjs-dist/legacy/build/pdf.js'
import Pdf from '@/assets/js.pdf'

@Options({})
export default class SinglePage extends Vue {
  pdfDoc: any = '' // 保存加载的pdf文件流
  pdfPages = 0
  pdfScale = 1.0

  // class 组件中生命周期函数直接这样写
  created () {
    this.loadFile(Pdf)
  }

  loadFile (url: string): void {
    PdfJs.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.entry')
    const loadingTask = PdfJs.getDocument(url)
    loadingTask.promise.then((pdf) => {
      this.pdfDoc = pdf
      this.pdfPages = this.pdfDoc.numPages
      this.$nextTick(() => {
        this.renderPage(1) // 表示渲染第 1 页
      })
    })
  }

  renderPage (num: any) {
    this.pdfDoc.getPage(num).then((page: any) => {
      const canvas: any = document.getElementById('pdf-canvas')
      const ctx: any = canvas.getContext('2d')
      const dpr = window.devicePixelRatio || 1
      const bsr = ctx.webkitBackingStorePixelRatio ||
                  ctx.mozBackingStorePixelRatio ||
                  ctx.msBackingStorePixelRatio ||
                  ctx.oBackingStorePixelRatio ||
                  ctx.backingStorePixelRatio ||
                  1
      const ratio = dpr / bsr
      const viewport = page.getViewport({ scale: this.pdfScale })
      canvas.width = viewport.width * ratio
      canvas.height = viewport.height * ratio
      canvas.style.width = viewport.width + 'px'
      canvas.style.height = viewport.height + 'px'
      ctx.setTransform(ratio, 0, 0, ratio, 0, 0)
      const renderContext = {
        canvasContext: ctx,
        viewport: viewport
      }
      page.render(renderContext)
    })
  }
}
</script>

2.5 效果

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-12 16:30:39  更:2021-08-12 16:30:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 21:33:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码