美文网首页
对pdfjs-dist进行vue组件封装(svg和canvas两

对pdfjs-dist进行vue组件封装(svg和canvas两

作者: AaronZ_dd7f | 来源:发表于2020-08-21 15:43 被阅读0次

    组件封装

    这边以vue-cli3生成的项目为例

    1. 安装相关文件
    npm install pdfjs-dist@2.4.456 --save
    
    1. 将node_modules中的pdfjs-dist/es5/build,pdfjs-dist/es5/web,pdfjs-dist/cmaps拷贝到public目录下,
      这边也可以将修改好的源码上传到cdn,引用会更加方便。


      引入pdfjs-dist
    2. (可选) 修改打开电子签章显示的代码
      public/pdfjs-dist/es5/build/pdf.worker.js


      pdf.work.js
    1. 在components下新建pdf文件夹


      pdf

    getPdfjsDist代码如下

    // src/components/pdf/getPdfjsDist.js
    const getJavsScript = (src) => {
      return new Promise((resolve, reject) => {
        const script = document.createElement('script')
    
        script.onload = resolve
        script.onerror = reject
    
        script.src = src
        document.body.append(script)
      })
    }
    
    const getCss = (href) => {
      return new Promise((resolve, reject) => {
        const link = document.createElement('link')
    
        link.onload = resolve
        link.onerror = reject
    
        link.setAttribute('rel', 'stylesheet')
        link.setAttribute('type', 'text/css')
        link.href=href
        document.body.append(link)
      })
    }
    
    const getPdfjsDist = (pdfjsDistPath) => {
      return getJavsScript(`${pdfjsDistPath}/pdfjs-dist/es5/build/pdf.js`)
      .then(() => {
        return Promise.all([
          getJavsScript(`${pdfjsDistPath}/pdfjs-dist/es5/web/pdf_viewer.js`),
          getCss(`${pdfjsDistPath}/pdfjs-dist/es5/web/pdf_viewer.css`)
        ])
      })
    }
    
    export default getPdfjsDist
    

    index.js代码如下

    // src/components/pdf/index.js
    import './index.less'
    import Pdf from './pdf'
    
    Pdf.install = (Vue) => {
      Vue.component(Pdf.name, Pdf);
    };
      
    
    export default Pdf
    

    pdf.js代码如下

    // src/components/pdf/pdf.js
    import getPdfjsDist from '@/components/pdf/getPdfjsDist'
    
    export default {
      name: 'Pdf',
      props: {
        url: {
          type: String,
          default: ''
        },
        type: {
          type: String,
          default: 'svg'
        },
        pdfjsDistPath: {
          type: String,
          default: '.'
        }
      },
      data() {
        return {
          pdfViewer: null,
          pdfLinkService: null,
          currentScale: 'page-width',
          loadingTask: null
        }
      },
    
      methods: {
        onPagesInit({source}) {
          source.currentScaleValue = this.currentScale
        },
        async pdfLibInit() {
          let pdfjsLib = window.pdfjsLib;
          let pdfjsViewer = window.pdfjsViewer
          if (!pdfjsLib || !pdfjsViewer) {
            try {
              await getPdfjsDist(this.pdfjsDistPath)
              this.CMAP_URL = `${this.pdfjsDistPath}/pdfjs-dist/cmaps/`
              pdfjsLib = window.pdfjsLib;
              pdfjsLib.GlobalWorkerOptions.workerSrc = `${this.pdfjsDistPath}/pdfjs-dist/es5/build/pdf.worker.js`
              pdfjsViewer = window.pdfjsViewer
            } catch (error) {
              // console.log(error)
              // pdfjs文件获取失败
              return 
            }
          }
    
          const container = this.$refs.container
          const eventBus = new pdfjsViewer.EventBus();
    
          // (Optionally) enable hyperlinks within PDF files.
          const pdfLinkService = new pdfjsViewer.PDFLinkService({
            eventBus: eventBus,
          });
          this.pdfLinkService = pdfLinkService
          const pdfViewer = new pdfjsViewer.PDFViewer({
            container: container,
            eventBus: eventBus,
            linkService: pdfLinkService,
            renderer: this.type,
            textLayerMode: 0,
            downloadManager: new pdfjsViewer.DownloadManager({}),
            enableWebGL: true
          });
          this.pdfViewer = pdfViewer
          pdfLinkService.setViewer(pdfViewer);
    
          eventBus.on("pagesinit", this.onPagesInit);
        },
        renderPdf() {
          if (!this.url) { return }
          // Loading document.
          if (this.pdfViewer === null || this.pdfLinkService === null) {
            return
          }
          if (this.loadingTask !== null) {
            this.loadingTask.destroy()
            this.loadingTask = null
          }
          this.loadingTask = window.pdfjsLib.getDocument({
            cMapUrl: this.CMAP_URL,
            cMapPacked: true,
            url: this.url,
          });
          return this.loadingTask.promise.then((pdfDocument) => {
            if (pdfDocument.loadingTask.destroyed || !this.url) { return }
            this.pdfViewer.setDocument(pdfDocument)
            this.pdfLinkService.setDocument(pdfDocument, null);
            this.loadingTask = null
          }).catch(error => {
            console.log(error)
          });
        }
      },
      mounted() {
        this.pdfLibInit().then(() => {
          this.renderPdf()
        })
      },
      watch: {
        url() {
          // 如果存在pdfViewer则取消渲染
          if(this.pdfViewer) {
            this.pdfViewer._cancelRendering()
          }
          this.renderPdf()
        }
      },
      render() {
        return (
          <div class="pdf-view">
            <div id="viewerContainer" ref="container">
              <div id="viewer" class="pdfViewer" />
            </div>
          </div>
        )
      }
    }
    

    最终在组件中使用方式如下:

    <div style="width:320px;height:560px">
        <!-- canvas渲染方式 -->
        <pdf url="./helloworld.pdf" type="canvas" />
        <!-- svg渲染方式 -->
        <pdf url="./helloworld.pdf" type="svg" />
    </div>
    

    依然未解决的问题

    1. 发现使用svg渲染的过程中,依然有部分pdf的电子签章,无法显示出来。暂时也无法解决
    2. win10 chrome(版本:62.0.3202.94)
      Funtouch OS PD1803_A_1.20.4 自带浏览器 Mozilla/5.0(Linux;Android 8.1.0;vivo Y83A Build/011019;vw)AppleWebKit/537.36(KHTML, like Gecko)Ghrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/8.2.10.0 渲染部分表格会出现黑块

    相关文章

      网友评论

          本文标题:对pdfjs-dist进行vue组件封装(svg和canvas两

          本文链接:https://www.haomeiwen.com/subject/jvehdktx.html