Vue PDF文件預覽vue-pdf

   最近作項目,遇到預覽PDF這個功能,在網上找了找,大多推薦的是pdf.js,不過在Vue中仍是想偷懶直接npm組件,最後找到了一個還不錯的Vue-pdf 組件,GitHub地址:https://github.com/FranckFreiburger/vue-pdf#readme
不過通常GitHub上的註釋比較簡潔,因此這裏把本身實際使用的過程總結了一下,下面貼代碼
 
 本博客源碼:  https://github.com/shengbid/vue-demo  這個項目裏會把平時博客寫的一些功能的代碼都放在裏面,有須要能夠下載看看,有幫助的話點個star哈
 
引用: npm install --save vue-pdf
 
template代碼:
<template>
  <div class="pdf" v-show="fileType === 'pdf'">
    <p class="arrow">
    // 上一頁
    <span @click="changePdfPage(0)" class="turn" :class="{grey: currentPage==1}">Preview</span>
    {{currentPage}} / {{pageCount}} // 下一頁
    <span @click="changePdfPage(1)" class="turn" :class="{grey: currentPage==pageCount}">Next</span>
    </p>
    // 本身引入就能夠使用,這裏個人需求是作了分頁功能,若是不須要分頁功能,只要src就能夠了
    <pdf :src="src" // src須要展現的PDF地址
      :page="currentPage" // 當前展現的PDF頁碼
      @num-pages="pageCount=$event" // PDF文件總頁碼
      @page-loaded="currentPage=$event" // 一開始加載的頁面
      @loaded="loadPdfHandler"> // 加載事件
    </pdf>
  </div>
</template>
js代碼:<script>   // 引入PDF
 import pdf from 'vue-pdf' export default { components: {pdf}, data () { return { currentPage: 0, // pdf文件頁碼 pageCount: 0, // pdf文件總頁數 fileType: 'pdf', // 文件類型
     src: '', // pdf文件地址

} },
  created: {
    // 有時PDF文件地址會出現跨域的狀況,這裏最好處理一下
    this.src = pdf.


createLoadingTask(this.src)
  } method: { // 改變PDF頁碼,val傳過來區分上一頁下一頁的值,0上一頁,1下一頁
 changePdfPage (val) { // console.log(val)
        if (val === 0 && this.currentPage > 1) { this.currentPage--
          // console.log(this.currentPage)
 } if (val === 1 && this.currentPage < this.pageCount) { this.currentPage++
          // console.log(this.currentPage)
 } }, // pdf加載時
 loadPdfHandler (e) { this.currentPage = 1 // 加載的時候先加載第一頁
 } } } </script>

實際效果html

 

問題補充:  文件打印亂碼問題解決方法

以前有人問了關於PDF打印亂碼問題,我本身試了確實有這個問題,在官網找了一下,有人提交了代碼解決了這個問題,如今我把方法附上vue

原始的打印頁面,PDF格式亂碼,主要是由於PDF裏使用了自定義字體,不能識別git

 

須要修改vue-pdf安裝包的pdfjsWrapper.js文件github

上面後綴爲1的文件是原始的,紅線框起來的是我修改以後的文件npm

替換以後,打印就能正常顯示了,canvas

 

 

博客園貌似不能上傳文件,代碼太多就不放上來了,若是有須要能夠找我郵箱發你,或者到官網本身修改文件跨域

git-hup地址:https://github.com/FranckFreiburger/vue-pdf/pull/130/commits/253f6186ff0676abf9277786087dda8d95dd8ea7,promise

 

 上面提供的解決文件打印亂碼的問題,實現起來比較麻煩,並且如今vue-pdf的版本已經更新了,用這個方法可能還會出現空白頁的問題.本身在研究了下,用了iframe來預覽打印,效果會更好些,這裏把方法放上來,有須要的能夠試試瀏覽器

這裏的例子是把PDF文件放在elment的彈框中,固然你能夠根據你本身的適用場景來決定安全

html:

<el-dialog :close-on-click-modal="false" :visible.sync="dialogVisible" :fullscreen="true" title="文件預覽">
          <div class="agreement_picture">
            <div class="pdf">
              <!-- <pdf // 以前的用PDF插件的方法
                v-for="i in pdf.numPages" :key="i" :page="i" :src="src">
              </pdf> -->
              // 使用iframe方法
              <iframe :src="src" frameborder="0" style="width: 100%; height: 100%"></iframe>
            </div>
          </div>
          <span slot="footer" class="dialog-footer">
            <div class="tip-left transfer">
                <el-button type="info" @click="dialogVisible=false">不一樣意</el-button>
              <el-button type="danger" @click="agreeSignFun">贊成</el-button>
            </div>
          </span>
        </el-dialog>

