UNPKG

pdfdataextract

Version:

Extract data from a pdf with pure javascript

275 lines 12 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.PdfDataExtractor = void 0; const pdf_mjs_1 = require("pdfjs-dist/legacy/build/pdf.mjs"); const pdfpagedata_1 = require("./pdfpagedata"); const types_1 = require("./types"); async function getPageNumber(pdf_document, pageRef, cache) { const ref = pageRef.gen === 0 ? `${pageRef.num}R` : `${pageRef.num}R${pageRef.gen}`; let number = cache[ref]; if (number == null) { number = await pdf_document.getPageIndex(pageRef); cache[ref] = number; } return number; } function parseRemoteUrlDest(remoteUrlDest) { try { const remoteDest = JSON.parse(remoteUrlDest); if (Array.isArray(remoteDest) && Number.isInteger(remoteDest[0])) { return remoteDest[0]; } } catch (_a) { } return undefined; } async function parseOutline(pdf_document, outlineData, cache) { const outline = []; for (const o of outlineData) { const dest = typeof (o.dest) === 'string' ? await pdf_document.getDestination(o.dest) : o.dest; if (dest == null) { if (o.unsafeUrl != null) { if (o.url == null) { const remoteUrl = o.unsafeUrl.split('#', 2); const remoteBaseUrl = remoteUrl[0]; if (remoteBaseUrl.toLowerCase().endsWith('.pdf')) { if (remoteUrl.length == 2) { outline.push(new types_1.PdfReferenceOutline(o.title, remoteBaseUrl, parseRemoteUrlDest(remoteUrl[1]), o.items ? await parseOutline(pdf_document, o.items, cache) : undefined)); } else { outline.push(new types_1.PdfReferenceOutline(o.title, remoteBaseUrl, undefined, o.items ? await parseOutline(pdf_document, o.items, cache) : undefined)); } } else { outline.push(new types_1.UrlOutline(o.title, o.unsafeUrl, false, o.items ? await parseOutline(pdf_document, o.items, cache) : undefined)); } } else { outline.push(new types_1.UrlOutline(o.title, o.url, true, o.items ? await parseOutline(pdf_document, o.items, cache) : undefined)); } } else { // TODO: ? } } else if (Array.isArray(dest)) { if (typeof dest[0] === 'object') { outline.push(new types_1.PageNumberOutline(o.title, await getPageNumber(pdf_document, dest[0], cache), o.items ? await parseOutline(pdf_document, o.items, cache) : undefined)); } else if (Number.isInteger(dest[0])) { outline.push(new types_1.PageNumberOutline(o.title, dest[0], o.items ? await parseOutline(pdf_document, o.items, cache) : undefined)); } else { // TODO: ? } } } return outline; } async function getInstalledCanvasApi() { try { require.resolve('canvas'); return (await Promise.resolve().then(() => __importStar(require('./nodecanvas')))).NodeCanvas; } catch (_e) { } try { require.resolve('@napi-rs/canvas'); return (await Promise.resolve().then(() => __importStar(require('./nodeskiacanvas')))).NodeSkiaCanvas; } catch (_e) { } try { require.resolve('pureimage'); return (await Promise.resolve().then(() => __importStar(require('./pureimagecanvas')))).PureimageCanvas; } catch (_e) { } return null; } async function getInstalledOcrApi() { try { require.resolve('tesseract.js'); return (await Promise.resolve().then(() => __importStar(require('./tesseractjsocr')))).TesseractJsOcr; } catch (_e) { } return null; } /** * the extractor for the data of the pdf */ class PdfDataExtractor { constructor(pdf_document, canvasApi, ocrApi) { this.pdf_document = pdf_document; this.canvasApi = canvasApi; this.ocrApi = ocrApi; } /** * get the extractor for the data * * @param {Uint8Array} data - the binary data file * @param {PdfDataExtractorOptions} [options={}] - the options on how to open the data in the extractor * @returns {Promise<PdfDataExtractor>} a promise that is resolved with a {PdfDataExtractor} object to pull the extracted data from */ static async get(data, options = {}) { var _a, _b, _c; if (data instanceof Buffer) { data = new Uint8Array(data); } const pdf_document = await (0, pdf_mjs_1.getDocument)({ data: data, password: options.password, verbosity: (_a = options.verbosity) !== null && _a !== void 0 ? _a : types_1.VerbosityLevel.ERRORS, isEvalSupported: false, }).promise; return new PdfDataExtractor(pdf_document, (_b = options.canvasApi) !== null && _b !== void 0 ? _b : await getInstalledCanvasApi(), (_c = options.ocrApi) !== null && _c !== void 0 ? _c : await getInstalledOcrApi()); } /** * get the fingerprint * * @returns {string | null} the fingerprint */ get fingerprint() { return this.pdf_document.fingerprints[0]; } /** * get the number of pages * * @returns {string} the number of pages */ get pages() { return this.pdf_document.numPages; } /** * get the permission flags * * @returns {Promise<Permissions | null>} a promise that is resolved with a {Permissions | null} object that contains the permission flags for the PDF */ async getPermissions() { const permission_flag_array = await this.pdf_document.getPermissions(); return permission_flag_array == null ? null : { assemble: permission_flag_array.includes(pdf_mjs_1.PermissionFlag.ASSEMBLE), copy: permission_flag_array.includes(pdf_mjs_1.PermissionFlag.COPY), copyForAccessibility: permission_flag_array.includes(pdf_mjs_1.PermissionFlag.COPY_FOR_ACCESSIBILITY), fillInteractiveForms: permission_flag_array.includes(pdf_mjs_1.PermissionFlag.FILL_INTERACTIVE_FORMS), modifyAnnotations: permission_flag_array.includes(pdf_mjs_1.PermissionFlag.MODIFY_ANNOTATIONS), print: permission_flag_array.includes(pdf_mjs_1.PermissionFlag.PRINT), printHQ: permission_flag_array.includes(pdf_mjs_1.PermissionFlag.PRINT_HIGH_QUALITY), modifyContents: permission_flag_array.includes(pdf_mjs_1.PermissionFlag.MODIFY_CONTENTS), }; } /** * get the text * * @param {number|number[]|((pageNumber: number) => boolean)} [pages] - can either be the number of pages to be read, * a number array with the specific pages (sorted by page number) * or a filter function (return true to parse the page) * @param {boolean|Sort} [sort=false] - sort the text by text coordinates * @returns {Promise<string[]>} a promise that is resolved with a {string[]} array with the extracted text per page */ async getText(pages, sort = false) { return Promise.all((await this.getPageData(pages)).map(async (page) => page == null ? '' : page.toText(sort))); } /** * get the text * * @param {number|number[]|((pageNumber: number) => boolean)} [pages] - can either be the number of pages to be read, * a number array with the specific pages (sorted by page number) * or a filter function (return true to parse the page) * @returns {Promise<string[]>} a promise that is resolved with a {string[]} array with the extracted text per page */ async getPageData(pages) { const page_array = []; const numPages = this.pdf_document.numPages; if (pages === undefined) { for (let pageNumber = 1; pageNumber <= numPages; pageNumber++) { const page = await this.pdf_document.getPage(pageNumber).catch(() => null); page_array.push(page == null ? null : new pdfpagedata_1.PdfPageData(page, this.canvasApi, this.ocrApi)); } } else if (typeof (pages) === 'number') { const counter = pages > numPages ? numPages : pages; for (let pageNumber = 1; pageNumber <= counter; pageNumber++) { const page = await this.pdf_document.getPage(pageNumber).catch(() => null); page_array.push(page == null ? null : new pdfpagedata_1.PdfPageData(page, this.canvasApi, this.ocrApi)); } } else if (typeof (pages) === 'function') { for (let pageNumber = 1; pageNumber <= numPages; pageNumber++) { if (pages(pageNumber)) { const page = await this.pdf_document.getPage(pageNumber).catch(() => null); page_array.push(page == null ? null : new pdfpagedata_1.PdfPageData(page, this.canvasApi, this.ocrApi)); } } } else { pages = pages.filter((value, index, self) => self.indexOf(value) === index).sort((a, b) => a - b); for (const pageNumber of pages) { if (pageNumber <= numPages) { const page = await this.pdf_document.getPage(pageNumber).catch(() => null); page_array.push(page == null ? null : new pdfpagedata_1.PdfPageData(page, this.canvasApi, this.ocrApi)); } } } return page_array; } /** * get the outline/bookmarks * * @returns {Promise<Outline[]>} a promise that is resolved with a {Outline[]} array with information from the tree outline */ async getOutline() { const outlineData = await this.pdf_document.getOutline(); if (outlineData == null) return null; return parseOutline(this.pdf_document, outlineData, {}); } /** * get the metadata * * @returns {Promise<MetadataInfo | null>} a promise that is resolved with a {MetadataInfo | null} object with information from the metadata section */ async getMetadata() { return await this.pdf_document.getMetadata().catch(() => null); } /** * close the extractor * * @returns {Promise<void>} a promise that is resolved when destruction is completed */ async close() { return this.pdf_document.destroy(); } } exports.PdfDataExtractor = PdfDataExtractor; //# sourceMappingURL=pdfdataextractor.js.map