pdfjs-dist在vue的使用

背景:iframe展示 pdf 在 IE 浏览器直接下载文件,无法预览展示。

1.安装 pdfjs-dist,别的版本有遇到些未知错误,最后用的 2.0.943 版本

npm install pdfjs-dist@2.0.943 --save

2.创建组件文件

没做翻页,展示全部页下滑展示

<template>
  <div class="pdf-wrap">
    <div class="canvas-container"></div>
  </div>
</template>
<script>
const pdfJS = require('pdfjs-dist')
pdfJS.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.entry')
export default {
  props: {
  	// pdf 的url地址
    src: String
  },
  mounted() {
    this.loadPdfData()
  },
  data() {
    return {
      pageNo: null,
      pdfPageNumber: null,
      pdfTotalPages: 1,
      renderingPage: false,
      pdfData: null, // PDF的base64
      scale: 1.5, // 缩放值
    }
  },
  methods: {
    loadPdfData() {
      this.pdfData = pdfJS.getDocument(this.src)
      // console.log(this.pdfData)
      this.renderPage()
    },
    // 渲染PDF
    renderPage() {
      this.renderingPage = true
      const canvasContainer = document.querySelector('.canvas-container')
      canvasContainer.innerHTML = '';
      this.pdfData.promise.then((pdf) => {
        this.pdfPageNumber = pdf.numPages
        for(let i = 1; i <= pdf.numPages; i++) {
          pdf.getPage(i).then((page) => {
          // 获取DOM中为预览PDF准备好的canvasDOM对象
          // let canvas = this.$refs.myCanvas
          let canvas = document.createElement('canvas')
          canvas.className = 'pdf-container'
          let viewport = page.getViewport(this.scale)
          canvas.height = viewport.height
          canvas.width = viewport.width
          canvasContainer.appendChild(canvas)
          let ctx = canvas.getContext('2d')
          let renderContext = { canvasContext: ctx, viewport: viewport }
          page.render(renderContext).then(() => {
            this.renderingPage = false
          })
        })
        }
      })
    }
  },
}
</script>
<style scoped>
.pdf-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.canvas-container {
  border: 1px dashed #e1e1e1;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
canvas {
  border: 1px dashed black;
  margin-bottom: 10px;
  width: 100%;
  height: 100%;
}
</style>

然后在对应的地方引入即可,传入对应的 src 路径;

3.做了分页的代码

<template>
  <div class="pdf-wrap">
    <div class="canvas-container">
      <canvas ref="myCanvas" class="pdf-container"> </canvas>
    </div>
    <div class="pagination-wrapper mt10">
      <el-button type="text" @click="clickPre">上一页</el-button
      ><span class="ml8 mr8">{{ pageNo }} / {{ pdfPageNumber }}</span
      ><el-button type="text" @click="clickNext">下一页</el-button>
      <!-- <el-pagination
        background
        layout="next , pager, prev"
        @current-change="handleCurrentChange"
        :page-size="1"
        :total="pdfTotalPages">
      </el-pagination> -->
    </div>
  </div>
</template>
<script>
const pdfJS = require('pdfjs-dist')
pdfJS.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.entry')
export default {
  props: {
    src: String
  },
  mounted() {
    this.loadPdfData()
  },
  data() {
    return {
      pageNo: null,
      pdfPageNumber: null,
      pdfTotalPages: 1,
      renderingPage: false,
      pdfData: null, // PDF的base64
      scale: 1.5, // 缩放值
    }
  },
  methods: {
    // 加载pdf数据
    loadPdfData() {
      this.pdfData = pdfJS.getDocument(this.src)
      console.log(this.pdfData)
      this.renderPage(1)
      this.renderScrollPdf()
    },
    // 根据页码渲染相应的PDF
    renderPage(num) {
      this.renderingPage = true
      this.pdfData.promise.then((pdf) => {
        this.pdfPageNumber = pdf.numPages
        pdf.getPage(num).then((page) => {
          // 获取DOM中为预览PDF准备好的canvasDOM对象
          let canvas = this.$refs.myCanvas
          let viewport = page.getViewport(this.scale)
          canvas.height = viewport.height
          canvas.width = viewport.width
          let ctx = canvas.getContext('2d')
          let renderContext = { canvasContext: ctx, viewport: viewport }
          page.render(renderContext).then(() => {
            this.renderingPage = false
            this.pageNo = num
          })
        })
      })
    },
    // 上一页
    clickPre() {
      if (!this.renderingPage && this.pageNo && this.pageNo > 1) {
        this.renderPage(this.pageNo - 1)
      }
    },
    // 下一页
    clickNext() {
      if (
        !this.renderingPage &&
        this.pdfPageNumber &&
        this.pageNo &&
        this.pageNo < this.pdfPageNumber
      ) {
        this.renderPage(this.pageNo + 1)
      }
    },
    renderScrollPdf() {
      this.pdfData.promise.then((pdf) => {
        this.pdfTotalPages = pdf.numPages
      })
    },
  },
}
</script>
<style scoped>
.pdf-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.canvas-container {
  /* width: 600px; */
  /* height: 500px; */
  border: 1px dashed #e1e1e1;
  position: relative;
  display: flex;
  justify-content: center;
}
.scroll-pdf-contanier {
  width: 600px;
  height: 500px;
  border: 1px dashed black;
  position: relative;
  display: flex;
  flex-direction: column;
  overflow-y: scroll;
}
.pdf-container {
  width: 100%;
  height: 100%;
}
.scroll-pdf-container {
  width: 350px;
}
.pagination-wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>

补充:
如果要展示盖章文件,会有印章不展示的问题,解决方案如下:
在node_modules里找到 pdfjs-dist 文件下的 pdf.worker.js 搜索 data.fieldType 注释掉 _this2.setFlags(_util.AnnotationFlag.HIDDEN) 就可以了。
在这里插入图片描述
在这里插入图片描述

本地注释后生产怎么处理,网上处理办法挺多的,都可以借鉴下:
我采用的处理办法:新建一个initInstall.js文件和package.json同级,执行下node initInstall.js 替换下对应文件的内容,然后再运行项目

const fs = require('fs');

const filePath = 'node_modules/pdfjs-dist/build/pdf.worker.js';
fs.readFile(filePath, 'utf8', (err, data) => {
    if (err) {
        console.error(err);
        return;
    }
    const modifiedData = data.replace(
      /_this2.setFlags/g,
      '// _this2.setFlags'
    )
    fs.writeFile(filePath, modifiedData, 'utf8', (err) => {
        if (err) {
            console.error(err);
            return;
        }
        console.log('File modified successfully!');
    });
});
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值