Vue: pdf.js usage details/hidden button/settings, get current page number/record reading progress/switch language (internationalization)

Description of Requirement

When previewing the pdf on the web page, I hope to achieve three requirements: 1. Hide some function buttons (such as download); 2. Automatically locate the last page browsed when opening the pdf (record reading progress); 3. Realize internationalization (in the code to change the language used by the pdf plugin).
The above requirements are difficult to achieve using the pdf plug-in that comes with Chrome. After research, we decided to use pdf.js to achieve.

Use pdf.js in vue project

This part of the content can be referred to: Use pdf.js to preview pdf files in the vue project . The original vue-pdf.js-demo is very valuable~

Here is a record of a pit that this miscellaneous fish stepped on when introducing pdf.js into the project: use iframe to load the HTML file under the public folder of the project, you can refer to the vue-public folder .
The pdf.js file introduced under the project public (copied from vue-pdf.js-demo):
Import pdf.js related files
If the project warehouse has eslint checks, remember to add this line of code at the beginning of all .js files under pdfjs to avoid eslint detection errors:

/* eslint-disable */

requesting research

This paragraph records in detail the process of this miscellaneous fish to achieve these three requirements.Friends who only need to refer to the code can go straight to the end of the article to pick it up~

hide button

After using pdf.js to preview pdf in vue, start to deal with additional requirements, starting with the hidden function button; taking the hidden download button as an example, F12 finds the id (download) of the download button, as shown in the figure below: Then go to the viewer
Find the download button
. Search for "download" in js to find the code for setting configuration items, as shown in the figure below:
Search configuration items
Search for the configuration item name "PDFViewerApplication" in viewer.js, and you can see that it is mounted on the window object:
window.PDFViewerApplication
preview in a new tab pdf, print out the window object (window) of the web page on the console:
The new tab page prints the window object
preview the pdf in the iframe, print out the window object of the iframe on the console (document.getElementById("iframe id").contentWindow):
iframe print window object
refer to viewer.js The configuration item, modify the corresponding configuration directly in the console to hide the download button:
PS: To redisplay the hidden button, setAttribute("hidden", false) is invalid, and removeAttribute("hidden") is required
hide download button

Set and get the current page number (record reading progress)

To automatically locate the last page number when opening the pdf, two things need to be done: 1. When the current page number of the pdf changes, obtain and record the page number; 2. When the pdf is reopened, the current page number is set to the last saved page number. With the number of pages read, and the total number of pages in the pdf, the reading progress can be calculated naturally~
Emm... To be honest, this has a component of luck of a million points. This miscellaneous fish is flipping through the window. When viewing the properties of the pdf, I saw these two items:
PDFViewerApplication configuration item
After observation, PDFViewerApplication.page is the current page number, and PDFViewerApplication.pagesCount is the total number of pages in the pdf~ In addition, have you found out that the result of printing these two data is ( ...), the same is true for printing the two-way bound data in data in vue! Therefore, you can directly modify the value of PDFViewerApplication.page to achieve page jumping:
jump page
when the page number changes, the pdf container must scroll, so you only need to monitor the scrolling of the container; you can achieve anti-shake by recording and judging whether the page number has changed.
When using viewer.html in the demo to load pdf, the container id is viewerContainer:
pdf container id

Switch Language (Internationalization)

First try to switch the language of the browser, and observe that the display language of the pdf.js plug-in will change with the browser language (only tried Simplified Chinese and English): So there must be a
switch browser language
code to obtain the browser language (navigator.language) in viewer.js , search out such a configuration item:
language configuration
So continue to search for ".locale" in viewer.js, and find such a function:
initialization language
You can see that viewer.js will get the locale configuration item from the hash of the pdf file link (that is, you need language used) value! But pay attention to the judgment statement at the beginning of the function, you also needOpen the pdfBugEnabled configurationIn order to customize the language, search for pdfBugEnabled in viewer.js, and change its assignment to true:
Open the configuration switch
Is this enough? NONONO, you also need to introduce the corresponding language pack:
first pull pdf.js , you can see a "l10n" folder, which stores various language packs; copy the language pack to be used to the web.locale folder, And just import the files in the package in locale.properties (the official website does not have the en language package, here is to modify the folder name after copying the en-US package): Of course, don’t forget the hash of the link in the pdf file at the
import language pack
end Add the locale parameter in Oh!
Add hash parameter locale

Reference Code

First, you need to obtain the demo provided by this blog using pdf.js to preview pdf files in the vue project : vue-pdf.js-demo, and then copy the required files to the public of your own project, you can refer to the screenshot at the beginning of the article; finally create a new pdfViewer.vue in the project, the content is as follows:

