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>

實際效果

 

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

之前有人問了關於PDF打印亂碼問題,我自己試了確實有這個問題,在官網找了一下,有人提交了代碼解決了這個問題,現在我把方法附上

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

 

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

上面后綴為1的文件是原始的,紅線框起來的是我修改之后的文件

替換之后,打印就能正常顯示了,

 

 

博客園貌似不能上傳文件,代碼太多就不放上來了,如果有需要可以找我郵箱發你,或者到官網自己修改文件

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

 

 上面提供的解決文件打印亂碼的問題,實現起來比較麻煩,而且現在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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM