pdfdataextract
Version:
Extract data from a pdf with pure javascript
150 lines (149 loc) • 5.47 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PdfPageData = void 0;
const types_1 = require("./types");
/**
* pdf data information per page
*/
class PdfPageData {
/**
* @internal
*/
constructor(page, canvasApi, ocrApi) {
this.page = page;
this.canvasApi = canvasApi;
this.ocrApi = ocrApi;
}
/**
* get the text of the page
*
* @param {boolean|Sort} [sort=false] - sort the text by text coordinates
* @returns {Promise<string>} a promise that is resolved with a {string} with the extracted text of the page
*/
async toText(sort = false) {
const sortOption = typeof sort === 'boolean' ? (sort ? types_1.Sort.ASC : null) : sort;
return this.page.getTextContent({
disableNormalization: false,
includeMarkedContent: false,
}).then((textContent) => {
const items = textContent.items;
/*
transform is a array with a transform matrix [scale x,shear x,shear y,scale y,offset x,offset y]
0,1 1,1
-----------
| |
| |
| pdf |
| |
| |
-----------
0,0 1,0
*/
//coordinate based sorting
if (sortOption !== null) {
if (sortOption === types_1.Sort.ASC) {
items.sort((e1, e2) => {
if (e1.transform[5] < e2.transform[5])
return 1;
else if (e1.transform[5] > e2.transform[5])
return -1;
else if (e1.transform[4] < e2.transform[4])
return -1;
else if (e1.transform[4] > e2.transform[4])
return 1;
else
return 0;
});
}
else {
items.sort((e1, e2) => {
if (e1.transform[5] < e2.transform[5])
return -1;
else if (e1.transform[5] > e2.transform[5])
return 1;
else if (e1.transform[4] < e2.transform[4])
return 1;
else if (e1.transform[4] > e2.transform[4])
return -1;
else
return 0;
});
}
}
let lastLineY = -1, text = '';
for (const item of items) {
if (lastLineY === -1 || lastLineY == item.transform[5]) {
text += item.str;
// TODO if spaced by coordinates (x + text width + space width = next x)
//textContent.styles[item.fontName];
//dummyContext.font = '';
//dummyContext.measureText(item.str);
}
else {
text += '\n' + item.str;
}
lastLineY = item.transform[5];
}
return text;
}, () => '');
}
/**
* recognizes the text from the image information of this pdf page
* requires node-canvas/node-pureimage and tesseract.js as additional installation
*
* @param {OCRLang[]} langs - the language traineddata used for recognition
* @returns {Promise<string>} the result as text
*/
async ocr(langs) {
if (!this.ocrApi)
throw new Error('OcrFactory.ocrApi is not set (tesseractjs)');
const ocr = new this.ocrApi();
const result = await ocr.ocrBuffers([await this.toJPEG()], langs);
return result[0];
}
/**
* creates a canvas and renders
*
* @param {T} canvasApi - the canvas api that is used to create the canvas
* @returns {Promise<T>} the canvas
*/
async toCanvasApi(canvasApi) {
const viewport = this.page.getViewport({ scale: 1.0 });
const canvas = new canvasApi(viewport.width, viewport.height);
await this.page.render({
canvasContext: canvas.createContext(),
viewport: viewport,
}).promise;
return canvas;
}
/**
* converts to a jpeg image
*
* @param {number} [quality=0.8] - the quality of the image (0.0-1.0)
* @returns {Promise<Buffer>} the jpeg image as a {Buffer}
*/
async toJPEG(quality = 0.8) {
if (!this.canvasApi)
throw new Error('canvasApi is not set (node-canvas or pureimage is not installed)');
return (await this.toCanvasApi(this.canvasApi)).toJPEG(quality);
}
/**
* converts to a png image
*
* @returns {Promise<Buffer>} the png image as a {Buffer}
*/
async toPNG() {
if (!this.canvasApi)
throw new Error('canvasApi is not set (node-canvas or pureimage is not installed)');
return (await this.toCanvasApi(this.canvasApi)).toPNG();
}
/**
* close the page data
* @returns {boolean} — if close was successfully
*/
close() {
return this.page.cleanup();
}
}
exports.PdfPageData = PdfPageData;
//# sourceMappingURL=pdfpagedata.js.map