我已经通过Java和PDF论坛从pdf文件中的表中提取文本值,但找不到除JPedal之外的任何解决方案(它不是开源和许可的)。
所以,我想知道任何开源API,如pdfbox,itext,以获得与JPedal相同的结果。
参考。例如:
答案 0 :(得分:5)
在评论中,OP澄清说他从pdf文件中的表中找到文本值他要提取
提供X和Y坐标
因此,虽然这个问题最初听起来像是从PDF中通用提取表格数据(至少可能很困难),但它实际上主要是从坐标给出的页面上的矩形区域中提取文本。
这可以使用您提到的任何一个库(当然也包括其他库)。
要限制要从中提取文字的区域,您可以使用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();
}
(来自iText in Action,第2版的ExtractPageContentArea样本)
请注意,iText会根据内容流中的基本文本块提取文本,而不是基于此类块中的每个字形。因此,如果只有最细小的部分在该区域内,则处理整个块。
这可能适合您,也可能不适合您。
如果遇到的问题是提取的内容比您想要的多,那么您应该事先将这些块拆分成它们的构成字形。 This stackoverflow answer解释了如何做到这一点。
要限制要从中提取文字的区域,您可以使用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" ) );
(来自PDFBox 1.8.8示例的ExtractTextByArea)
答案 1 :(得分:0)
试试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);
}
}