vue pdf下載及預覽(移動端)

本文使用的是 vue-pdf,其實還有其他的很多比如pdf.js,只不過覺得這個和vue結合了應該不用下載一堆東西,直接npm install就可以,所以採用vue-pdf來撰寫pdf下載及預覽。

無論是預覽還是下載,都需要安裝vue-pdf

先看下效果:

1、安裝vue-pdf

npm install --save vue-pdf

2、在需要的組件裏面引用

import pdf from 'vue-pdf'

components: {pdf},

3、在需要的vue文件中引入vue-pdf,pdf引入以及使用的位置,如下圖:

一、pdf下載

1、先在template中定義一個下載按鈕,添加事件

<span @click.stop="gotoOption('downLoad', item['article'], index)"><i class="iconfont iconxiazai1"></i>下載</span>

 2、methods中定義方法:

gotoOption (val, item, index) {
      if (val === 'collect') {
        this.collectReport(item, index)
      } else if (val === 'downLoad') {
        this.downloadWeekly(item['local_access_full-text-link'], item['article_article-title'], item['uuid'])
      }
    },
    // 下載
    downloadWeekly (url, pdfName, uuid) {
      // 調用子組件的下載方法
      this.downloadPDF(url, pdfName, uuid)
    },

    downloadPDF (url, fileName, uuid) {
      const _this = this
      fetch(url).then(function (response) {
        if (response.ok) {
          return response.arrayBuffer()
        }
        throw new Error('Network response was not ok.')
      }).then(function (arraybuffer) {
        let blob = new Blob([arraybuffer], {
          type: `application/pdf;charset-UTF-8` // word文檔爲msword,pdf文檔爲pdf
        })

        let objectURL = URL.createObjectURL(blob)

        let downEle = document.createElement('a')
        let fname = fileName // 下載文件的名字
        // let fname = `download` // 下載文件的名字
        downEle.href = objectURL
        downEle.setAttribute('download', fname)
        document.body.appendChild(downEle)
        downEle.click()
        DownloadArticleList({ // 此處是調用接口,將下載的文件信息傳給後臺
          uuid: uuid,
          openid: _this.openid
        }).then(res => {
          if (res.data.errno === 0) {
            alert('下載完成')
          }
          console.log('xiazai:', res.data)
        })
      }).catch(function (error) {
        console.log('There has been a problem with your fetch operation: ', error.message)
      })
    },

以上就是pdf下載

二、pdf預覽

一共有兩種方法,一種是分頁,還可以放大縮小,另一種是不分頁,還未實現放大縮小

1、第一種是分頁的pdf預覽,也可以實現放大,代碼如下:

<template>
  <div class="collect_info">
    <div class="score_header">
      <div class="return__icon" @click="returnBack">
        <i class="iconfont iconfanhui"></i>
      </div>
      <div class="title">下載詳情</div>
    </div>
    <div class="pdf" v-show="fileType === 'pdf'">
      <p class="arrow">
        <!--      // 上一頁-->
        <span @click="changePdfPage(0)" class="turn" :class="{grey: currentPage===1}">上一頁</span>
        {{currentPage}} / {{pageCount}}
        <!--      // 下一頁-->
        <span @click="changePdfPage(1)" class="turn" :class="{grey: currentPage===pageCount}">下一頁</span>
      </p>
      <!--    // 自己引入就可以使用,這裏我的需求是做了分頁功能,如果不需要分頁功能,只要src就可以了-->
      <!--    // src需要展示的PDF地址-->
      <!--    // 當前展示的PDF頁碼-->
      <!--    // PDF文件總頁碼-->
      <!--    // 一開始加載的頁面-->
      <!--    // 加載事件-->
      <pdf :src="src" :page="currentPage"
           @num-pages="pageCount=$event"
           @page-loaded="currentPage=$event"
           @loaded="loadPdfHandler">
      </pdf>
    </div>
  </div>
</template>

