【2020-10-31】vue项目中使用pdf.js预览pdf文件

4 篇文章 0 订阅

起因

项目中需要前端来解析.zip\ .image\ .pdf 预览图像,并且需要在图形上绘制。所以我的整体解决方法是,在解析生成的图形的基础上,覆盖一层 Canvas。

  • zip 使用了 jszip 直接将其中的图片取出来
  • image 可以直接使用 <img />展示没问题
  • pdf : 本来上面两步使用 <img />可以解决了,但是 pdf 不能够使用呀,在网上查找了资料,最后打算将 pdf 转换成 canvas ,使用的是 pdf,js

由于网上 关于 pdf,js 的资料都比较不统一,各种 API 都是比较老旧的,所以本次记录一下,希望帮助到后来的人能够快速完成一个 预览 pdf 的 Demo。

开始

先看看最终完成效果
在这里插入图片描述
安装 pdfjs-dist

npm i pdfjs-dist

这里直接附上代码

<template>
  <div class="file-container">
    <div class="file-upload">
      <h3>PDF 转 Canvas</h3>
      <el-upload class="file2img-upload"
        drag
        action=""
        :on-change="handleChange"
        accept=".pdf"
        :http-request="httpRequest"
        :before-upload="beforeUpload">
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        <div class="el-upload__tip"
          slot="tip">支持 PDF</div>
      </el-upload>
    </div>

    <div class="img-container"
      v-show="file">
      <div>
        <div class="theCanvas">
          <canvas id="theCanvas"></canvas>
        </div>
        <el-pagination layout="prev, pager, next"
          :current-page.sync="currentPage"
          :page-size="1"
          :total="total">
        </el-pagination>
      </div>
    </div>
  </div>
</template>

<script>
const pdfjsLib = require('pdfjs-dist')
// Setting worker path to worker bundle.
window.pdfjsWorker = require('pdfjs-dist/build/pdf.worker')
export default {
  data () {
    return {
      currentPage: 1,
      total: 0,
      pageRendering: false,
      file: null
    }
  },
  watch: {
    currentPage () {
      // 渲染完才允许切换页码
      if (!this.pageRendering) {
        this.loadPdf(this.file)
      }
    }
  },
  mounted () {

  },
  methods: {
    handleChange (files, fileList) {
      if (fileList.length > 1) {
        fileList.splice(0, 1)
      }
    },
    httpRequest (file) { },

    beforeUpload (file) {
      this.currentPage = 1 // 初始化

      const blob = new Blob([file])
      const reader = new FileReader()
      const that = this
      reader.onload = function () {
        that.file = this.result
        that.loadPdf(this.result)
      }
      reader.readAsArrayBuffer(blob)
    },

    async loadPdf (result) {
      const currentPage = this.currentPage
      const loadingTask = pdfjsLib.getDocument(result)
      const pdfDocument = await loadingTask.promise

      this.total = pdfDocument.numPages

      if (!pdfDocument) console.error('Error: ' + pdfDocument)
      // Request a first page
      this.pageRendering = true
      const pdfPage = await pdfDocument.getPage(currentPage)
      // Display page on the existing canvas with 100% scale.
      const viewport = pdfPage.getViewport({ scale: 1.0 - 0.2 })
      const canvas = document.getElementById('theCanvas')
      canvas.width = viewport.width
      canvas.height = viewport.height
      const ctx = canvas.getContext('2d')
      const renderTask = pdfPage.render({
        canvasContext: ctx,
        viewport: viewport
      })

      // Wait for rendering to finish
      await renderTask.promise

      this.pageRendering = false
    }

  }
}
</script>

<style lang="less" scoped>
.file-container {
  overflow: auto;
  display: flex;

  .img-container {
    flex: 1;
    display: flex;
    > div {
      margin: 0 auto;
      .theCanvas {
        display: inline-block;
        border: 1px solid #ccc;
      }
    }
  }
}
</style>

最后

附上

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_pengliang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值