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