Чтение таблицы или значения ячейки в файле 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);
}
}