<!--
 * @Author: shenmingming
 * @Date: 2023-02-23 09:45:00
 * @LastEditors: shenmingming
 * @LastEditTime: 2023-02-24 10:48:19
 * @Description: 封装pdf.js插件
-->
<template>
  <div
    v-loading="pdfLoading"
    class="pdf-viewer"
  >
    <!-- 这里加载的pdf是接口返回网址的格式,filePath格式:https://IP/路径/文件名.pdf?token=XXX -->
    <!-- 如果需要使用其他方式加载pdf,请参考vue-pdf.js-demo中的HelloWorld.vue -->
    <iframe
      id="pdf-iframe"
      :src="`${publicPath}/pdfjs/web/viewer.html?file=${encodeURIComponent(filePath)}#toolbar=0&locale=${localLan}`"
      frameborder="0"
    />
  </div>
</template>

<script>
export default {
  name: 'PdfViewer',
  props: {
    filePath: { // 文件网址
      type: String,
      default: () => ''
    },
    initPage: { // 初始页码
      type: Number,
      default: () => 1
    },
    hideBtns: { // 隐藏的pdf功能按钮
      type: Array,
      default: () => [`openFile`, `print`, `download`, `viewBookmark`, `toggle`]
    },
    localLan: { // 语言(默认简中)
      type: String,
      default: () => 'zh-CN'
    },
  },
  data () {
    return {
      publicPath: process.env.BASE_URL || `/`,
      interval: null, // 轮询pdf加载状态定时器
      pdfPageNow: this.initPage, // pdf当前页码
      pdfLoading: true, // 是否显示加载效果
      reloadTime: 50 // 检测加载状态50次未加载成功(15s),判断为加载失败
    }
  },
  mounted () {
    // 每300ms判断pdf加载状态,直到加载完成
    this.interval = setInterval(this.checkPdf, 300)
  },
  methods: {
    checkPdf () { // 轮询pdf文件加载状态
      if (!document.getElementById('pdf-iframe') || this.reloadTime-- < 1) { // 加载失败
        clearInterval(this.interval)
        return
      }

      let pdfFrame = document.getElementById('pdf-iframe').contentWindow
      let maxNum = pdfFrame.document.getElementById('pageNumber').getAttribute('max')
      if (maxNum == 0 || maxNum == undefined) { // 直接获取页面显示的总页数,获取到了说明加载完成
        console.info('Loading...')
      } else {
        clearInterval(this.interval)
        this.hidePdfBtns()
        pdfFrame.PDFViewerApplication.page = this.pdfPageNow // pdf跳页
        this.pdfLoading = false
        if (maxNum < 2) { // 只有一页的pdf,进度更新为100%
          console.log(`1/1, prog:100%`)
        } else {
          pdfFrame.document.getElementById('viewerContainer') // 监听pdf滚动事件
            .addEventListener('scroll', e => {
              let pdfInfo = pdfFrame.PDFViewerApplication
              if (this.pdfPageNow !== pdfInfo.page) { // 防抖:当前页变化时,更新进度
                this.pdfPageNow = pdfInfo.page
                console.log(`${pdfInfo.page}/${pdfInfo.pagesCount}, prog:${parseInt(pdfInfo.page / pdfInfo.pagesCount)}%`)
              }
            })
        }
      }
    },
    hidePdfBtns () { // 隐藏pdf功能按钮
      let pdfConfig = document.getElementById('pdf-iframe').contentWindow.PDFViewerApplication.appConfig
      this.hideBtns.forEach(btn => {
        if (pdfConfig.toolbar[btn]) pdfConfig.toolbar[btn].hidden = true
        if (pdfConfig.secondaryToolbar[`${btn}Button`]) pdfConfig.secondaryToolbar[`${btn}Button`].hidden = true
      })
    }
  }
}
</script>

<style scoped>
.pdf-viewer,
iframe {
  width: 100%;
  height: 100%;
}
</style>

have to be aware of is:

1. The pdf loaded by this reference code is the format of the URL returned by the interface. The filePath format is similar to "https://IP/path/filename.pdf?token=XXX". If you need to use other methods to load pdf, please refer to vue- HelloWorld.vue in pdf.js-demo;
2. To switch languages ​​(internationalization), you also need to turn on the configuration switch in viewer.js and import the corresponding language pack into the project. For details, please refer to the requirement research section

Finally, call the pdfViewer component where needed, and debug it as needed~★▼★~

reference documents

[1] pdf.js
[2] Use pdf.js to preview pdf files in vue project
[3] vue-public folder
[4] hash (location.hash details)

Guess you like

Origin blog.csdn.net/qq_36604536/article/details/129184357