UNPKG

pdfjs-vue-print

Version:

Example Vue 3 project using pdf.js to build a simple custom PDF.js viewer and print service.

282 lines (239 loc) 7.32 kB
/* Copyright 2016 Mozilla Foundation * Copyright 2022 Drew Letcher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ "use strict"; import * as pdfjsLib from "pdfjs-dist/build/pdf.js" import * as pdfjsViewer from "pdfjs-dist/web/pdf_viewer.js" if (!pdfjsLib.getDocument || !pdfjsViewer.PDFViewer) { // eslint-disable-next-line no-alert alert("Please build the pdfjs-dist library using\n `gulp dist-install`"); } pdfjsLib.GlobalWorkerOptions.workerSrc = "../../node_modules/pdfjs-dist/build/pdf.worker.js"; const USE_ONLY_CSS_ZOOM = true; const TEXT_LAYER_MODE = 0; // DISABLE const MAX_IMAGE_SIZE = 1024 * 1024; const CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/"; const CMAP_PACKED = true; const DEFAULT_SCALE_DELTA = 1.1; const MIN_SCALE = 0.25; const MAX_SCALE = 10.0; const DEFAULT_SCALE_VALUE = "auto"; const ENABLE_XFA = false; export default class PDFViewerApp { constructor(options) { this.options = options; this.viewerContainer = options.viewerContainer || null; this.password = options.password || ""; this.eventBus = null; this._boundEvents = {}; this.l10n = pdfjsViewer.NullL10n; this.pdfViewer = null; this.pdfDocument = null; this.pdfLoadingTask = null; this.url = ""; this.documentInfo = null; this.metadata = null; } /** * * @returns */ createViewer() { console.log("createViewer"); this.eventBus = new pdfjsViewer.EventBus(); const pdfViewer = new pdfjsViewer.PDFViewer({ container: this.viewerContainer, eventBus: this.eventBus, l10n: this.l10n, useOnlyCssZoom: USE_ONLY_CSS_ZOOM, textLayerMode: TEXT_LAYER_MODE, }); this.pdfViewer = pdfViewer; this.eventBus.on("pagesinit", () => { // We can use pdfViewer now, e.g. let's change default scale. pdfViewer.currentScaleValue = "page-actual"; }); } /** * Add event handler to PDFViewer's eventbus * * @param {*} name PDFViewer event name * @param {*} fn (event) => {} */ on(name, fn) { this.eventBus.on(name, fn); } /** * Opens PDF document specified by URL. */ async open(params) { console.log("open"); if (this.pdfLoadingTask) { // We need to destroy already opened document await this.close() } let self = this; const url = params.url; this.setTitleUsingUrl(url); // Loading document const loadingTask = pdfjsLib.getDocument({ url, cMapUrl: CMAP_URL, cMapPacked: CMAP_PACKED, maxImageSize: MAX_IMAGE_SIZE, enableXfa: ENABLE_XFA, }); this.pdfLoadingTask = loadingTask; let pdfPassword = this.password; loadingTask.onPassword = (callback, reason) => { console.log("onPassword: " + reason) callback(pdfPassword) } loadingTask.onProgress = function (progressData) { self.progress(progressData.loaded / progressData.total); }; const pdfDocument = await loadingTask.promise // Document loaded, specifying document for the viewer. this.pdfDocument = pdfDocument; console.log("pdfViewer.setDocument") this.pdfViewer.setDocument(pdfDocument); self.loadingBar.hide(); this.setTitleUsingMetadata(pdfDocument); /* catch((error) => { const message = error && error.message; console.log(message); const l10n = this.l10n; let loadingErrorMessage; if (error instanceof pdfjsLib.InvalidPDFException) { // change error message also for other builds loadingErrorMessage = l10n.get( "invalid_file_error", null, "Invalid or corrupted PDF file." ); } else if (error instanceof pdfjsLib.MissingPDFException) { // special message for missing PDFs loadingErrorMessage = l10n.get( "missing_file_error", null, "Missing PDF file." ); } else if (error instanceof pdfjsLib.UnexpectedResponseException) { loadingErrorMessage = l10n.get( "unexpected_response_error", null, "Unexpected server response." ); } else { loadingErrorMessage = l10n.get( "loading_error", null, "An error occurred while loading the PDF." ); } loadingErrorMessage.then((msg) => { console.log(msg); error.moreInfo = msg; throw (error); }); self.loadingBar.hide(); }) */ } /** * Closes opened PDF document * @returns {Promise} - Returns the promise, which is resolved when all * destruction is completed. */ async close() { console.log("close"); if (!this.pdfLoadingTask) { return; } await this.pdfLoadingTask.destroy(); this.pdfLoadingTask = null; if (this.pdfDocument) { this.pdfDocument = null; this.pdfViewer.setDocument(null); } } get loadingBar() { const bar = new pdfjsViewer.ProgressBar("loadingBar"); return pdfjsLib.shadow(this, "loadingBar", bar); } progress(level) { const percent = Math.round(level * 100); // Updating the bar if value increases. if (percent > this.loadingBar.percent || isNaN(percent)) { this.loadingBar.percent = percent; } } setTitle(title) { document.title = title; } setTitleUsingUrl (url) { this.url = url; let title = pdfjsLib.getFilenameFromUrl(url) || url; try { title = decodeURIComponent(title); } catch (e) { // decodeURIComponent may throw URIError, // fall back to using the unprocessed url in that case } this.setTitle(title); } setTitleUsingMetadata(pdfDocument) { const self = this; pdfDocument.getMetadata() .then((data) => { const info = data.info; const metadata = data.metadata; self.documentInfo = info; self.metadata = metadata; // Provides some basic debug information console.log( "PDF " + pdfDocument.fingerprints[0] + " [" + info.PDFFormatVersion + " " + (info.Producer || "-").trim() + " / " + (info.Creator || "-").trim() + "]" + " (PDF.js: " + (pdfjsLib.version || "-") + ")" ); let pdfTitle; if (metadata && metadata.has("dc:title")) { const title = metadata.get("dc:title"); // Ghostscript sometimes returns 'Untitled', so prevent setting the // title to 'Untitled. if (title !== "Untitled") { pdfTitle = title; } } if (!pdfTitle && info && info.Title) { pdfTitle = info.Title; } if (pdfTitle) { self.setTitle(pdfTitle + " - " + document.title); } }); } }; export { PDFViewerApp };