Как конвертировать PDF в текст (извлечь текст из PDF) с помощью JavaScript

Работая с файлами Portable Document Format (PDF), пользователь может захотеть извлечь весь текст из файла PDF. Таким образом, пользователю не нужно выделять весь текст PDF с помощью мыши, а затем что-то делать с ним.

В этой статье вы узнаете, как извлечь текст из PDF с помощью Javascript, используя pdf.js. Эта библиотека представляет собой универсальную платформу, основанную на веб-стандартах, для анализа и рендеринга PDF-файлов. Этот проект использует разные слои, мы собираемся использовать конкретно 2, ядро ​​и слой дисплея. PDF.js в значительной степени зависит от использования обещаний. Если обещания являются новыми для вас, рекомендуется ознакомиться с ними, прежде чем продолжить. PDF.js поддерживается сообществом и поддерживается Mozilla Labs.

Сказав это, давайте начнем!

Требования

Для получения дополнительной информации о pdf.js, пожалуйста, посетите Официальный репозиторий Github здесь.

1. Включите необходимые файлы

Для того, чтобы извлечь текст из PDF вам потребуется как минимум 3 файла (2 из них загружены асинхронно). Как уже упоминалось ранее, мы будем использовать pdf.js, Предварительная сборка этой библиотеки основана на 2 файлах, а именно pdf.js а также pdf.worker.js, pdf.js файл должен быть включен через тег script:

И pdf.worker.js должен быть загружен через workerSrc метод, который ожидает URL и загружает его автоматически. Вам необходимо сохранить URL-адрес PDF-файла, который вы хотите преобразовать, в переменную, которая будет использоваться позже:


// Path to PDF file
var PDF_URL = '/path/to/example.pdf';
// Specify the path to the worker
PDFJS.workerSrc = '/path/to/pdf.worker.js';

С помощью необходимых сценариев вы можете приступить к извлечению текста PDF, выполнив следующие действия.

2. Загрузить PDF

Продолжите импортировать PDF, который вы хотите преобразовать в текст, используя getDocument метод PDFJS (открывается глобально после загрузки скрипта pdf.js в документ). Структура объекта PDF.js слабо повторяет структуру реального PDF. На верхнем уровне находится объект документа. Из документа можно получить дополнительную информацию и отдельные страницы. Используйте следующий код, чтобы получить PDF документ:

Заметка

Чтобы предотвратить проблемы с CORS, PDF-файл необходимо обслуживать из одного домена веб-документа (например, www.yourdomain.com/pdf-to-test.html и www.yourdomain.com/pdffile.pdf). Кроме того, вы можете загрузить PDF-документ через base64 непосредственно в документ без каких-либо запросов (см. Документацию).

var PDF_URL  = '/path/to/example.pdf';
PDFJS.getDocument(PDF_URL).then(function (PDFDocumentInstance) {
// Use the PDFDocumentInstance To extract the text later
}, function (reason) {
// PDF loading error
console.error(reason);
});

PDFDocumentInstance это объект, который содержит полезные методы, которые мы собираемся использовать для извлечения текста из PDF.

3. Извлечение текста с одной страницы

PDFDocumentInstance объект, полученный из getDocument Метод (предыдущий шаг) позволяет изучить PDF с помощью полезного метода, а именно getPage, Этот метод ожидает в качестве первого аргумента номер страницы PDF, который должен быть обработан, а затем возвращает (когда обещание выполнено) в качестве переменной pdfPage, От pdfPageДля достижения нашей цели извлечения текста из PDF мы будем полагаться на getTextContent метод. getTextContent Метод pdf-страницы — это метод, основанный на обещаниях, который возвращает объект с двумя свойствами:

  • items: Массив [X]
  • styles: Объект

Мы заинтересованы в объектах, хранящихся в массиве items. Этот массив содержит несколько объектов (или только один в зависимости от содержимого PDF), которые имеют следующую структуру:

{
"dir":"ltr",
"fontName": "g_d0_f2",
"height": 8.9664,
"width": "227.1458",
"str": "When a trace call returns blabla bla ..."
}

Вы видите что-то интересное? Вот так ! объект содержит str свойство, содержащее текст, который должен быть нарисован в PDF. Чтобы получить весь текст страницы, вам просто нужно объединить все str свойства всех объектов. Вот что делает следующий метод, простой метод, основанный на обещаниях, который возвращает объединенный текст страницы, когда он решен:

Важное замечание против ненавистника

Прежде чем начать в комментариях сказать, что вместо объединения строк используется += следует избегать и вместо этого делать что-то вроде сохранения строк в массиве, а затем соединять их, вы должны знать, что на основе тестов в JSPerf что с помощью += это самый быстрый метод, хотя не обязательно в каждом браузере. Узнайте больше об этом здесь, и если вам это не нравится, измените его, как хотите.

