Обработка pdf документа через pdf.js библиотеку

Суть моей задачи

Моя задача: написать pdf обработчик, который будет из документа получать данные. У документа есть определенный стиль, по этому его обработать используя код - возможно. По сути задача: из документа получить текст, но его разделить ответ на блоки.

Пример pdf

xml handler

Как можно заметить, есть определенные рамки, по которым я и хочу разделить ответ на части. Изначально хотел использовать xml преобразователь и все было хорошо, если он смог весь текст распознать нормально. Но этому не суждено быть:

  1. Не весь текст нормально распознался
  2. Линии находится ниже чем должны
  3. Полигоны вообще не вывожу на фотографии, ибо с ними вообще все плохо.

xml handler

Эти символы не могут нормально отобразиться даже в массив формате (в консоли браузера):

0: {tag: 'draw:text-box', args: {…}, data: 'Задание №1 профильного ЕГЭ по математике '}
1: {tag: 'draw:text-box', args: {…}, data: 'https://math100.ru'}
2: {tag: 'draw:polygon', args: {…}, data: ''}
3: {tag: 'draw:text-box', args: {…}, data: 'ЗАДАНИЯ №1 ПРОФИЛЬНОГО ЕГЭ ПО МАТЕМАТИКЕ '}
4: {tag: 'draw:text-box', args: {…}, data: 'РАЦИОНАЛЬНЫЕ УРАВНЕНИЯ '}
28: {tag: 'draw:text-box', args: {…}, data: '13 '}
29: {tag: 'draw:text-box', args: {…}, data: ''} <== вот символ который не может нормально отобразиться.
30: {tag: 'draw:line', args: {…}, data: ''}

pdf.js

Понял что самый хороший способ - исключить любые преобразователи и обрабатывать pdf напрямую. Решил использовать библиотеку pdf.js от mozilla, но:

  1. У нее плохая документация.
  2. Есть функция getTextContext(), которая выводит только лишь текст, а мне нужно еще линии и полигоны.
  3. Функция render выводит только в canvas и больше с ней не чего нельзя сделать.

В итоге стал я разбирать данную библиотеку через debug режим, но проблема в том, что она ВСЯ работает через Promise, по этому точки остановки нужно ставить проктический везде. В противном случае браузер скрывает очень много ценного (поставить точки в нужных местах - тоже большая проблема). Отдельное спасибо хочу отдать функции createPromiseCapability, которая приводит Promise к глобальному виду.

Функция createPromiseCapability из pdf.js:

t.createPromiseCapability = function createPromiseCapability()
{
    const e = Object.create(null);
    let t = !1;
    
    Object.defineProperty(e, "settled", {
        get: () => t
    });
    
    e.promise = new Promise((function(a, r)
    {
        e.resolve = function(e)
        {
            t = !0;
            a(e)
        };
        
        e.reject = function(e)
        {
            t = !0;
            r(e)
        }
    }));
    
    return e
};

Итог

В итоге я стою в тупике:

  1. Пытаться дальше разбирать код pdf.js - не известно сколько еще на это уйдет времени (я уже чистые 5 дней сижу, без отдыха).
  2. xml преобразователи не могут нормально обработать текст (скорее всего шрифт не нравиться).
  3. Пытаться читать pdf самостоятельно - уже нет желания (я читал несколько статей, и поверьте, pdf сам по себе тоже не такой простой - как кажется).
  4. Написать свой класс CanvasRenderingContext2D, для перехвата линий, текста, полигонов - возможно хорошая идея.

Примечание: Забыл написать, что при вызове функции: getTextContext - текст в массиве отображается как и у xml (то есть криво). Но этой проблемы нет при вызове render функции.


Подскажите пожалуйста, что стоит делать в этой ситуации?

  • Пытаться дальше разобраться pdf.js?
  • Либо может кто-то пытался до меня разобраться данную библиотеку и понять как она работает, чтобы подсказать в каком направление двигаться?

Я действительно уже просто сижу и не знаю что делать...

Мой код pdf отображения на экране (функция render)

Если кому-то нужен будет код для отображения pdf на экране:

<!DOCTYPE html>
<html lang="ru">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=Edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        
        <!-- header -->
        <title>HTML</title>
    </head>
    
    <body>
        <span id="pdf_page_length"></span>
        <main id="pdf_list_canvas"></main>
        
        <!-- scripts -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.1.81/pdf.min.js"></script>
        <script src="loader.js"></script>
    </body>
</html>
const pdf_page_length = document.getElementById('pdf_page_length');
const pdf_list_canvas = document.getElementById('pdf_list_canvas');

function renderPage(page)
{
    // canvas
    const canvas_tag = document.createElement('canvas');
    const canvas_ctx = canvas_tag.getContext('2d');
    pdf_list_canvas.append(canvas_tag);
    
    // viewport
    const viewport = page.getViewport({ scale: 1 });
    canvas_tag.height = viewport.height;
    canvas_tag.width  = viewport.width;
    
    page.render({
        canvasContext: canvas_ctx,
        viewport: viewport
    });
    
    window.pdf_page.push({
        canvas_tag: canvas_tag,
        canvas_ctx: canvas_ctx,
        viewport: viewport,
        page: page
    });
    
    page.getTextContent().then(function (text)
    {
        window.pdf_text.push(text);
    });
}

function renderFile(file)
{
    window.pdf_file = file;
    window.pdf_page = [];
    window.pdf_text = [];
    
    pdf_page_length.textContent = file.numPages;
    
    for (let index = 1; index <= file.numPages; index++)
    {
        file.getPage(index).then(renderPage);
    }
}

// Загрузка pdf файла
window.pdf_task = pdfjsLib.getDocument('math.pdf');
window.pdf_task.promise.then(renderFile);

Ответы (0 шт):