The other day the test girl told me, why doesn’t this PDF open in IE? Then I took a peek:

This browser does not support inline PDFs. Please download the PDF to view it: Download PDF
Copy the code

I haven’t had much experience with PDF online reading, this is an old project, and then I went to see what kind of INCOMPATIBLE PDF online reading plug-in these guys were using, and I found that it was PDFObject, and PDFObject doesn’t support rendering PDF in browsers without PDF renderers. Let’s download an Adobe Reader! And so on… Do I have to remind every customer to download this Reader? Won’t customer psychology be MMP?

Here,
pdf.js

You can also use PDF.js to force PDF rendering in-browser without a plugin, but that’s outside the scope of PDFObject.

Learn something new, start with a demo

1. Install PDF. Js

This demo is created using vue-CLI

  • Source code installation, download the source code directly from the official website
  • You can use the CDN in the following ways

www.jsdelivr.com/package/npm… Cdnjs.com/libraries/p… unpkg.com/pdfjs-dist/

  • Use the pre-built version and download it from NPM
npm i pdfjs-dist
Copy the code

or

yarn add pdfjs-dist
Copy the code

2. Use it in vUE

import PDFJS from 'pdfjs-dist';

PDFJS.GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker.js';
Copy the code

In order to improve the performance of parsing and rendering PDF, PDF.js introduces Web Workers

PDFJs renders PDF content to the browser via canvas, so we need to add a canvas to our HTML

<canvas id="the-canvas" style="border:1px solid black"></canvas>
Copy the code

However, the PDF rendered in this way can not be selected, what to do?

Get the PDF content using getTextContent and then use TextLayerBuilder to render the content on top of the Canvas layer

Get a PDFDocumentLoadingTask by calling pdfjs.getDocument.

GetDocument (SRC) →{PDFDocumentLoadingTask}

SRC types can string | TypedArray | DocumentInitParameters | PDFDataRangeTransport, here we directly use type string, the PDF of the url string

This method returns a PDFDocumentLoadingTask, but it can still be used as a promise. The source code is shown below, and a Promise object is returned when pdF.then is called.

  class PDFDocumentLoadingTask {
    /* omit some code */
    /** * @return {Promise} */
    get promise() {
      return this._capability.promise;
    }

    then(onFulfilled, onRejected) {
      deprecated('PDFDocumentLoadingTask.then method, ' +
                 'use the `promise` getter instead.');
      return this.promise.then.apply(this.promise, arguments); }}Copy the code

After getting the PDFDocumentLoadingTask, get the PDF of the current page based on the PDF page number

letPDF = await pdfjs.getDocument (url) // Url is a link to PDFletPage = await pdf.getPage(num) // num is the page number, e.g. 1Copy the code

Set the page size of the PDf document (display scale)

letScale = 1.5;let viewport = page.getViewport(scale);
Copy the code

Rendering PDF

let renderContext = {
    canvasContext: context, // This is the Canvas context
    viewport: viewport
};
        
await page.render(renderContext); // await is used to render the PDF text later
Copy the code

Then take the PDF content and render it into text

lettextContent = await page.getTextContent() /* ... Var textLayer = new TextLayerBuilder({textLayerDiv: textLayerDiv, dom pageIndex); Page. PageIndex, // PDF page number viewPort: viewPort}); textLayer.setTextContent(textContent); textLayer.render();Copy the code

The complete code is as follows, then it is time to show CV method, can refer to example

Blah blah blah…

import PDFJS from "pdfjs-dist";
import { TextLayerBuilder } from "pdfjs-dist/web/pdf_viewer";
import "pdfjs-dist/web/pdf_viewer.css";
PDFJS.GlobalWorkerOptions.workerSrc = "pdfjs-dist/build/pdf.worker.js";

var container;
export default {
  name: "HelloWorld".props: {
    msg: String
  },
  mounted() {
    this.$nextTick((a)= > {
        let url =
        "http://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf";
        this.getPDF(url);
    });
  },
  methods: {
    async getPDF(url) {
        let pdf = await PDFJS.getDocument(url)
        container = container || document.querySelector('#container')
        for(let i = 0; i < pdf.numPages; i++) {
            try{
                await this.rendPDF(pdf, i)
            } catch(e) {
                // console.error(e)}}},async renderPDF(pdf, num) {
        let page = await pdf.getPage(num)
        // Set the display scale
        let scale = 1.5;
        let viewport = page.getViewport(scale);

        let pageDiv = document.createElement('div');
        pageDiv.setAttribute('id'.'page-' + (page.pageIndex + 1));
        pageDiv.setAttribute('style'.'position: relative');
        container.appendChild(pageDiv);

        let canvas = document.createElement('canvas');
        pageDiv.appendChild(canvas);
        let context = canvas.getContext('2d');
        canvas.height = viewport.height;
        canvas.width = viewport.width;
        
        let renderContext = {
            canvasContext: context,
            viewport: viewport
        };
        
        await page.render(renderContext);
        let textContent = await page.getTextContent()
        // Create the text layer div
        const textLayerDiv = document.createElement('div');
        textLayerDiv.setAttribute('class'.'textLayer');
        textLayerDiv.setAttribute('style'.`width: ${viewport.width}px; margin: 0 auto; `)
        // Add the text layer div to each PDF page div
        pageDiv.appendChild(textLayerDiv);
        
        // Create a new TextLayerBuilder instance
        var textLayer = new TextLayerBuilder({
            textLayerDiv: textLayerDiv,
            pageIndex: page.pageIndex,
            viewport: viewport }); textLayer.setTextContent(textContent); textLayer.render(); }}};Copy the code

Effect of 3.



The demo address