vue移動端預覽pdf功能(可以多頁)以及第三方電子簽章不能正常展示解決方案(多種)

vue移動端預覽pdf功能(可以多頁)以及第三方電子簽章不能正常展示解決方案(多種)

隨着網絡的發展,PC端的網站已不能滿足人們的需求,人們更喜歡採用移動端進行業務操作。最近公司要求把PC端網站的訂單合同簽署功能移植到微信端,而不再侷限於PC端操作。

對於這樣的要求,我們需要了解的是訂單合同,協議書之類的一般都屬於不可以任意修改的文件(PDF),這樣的文件,現在的瀏覽器基本都支持直接訪問的。但是遺憾的是,移動端並不支持直接訪問,這樣我們需要對PDF文件進行解析處理。首先我們考慮到通過服務器訪問到PDF文件,傳遞到前端,再由前端進行解析處理。

這裏前端框架採用vue,vue中有整合到第三方pdf解析庫pdfjs-dist

1、安裝 pdfjs-dist

npm install pdfjs-dist --save

2、創建pdf組件 pdf-component.vue

<template>
  <div>
    <canvas v-for="page in pages" :id="'the-canvas'+page" :key="page"></canvas>
  </div>
</template>

<script>
import PDFJS from 'pdfjs-dist'
const Base64 = require('js-base64').Base64

export default {
  name: 'pdf-component',
  data () {
    return {
      title: '查看合同',
      pdfDoc: null,
      pages: 0
    }
  },
  methods: {
    _renderPage (num) {
      this.pdfDoc.getPage(num).then((page) => {
        let canvas = document.getElementById('the-canvas' + num)
        let ctx = canvas.getContext('2d')
        let dpr = window.devicePixelRatio || 1
        let bsr = ctx.webkitBackingStorePixelRatio ||
                  ctx.mozBackingStorePixelRatio ||
                  ctx.msBackingStorePixelRatio ||
                  ctx.oBackingStorePixelRatio ||
                  ctx.backingStorePixelRatio || 1
        let ratio = dpr / bsr
        let viewport = page.getViewport(screen.availWidth / page.getViewport(1).width)
        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)
        let renderContext = {
          canvasContext: ctx,
          viewport: viewport
        }
        page.render(renderContext)
        if (this.pages > num) {
          this._renderPage(num + 1)
        }
      })
    },
    _loadFile (url) {
      PDFJS.getDocument(url).then((pdf) => {
        this.pdfDoc = pdf
        this.pages = this.pdfDoc.numPages
        this.$nextTick(() => {
          this._renderPage(1)
        })
      })
    }
  },
  mounted () {
    document.title = this.title
    let url = Base64.decode(this.$route.query.url)
    this._loadFile(url)
  }
}
</script>

<style scoped>
canvas {
  display: block;
  border-bottom: 1px solid black;
}
</style>

3、路由配置

{
  path: '/pdf',
  name: 'pdf',
  component: () => import('@/components/public/pdf-component'),
  meta: {
  }
}

4、點擊跳轉事件

_loadingPdf (id) {
   let url = '/api/orders/findPdfById/' + id
   this.$router.push({ name: 'pdf', query: { url: Base64.encode(url) } })
}

整個前端加載pdf功能已全部做完。代碼量不多,在測試中一個1M左右的pdf文件在頁面渲染時間大約在3秒左右,如果有多頁的則需要更多時間,效率上並不是很理想。

另一種方法


思路: 通過獲取雲端pdf文件,解析成圖片,然後返回給前端,前端只需要展現圖片即可,不需要做任何操作。
1、pdf組件

<template>
  <div>
    <img v-if="imgSrc" :src="imgSrc">
  </div>
</template>

<script>
const Base64 = require('js-base64').Base64
export default {
  data () {
    return {
      title: '查看合同',
      imgSrc: '',
      pages: 0
    }
  },
  methods: {
  },
  mounted () {
    document.title = this.title
    this.imgSrc = Base64.decode(this.$route.query.url)
  }
}
</script>

<style scoped>
  img {
  display: block;
  border-bottom: 1px solid black;
}
</style>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章