<script>
import pdf from 'vue-pdf'
export default {
  metaInfo: {
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width,initial-scale=1.0, maximum-scale=2.0, user-scalable=yes' }
    ]
  },
  components: {pdf},
  data () {
    return {
      currentPage: 0, // pdf文件頁碼
      pageCount: 0, // pdf文件總頁數
      fileType: 'pdf', // 文件類型
      src: '', // pdf文件地址
    }
  },
  computed: {
    pdfInfo () { // 這個是路由跳轉攜帶的關於pdf的信息,包含鏈接,鏈接是可以直接打開pdf文件的
      return this.$route.query.pdfInfo
    }
  },
  created () {
    // 有時PDF文件地址會出現跨域的情況,這裏最好處理一下
     this.src = pdf.createLoadingTask(this.pdfInfo.url)
  },
  methods: {
    returnBack () {
      this.$router.push({name: 'myDownLoad'})
    },
   
    // 改變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>
<style lang="scss" scoped>
  .collect_info {
    height: 100%;
    display: flex;
    flex-direction: column;
    /*background: #f8f8f8;*/
    position: relative;
  }
  .score_header {
    text-align: center;
    letter-spacing: 0.2em;
    position: relative;
    font-size: 18px;
    width: 100%;
    background-color: rgb(0, 115, 231);
    color: #fff;
    height: 45px;
    line-height: 45px;
    flex: none;
    z-index: 1;
  }
  .return__icon{
    position: absolute;
    margin-left: 15px;
  }
  .iconfanhui {
    margin-top: 10px;
    font-size: 20px;
  }
  .pdf {
    text-align: center;
    .arrow {
      margin: 8px 0;
      /*font-size: 14px;*/
    }
    .grey {
      color: #9c9c9c;
    }
  }
</style>

pdf鏈接打開是這樣的:

2、 第二種是不分頁的不可以實現放大縮小,但是可以上下滾動

<template>
  <div class="collect_info">
    <div class="score_header">
      <div class="return__icon" @click="returnBack">
        <i class="iconfont iconfanhui"></i>
      </div>
      <div class="title">下載詳情</div>
    </div>
    <div class="pdfIn" v-show="fileType === 'pdf'" ref="pdfView">
      <div>
        <pdf
          v-for="i in numPages"
          ref="pdfs"
          :src="src"
          :key="i"
          :page="i"
        >
        </pdf>
      </div>
    </div>
  </div>
</template>

<script>
import pdf from 'vue-pdf'
import BScroll from 'better-scroll'
export default {
  metaInfo: {
    meta: [
      { name: 'viewport', content: 'width=device-width,initial-scale=1.0, maximum-scale=2.0, user-scalable=yes' }
    ]
  },
  components: {pdf},
  data () {
    return {
      fileType: 'pdf', // 文件類型
      src: '', // pdf文件地址
      numPages: 0, // 總頁數
      pdfScroll: null,
    }
  },
  computed: {
    pdfInfo () { // 路由攜帶的參數,包括pdf鏈接
      return this.$route.query.pdfInfo
    }
  },
  created () {
    // 有時PDF文件地址會出現跨域的情況,這裏最好處理一下
    this.src = pdf.createLoadingTask(this.pdfInfo.url)
    this.src.promise.then(pdf => {
      this.numPages = pdf.numPages
    })
    this.init()
  },
  methods: {
    returnBack () {
      this.$router.push({name: 'myDownLoad'})
    },
    init () {
      this.$nextTick(() => {
        this.pdfScroll = new BScroll(this.$refs.pdfView, {
          click: true
        })
      })
    },
  }
}

</script>
<style lang="scss" scoped>
  .collect_info {
    height: 100%;
    display: flex;
    flex-direction: column;
    /*background: #f8f8f8;*/
    position: relative;
  }
  .score_header {
    text-align: center;
    letter-spacing: 0.2em;
    position: relative;
    font-size: 18px;
    width: 100%;
    background-color: rgb(0, 115, 231);
    color: #fff;
    height: 45px;
    line-height: 45px;
    flex: none;
    z-index: 1;
  }
  .return__icon{
    position: absolute;
    margin-left: 15px;
  }
  .iconfanhui {
    margin-top: 10px;
    font-size: 20px;
  }
  .pdfIn {
    height: calc(100% - 50px);
    overflow: hidden;
  }
</style>

以上就是關於pdf下載和預覽的一些分享,哪裏有不對的,歡迎指正~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章