Received a mobile web page PDF preview demand, the first thought of the solution is to use iframe to display. Backend response header Settings

Content-Disposition: inline
Copy the code

Content-Disposition

There are generally the following cases

Content-disposition: Inline // attachment means that the body of the message should be downloaded locally; content-disposition: Inline // attachment means that the body of the message should be downloaded locally. Most browsers display a "save as" dialog box content-disposition: attachment // filename the filename after downloading content-disposition: attachment; filename="filename.jpg"Copy the code

In normal thinking, the PDF content should be displayed in the IFrame. When tested in the PC simulator, everything was as expected. But when it comes to mobile browsers, things are different.

Safari on the iPhone, wechat, and wechat’s browser for enterprises are all in line with expectations. For Android phones (Huawei Mate9), the PDF is opened in a new window in the built-in browser of wechat. Both the built-in browser of wechat and the built-in browser of mobile phones prompt you to download.

The effect is inconsistent with the requirements

pdf.js

Introduction to the

Pdf.js is a portable document format (PDF) viewer built using HTML5.

Pdf.js is community-driven and supported by Mozilla. The goal is to create a common platform based on Web standards for parsing and rendering PDFS.

PDFJS provides a package called PDFJs-dist in the NPM repository.

The introduction of PFDJS

const PDFJS = require("@/pdfjs-dist");
const workerSrc = require("@/pdfjs-dist/es5/build/pdf.worker.entry.js");
PDFJS.GlobalWorkerOptions.workerSrc = workerSrc;
Copy the code

Download the PDF

Const CMAP_URL = "https://unpkg.com/[email protected]/cmaps/"; const loadingTask: any = PDFJS.getDocument({ url: this.pdfUrl, cMapUrl: CMAP_URL, cMapPacked: true, withCredentials: true, }); Loadingtask.promise.then ((pdfDoc_) => {// Get the PDF and save it for the next display}). Catch ((error: any) => {});Copy the code

Gets the content of a page

this.pdfDoc
    .getPage(num)
    .then(
      (page: any) => {
        const viewport = page.getViewport({ scale: 1 });

        canvas.height = viewport.height;
        canvas.width = viewport.width;
        canvas.style.width = "100%";
        
        const renderContext = {
          canvasContext,
          viewport: viewport,
        };
        page.render(renderContext);
      }
    )
    .catch((e: any) => {
      console.info(e);
    });
Copy the code

The problem

  • PDF display blur

    On a high resolution screen, the PDF may not display well. This is the canvas property setting width/height to refer to physical pixels. If devicePixelRatio is 2, that means one CSS pixel equals two physical pixels. According to the above Settings, the CSS width value of canvas is the same as the physical pixel value of canvas, which will cause the canvas to be enlarged and the display becomes blurred. Therefore, according to the screen pixel ratio, set the value of scale, so that devices with different resolutions can get a clear experience effect.

  • Some fonts in PDF are not displayed

Const CMAP_URL = “https://unpkg.com/[email protected]/cmaps/”; // Const loadingTask: any = pdfjs.getDocument ({url: this. PdfUrl, cMapUrl: CMAP_URL, cMapPacked: true, withCredentials: true, });

  • The seal is not displayed

Manually modify the source code because the library author for security reasons, if the Sig type, will be hidden, so, you can not expect the author to release. You can only do it yourself. pdf.worker.js

Download the PDF

The performance is still inconsistent across browsers

In WeChat

First show an induced download QQ browser page, need to choose [other ways to download], more than a step, fortunately, can achieve download

In the enterprise wechat

Download and preview directly

In your own browser