vue component vue pdf encountered the problem that the content replaced by gnawing and loading pdf is not displayed

Keywords: Javascript node.js Vue Vue.js

Recently done mobile terminal project, packaging PDF Preview component, colleagues started using vue-pdf To preview and step on the pit again and again, we basically encounter three problems:
1,PDF Chinese not displayed
2,PDF If the signature is not displayed, the console prompts: Warning: Unimplemented widget field type "Sig", falling back to base field type
3,Second opening PDF I'll meet you when I'm young PDF Blank question, console prompt: Error during font loading: Failed to execute 'postMessage' on 'Worker': ArrayBuffer at index 0 is already detached

For problem 1, we all do the same. We solve the problem by introducing CMapReaderFactory.js:

import CMapReaderFactory from 'vue-pdf/src/CMapReaderFactory.js'

    this.src = pdf.createLoadingTask({
      url: this.pdfUrl,
      CMapReaderFactory
    });

The introduction of CMapReaderFactory.js does solve problem 1, but it will also cause problem 3. Let's talk about this after problem 2.

For problem 2, there are many solutions online. Vue PDF actually integrates the implementation of pdfJS. Generally, the problem can be solved by commenting the code in pdfJS and opening the signature. Refer to http://www.zyiz.net/tech/detail-129606.html :

//pdf.worker.js

if (data.fieldType === 'Sig') {

  data.fieldValue = null;

    //Just comment on this line of code

  //_this3.setFlags(_util.AnnotationFlag.HIDDEN);

}

For question 3, it was mentioned earlier that CMapReaderFactory was introduced. If you enter the code breakpoint, you will find that his code is written as follows:

import { CMapCompressionType } from 'pdfjs-dist/build/pdf.js'

// see https://github.com/mozilla/pdf.js/blob/628e70fbb5dea3b9066aa5c34cca70aaafef8db2/src/display/dom_utils.js#L64

export default function() {    this.fetch = async function(query) {
        
        /* webpackChunkName: "noprefetch-[request]" */
        return import('./buffer-loader!pdfjs-dist/cmaps/'+query.name+'.bcmap')
        .then(function(bcmap) {

            return {
                cMapData: bcmap.default,
                compressionType: CMapCompressionType.BINARY,
            };
        });
    }
};

This code solves the problem of Chinese display by dynamically importing PDF language files. However, when you load PDF for the second time, you will find that the loaded page is a blank page. After debugging for a day, I found that when you load PDF for the first time, the return value of bcmap is the array object of Uint8Array[43366], During the second preview of PDF loading, it is found that the return value of bcmap is an empty array of Uint8Array []. The breakpoint can't be seen clearly after looking at it. However, it can be guessed that it is due to the cache problem. During the second loading, the cache of loadModules of the language file when the PDF file is loaded for the first time is taken, but the fetching process leads to failure and returns a null value, The solution to the problem is actually a line of code:

import { CMapCompressionType } from 'pdfjs-dist-sign/build/pdf.js'

// see https://github.com/mozilla/pdf.js/blob/628e70fbb5dea3b9066aa5c34cca70aaafef8db2/src/display/dom_utils.js#L64

export default function() {    this.fetch = async function(query) {
        /* webpackChunkName: "noprefetch-[request]" */
        return import('./buffer-loader!pdfjs-dist-sign/cmaps/'+query.name+'.bcmap').then(function(bcmap) {

            //Clear the cache after loading the language file

            delete require.cache[require.resolve('./buffer-loader!pdfjs-dist-sign/cmaps/'+query.name+'.bcmap')];

            return {
                cMapData: bcmap.default,
                compressionType: CMapCompressionType.BINARY,
            };
        });
    }
};

You can load the Preview PDF many times by deleting the require cache, but this is the source code of other plug-ins. You have changed it locally. Other partners don't know. What should we do? My solution is to add cache clearing code to my encapsulated PDF component:

that.src = pdf.createLoadingTask({
  url: this.pdfUrl,
  CMapReaderFactory
});
//Clear the cache after loading the PDF
for(var key in require.cache) {
  if(key.indexOf('bcmap') >= 0) {
    delete require.cache[key];
  }
}

It is feasible to try the above method locally, but it is not feasible to deploy it on the server. After debugging, it is found that it is because the file name is compressed into an alias when the webpack is packaged, which makes it impossible to delete the require d cache according to the file name. There is no way but to fork a branch in the github of Vue PDF and clone it for local adjustment, Then publish it to npm. If you are lazy, you can directly use Vue PDF signature package to replace Vue PDF. This is my modified version of Vue PDF. If you want to do it yourself, change the reference to PDF dist into the reference to PDF dist sign, add the code to clean the cache, and then send an npm package.


    //Replace Vue pdf

    npm install --save vue-pdf-signature

Posted by julian1 on Sun, 19 Sep 2021 11:42:45 -0700