js:

 data () { return { src: '/static/file/中國互聯網總體網民發展情況——《第31次中國互聯網發展情況調查報告(上)》.pdf', //pdf地址,這裏我用的是我本地的文件,你也能夠使用後臺的文件
 dialogVisible: true } }

 

效果展現:

打印效果:

 

補充內容:

朋友們,關於跨域問題,我這裏說明一下,若是你是在本地localhost環境請求後臺接口返回的文件地址,通常都會跨域,報錯以下

這個文件地址我在瀏覽器能夠直接打開預覽

 

遇到這種問題,是由於你本地的localhost和你後臺返回的域名不一致,能夠先用一個本地靜態文件調試效果,在線上環境即經過打包部署的環境(域名和返回的PDF域名一致的環境)再看效果.若是域名端口一致的狀況還有報跨域的錯誤,那你的項目與vue-pdf八字不合,建議更換組件

 

另外補充一下打印的問題,經過vue-pdf自帶的打印功能,打印出來的效果通常是這樣

 

這個做者在git上也說了,如今vue-pdf的打印功能還在試驗階段,沒有完善,因此寄但願於這個方法實現打印還需一段時日,上面的內容裏我用了<iframe>標籤來預覽打印,可是如今iframe已經不怎麼使用了,有些項目還不容許用,這裏我再補充兩種打印方法

1. 先把PDF內容轉成圖片後再打印

<el-dialog title="文件預覽" :visible.sync="dialogVisible" width="50%"
    >
      <div ref="printContent">
        <!-- 加載所有頁面的PDF是循環生成,不能指定ref,不能調用print打印方法 -->
        <Pdf v-for="i in numPages" :key="i" :src="src" :page="i"
        />
        <!-- 寫一個隱藏的PDF,用來調用打印 -->
        <Pdf v-show="false" ref="printPdf" :src="src"
        />
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="print">vue-pdf自帶打印</el-button>
        <el-button type="primary" @click="toImg">轉圖片打印</el-button>
      </span>
    </el-dialog>
<script> import Pdf from 'vue-pdf' import html2canvas from 'html2canvas' import printJS from 'print-js' export default { components: { Pdf }, data() { return { fileList: [ { id: 1, fileName: '增進函', fileUrl: 'http://172.16.79.33:8888/group1/.........../rBBPIV7whg2AQNCmAAoc6DKtkwE841.pdf' }, { id: 2, fileName: '應收帳款', fileUrl: `${window.location.origin}/test1.pdf`
 } ], numPages: undefined, dialogVisible: false, src: '', printName: '轉圖片打印' } }, created() { }, methods: { // 預覽
 preview(item) { this.src = Pdf.createLoadingTask(item.fileUrl) this.src.promise.then(pdf => { this.numPages = pdf.numPages }) this.dialogVisible = true
      this.printName = item.fileName }, // 轉圖片打印
 toImg() {  html2canvas(this.$refs.printContent, { backgroundColor: null, useCORS: true, windowHeight: document.body.scrollHeight }).then((canvas) => { const url = canvas.toDataURL() printJS({ printable: url, type: 'image', documentTitle: this.printName }) // console.log(url)
 }) }, // pdf自帶打印
 print() { this.$refs.printPdf.print() } } }

打印效果

 

2.跳轉頁面打印,這種和iframe的差很少,新建一個頁面,調用window.print()打印頁面,效果以下

 

最近我會把vue-pdf的使用整理一下,把源碼放到git上,以前的代碼找不到了

 若是以上都不能解決你的問題,我以爲你能夠使用window.open()直接新頁面打開預覽,使用瀏覽器自帶的打印預覽功能.若是產品不一樣意,你能夠對他曉之以情,動之以理

 

如今通常項目爲了安全性,不會直接返回文件地址,會返回文件流的格式,對於文件流格式文件能夠轉化成blob文件,若是有須要能夠看下我另外一篇博客:文件流數據如何轉blob文件 https://www.cnblogs.com/steamed-twisted-roll/p/11821148.html

相關文章
相關標籤/搜索