Чтение таблицы или значения ячейки в файле PDF с использованием Java?

Я прошел форумы по Java и PDF для извлечения текстового значения из таблицы в pdf-файле, но не смог найти никакого решения, кроме JPedal (оно не с открытым исходным кодом и не лицензировано).

Итак, я хотел бы знать любые API с открытым исходным кодом, такие как pdfbox, itext для достижения того же результата, что и JPedal.

Ссылка Пример:

Образец таблицы

2 ответа

В комментариях ОП пояснил, что он находит текстовое значение из таблицы в PDF-файле, который он хочет извлечь

Предоставляя координаты X и Y

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

Это возможно с помощью любой из библиотек, которые вы упомянули (и, конечно, других).

IText

Чтобы ограничить область, из которой вы хотите извлечь текст, вы можете использовать RegionTextRenderFilter в FilteredTextRenderListenerНапример:

/**
 * Parses a specific area of a PDF to a plain text file.
 * @param pdf the original PDF
 * @param txt the resulting text
 * @throws IOException
 */
public void parsePdf(String pdf, String txt) throws IOException {
    PdfReader reader = new PdfReader(pdf);
    PrintWriter out = new PrintWriter(new FileOutputStream(txt));
    Rectangle rect = new Rectangle(70, 80, 490, 580);
    RenderFilter filter = new RegionTextRenderFilter(rect);
    TextExtractionStrategy strategy;
    for (int i = 1; i <= reader.getNumberOfPages(); i++) {
        strategy = new FilteredTextRenderListener(new LocationTextExtractionStrategy(), filter);
        out.println(PdfTextExtractor.getTextFromPage(reader, i, strategy));
    }
    out.flush();
    out.close();
    reader.close();
}

( ExtractPageContentArea образец из iText в действии, 2-е издание)

Тем не менее, будьте осторожны, iText извлекает текст на основе базовых фрагментов текста в потоке контента, а не на основе каждого отдельного символа в таком фрагменте. Таким образом, весь кусок обрабатывается, если только самая маленькая его часть находится в области.

Это может или не может вас устраивать.

Если вы столкнулись с проблемой, что извлекается больше, чем вы хотели, вы должны заранее разбить куски на их составляющие глифы. В этом ответе описывается, как это сделать.

PDFBox

Чтобы ограничить область, из которой вы хотите извлечь текст, вы можете использовать PDFTextStripperByAreaНапример:

PDDocument document = PDDocument.load( args[0] );
if( document.isEncrypted() )
{
    document.decrypt( "" );
}
PDFTextStripperByArea stripper = new PDFTextStripperByArea();
stripper.setSortByPosition( true );
Rectangle rect = new Rectangle( 10, 280, 275, 60 );
stripper.addRegion( "class1", rect );
List allPages = document.getDocumentCatalog().getAllPages();
PDPage firstPage = (PDPage)allPages.get( 0 );
stripper.extractRegions( firstPage );
System.out.println( "Text in the area:" + rect );
System.out.println( stripper.getTextForRegion( "class1" ) );

( ExtractTextByArea из примеров PDFBox 1.8.8)

Попробуйте PDFTextStream. По крайней мере, я могу определить значения столбца. Ранее я использовал iText и застрял в определении стратегии. Это тяжело.

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

import com.snowtide.PDF;
import com.snowtide.pdf.Document;
import com.snowtide.pdf.OutputTarget;

public class PDFText {
    public static void main(String[] args) throws java.io.IOException {
        String pdfFilePath = "xyz.pdf";

        Document pdf = PDF.open(pdfFilePath);
        StringBuilder text = new StringBuilder(1024);
        pdf.pipe(new OutputTarget(text));
        pdf.close();
        System.out.println(text);
   }
}

Был задан вопрос, связанный с этим на stackru!

Другие вопросы по тегам