本文使用的是 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下载和预览的一些分享,哪里有不对的,欢迎指正~

Logo

前往低代码交流专区

更多推荐