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