The usage process of nanny-level vue-pdf

The first step is to introduce vue-pdf

npm install --save vue-pdf

The second step is to proceed slowly according to the needs

01. Give you the url of a pdf file, which needs to be rendered on the page

Code

<template>
  <div>
    <pdf
      ref="pdf"
      :src="url">
    </pdf>
  </div>
</template>
<script>
import pdf from 'vue-pdf'
export default {
  components: {
    pdf
  },
  data() {
    return {
      url: "http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf",
    }
  }
}
</script>

This is just a first experience. If your PDF has only one page, there is no problem writing it this way, but when our PDF has many pages, you will find that this does not work. So, next, let’s take a look at how to make it display multiple pages.

02. Rendering multi-page pdf

<template>
  <div>
    <pdf v-for="i in numPages" :key="i" :src="url" :page="i"></pdf>
  </div>
</template>

<script>
import pdf from 'vue-pdf'
export default {
  components: {
    pdf
  },
  data() {
    return{
      url: '',
      numPages: 1,
      pdf: ''
    }
  },
  created() {
    this.pdf = require('vue-pdf')
    console.log('Get pdf', this.pdf)
  },
  mounted: function() {
    this.getNumPages("http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf")
  },
  methods: {
    getNumPages(url) {
      var loadingTask = pdf.createLoadingTask(url)
      // var loadingTask = this.pdf.default.createLoadingTask(url)
      loadingTask.promise.then(pdf => {
        this.url = loadingTask
        this.numPages = pdf.numPages
      }).catch((err) => {
        console.error('pdf loading failed')
      })
    },
  }
}
</script>

If you omit promise here, the console will report an error as follows

vue.runtime.esm.js:4605 [Vue warn]: Error in mounted hook: “TypeError: loadingTask.then is not a function”

You also need to understand that your vue-pdf object can be imported through import or require

Each attribute:

  • url: The path of the pdf file, which can be a local path or an online path.
  • numPages: The total number of pages in the pdf file.

getNumPages calculates the total number of pages and assigns values to url and numPages.

Note that this sentence does not have to be written in mounted. You can write it wherever you want. For example, if your front end requests the back end, and the back end returns a pdf URL, just write it there, and write it where you need it.

03. Do you want your PDF to have pagination interaction and printing functions? Direct code

<template>
  <div>
    <div class="tools" style="display: flex;justify-content: center;margin: 30px">
      <el-button :theme="'default'" type="submit" :title="'Basic Button'" @click.stop="prePage" class=" mr10">Previous page</el-button>
      <el-button :theme="'default'" type="submit" :title="'Basic Button'" @click.stop="nextPage" class=" mr10">Next page</el-button>
      <div class="page" style="margin-top: 10px">{<!-- -->{pageNum}}/{<!-- -->{pageTotalNum}} </div>
      <el-button :theme="'default'" type="submit" :title="'Basic Button'" @click.stop="clock" class=" mr10">clockwise</el-button>
      <el-button :theme="'default'" type="submit" :title="'Basic Button'" @click.stop="counterClock" class=" mr10">Counterclockwise</el-button>
    </div>
    <pdf ref="pdf"
         :src="url"
         :page="pageNum"
         :rotate="pageRotate"
         @progress="loadedRatio = $event"
         @page-loaded="pageLoaded($event)"
         @num-pages="pageTotalNum=$event"
         @error="pdfError($event)"
         @link-clicked="page = $event">
    </pdf>
  </div>
</template>
<script>
import pdf from 'vue-pdf'
export default {
  name: 'Home',
  components: {
    pdf
  },
  data() {
    return {
      url: "http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf",
      pageNum: 1,
      pageTotalNum: 1,
      pageRotate: 0,
      //Loading progress
      loadedRatio: 0,
      curPageNum: 0,
    }
  },
  mounted: function() {},
  methods: {
    // Previous page function,
    prePage() {
      var page = this.pageNum
      page = page > 1 ? page - 1 : this.pageTotalNum
      this.pageNum = page
    },
    //Next page function
    nextPage() {
      var page = this.pageNum
      page = page <this.pageTotalNum ? page + 1 : 1
      this.pageNum = page
    },
    // Flip the page 90 degrees clockwise.
    clock() {
      this.pageRotate + = 90
    },
    // Flip the page 90 degrees counterclockwise.
    counterClock() {
      this.pageRotate -= 90
    },
    // Page loading callback function, where e is the current page number
    pageLoaded(e) {
      this.curPageNum = e
    },
    // Other callback functions.
    pdfError(error) {
      console.error(error)
    },
  }
}
</script>

  • page: The number of pages currently displayed, such as the first page page=1
  • rotate: Rotation angle, for example, 0 means no rotation, +90, -90 means horizontal rotation.
  • progress: The loading progress of the current page, ranging from 0-1. When equal to 1, it means that the current page has been completely loaded.
  • page-loaded: Callback function for successful page loading, rarely used.
  • num-pages: Total number of pages
  • error: Loading error callback
  • link-clicked: The link in the stand-alone pdf will be triggered.

04. Function of loading local pdf

Install file-loader first:

npm install –save file-loader

Then add the following content to vue.config.js:

module.exports = {
    chainWebpack: config => {
        const fileRule = config.module.rule('file')
        fileRule.uses.clear()
        fileRule
            .test(/\.pdf|ico$/)
            .use('file-loader')
            .loader('file-loader')
            .options({
                limit: 10000,
            })
    },
    publicPath: './'
}

After that, there will be no problem if url:require("../assets/1.pdf") is used. Note that vue-pdf src receives string objects. If you pass the url directly to me, If an error is reported, you may need to pass url.default.

Others

Print interface characters are garbled:

I encountered this. When printing on Google Chrome, the preview interface really turned into “real square characters”, all squares. This problem is caused by the use of custom fonts in your PDF. The specific solution is as follows:

First, find this file: node_modules/vue-pdf/src/pdfjsWrapper.js

Then according to this issue on github, the red ones need to be deleted, and the green ones need to be added. You can solve it by changing them accordingly.

Address: github.com/FranckFreib…

According to my actual test, the problem of printing garbled characters can be solved.

Cross-domain issues:

Many people who use pdf.js on the Internet will encounter cross-domain problems. I actually applied this to my project today. Since I have set up cross-domain on the server, there are no cross-domain problems. If cross-domain occurs, you need to modify it. request header.

It’s time to get off work as I write this. Thank you fellow veterans for your likes. Your likes are the motivation for me to work hard and improve.