/**
* Retrieves the text of a specif page within a PDF Document obtained through pdf.js
*
* @param {Integer} pageNum Specifies the number of the page
* @param {PDFDocument} PDFDocumentInstance The PDF document obtained
**/
function getPageText(pageNum, PDFDocumentInstance) {
// Return a Promise that is solved once the text of the page is retrieven
return new Promise(function (resolve, reject) {
PDFDocumentInstance.getPage(pageNum).then(function (pdfPage) {
// The main trick to obtain the text of the PDF page, use the getTextContent method
pdfPage.getTextContent().then(function (textContent) {
var textItems = textContent.items;
var finalString = "";
// Concatenate the string of the item to the final string
for (var i = 0; i < textItems.length; i++) {
var item = textItems[i];
finalString += item.str + " ";
}
// Solve promise with the text retrieven from the page
resolve(finalString);
});
});
});
}

Довольно просто, не так ли? Теперь вам просто нужно написать код, описанный ранее:

var PDF_URL  = '/path/to/example.pdf';
PDFJS.getDocument(PDF_URL).then(function (PDFDocumentInstance) {
var totalPages = PDFDocumentInstance.pdfInfo.numPages;
var pageNumber = 1;
// Extract the text
getPageText(pageNumber , PDFDocumentInstance).then(function(textPage){
// Show the text of the page in the console
console.log(textPage);
});
}, function (reason) {
// PDF loading error
console.error(reason);
});

И текст (если есть) первой страницы PDF должен быть показан в консоли. Потрясающие !

4. Извлечение текста из нескольких страниц

Чтобы извлечь текст из нескольких страниц одновременно, мы будем использовать один и тот же getPageText метод, созданный на предыдущем шаге, который возвращает обещание при извлечении содержимого страницы. Поскольку асинхронность может привести к очень проблематичным недопониманиям, и для правильного извлечения текста мы будем запускать несколько обещаний одновременно с Promise.all это позволяет вам решать несколько обещаний одновременно в том же порядке, в котором они были представлены в качестве аргумента (это поможет контролировать проблему обещаний, которые выполняются первыми, чем другие) и, соответственно, получать результаты в массиве в том же порядке:

var PDF_URL = '/path/to/example.pdf';
PDFJS.getDocument(PDF_URL).then(function (PDFDocumentInstance) {
var pdfDocument = pdf;
// Create an array that will contain our promises
var pagesPromises = [];
for (var i = 0; i < pdf.pdfInfo.numPages; i++) {
// Required to prevent that i is always the total of pages
(function (pageNumber) {
// Store the promise of getPageText that returns the text of a page
pagesPromises.push(getPageText(pageNumber, pdfDocument));
})(i + 1);
}
// Execute all the promises
Promise.all(pagesPromises).then(function (pagesText) {
// Display text of all the pages in the console
// e.g ["Text content page 1", "Text content page 2", "Text content page 3" ... ]
console.log(pagesText);
});
}, function (reason) {
// PDF loading error
console.error(reason);
});

Живой пример

Поиграйте со следующей скрипкой, она извлекает содержимое всех страниц этот PDF и добавьте их в виде текста в DOM (перейдите на вкладку Result):

пример

Следующий документ содержит очень простой пример, который отображает содержимое каждой страницы PDF в консоли. Вам просто нужно реализовать это на http-сервере, добавить pdf.js и pdf.worker.js, PDF для тестирования, и все:


PDF.js
var urlPDF = '/path/to/example.pdf';
PDFJS.workerSrc = '/path/to/pdf.worker.js';
PDFJS.getDocument(urlPDF).then(function (pdf) {
var pdfDocument = pdf;
var pagesPromises = [];
for (var i = 0; i < pdf.pdfInfo.numPages; i++) {
// Required to prevent that i is always the total of pages
(function (pageNumber) {
pagesPromises.push(getPageText(pageNumber, pdfDocument));
})(i + 1);
}
Promise.all(pagesPromises).then(function (pagesText) {
// Display text of all the pages in the console
console.log(pagesText);
});
}, function (reason) {
// PDF loading error
console.error(reason);
});
/**
* Retrieves the text of a specif page within a PDF Document obtained through pdf.js
*
* @param {Integer} pageNum Specifies the number of the page
* @param {PDFDocument} PDFDocumentInstance The PDF document obtained
**/
function getPageText(pageNum, PDFDocumentInstance) {
// Return a Promise that is solved once the text of the page is retrieven
return new Promise(function (resolve, reject) {
PDFDocumentInstance.getPage(pageNum).then(function (pdfPage) {
// The main trick to obtain the text of the PDF page, use the getTextContent method
pdfPage.getTextContent().then(function (textContent) {
var textItems = textContent.items;
var finalString = "";
// Concatenate the string of the item to the final string
for (var i = 0; i < textItems.length; i++) {
var item = textItems[i];
finalString += item.str + " ";
}
// Solve promise with the text retrieven from the page
resolve(finalString);
});
});
});
}

Текст не извлекается

Если вы уже пробовали код, а текст не получен, потому что ваш PDF, вероятно, не имеет каких-либо. Возможно, текст PDF, который вы не видите, не является текстом, а изображением, тогда процесс, описанный в этом процессе, вам не поможет. Вы можете использовать другие подходы, такие как оптическое распознавание символов (OCR), однако это не рекомендуется делать на стороне клиента, но на стороне сервера

Ссылка на основную публикацию
Adblock
detector