问题是:一些 pdf 文件包含 2 列,当我提取文本时,我得到一个文本文件,其中各列被合并为结果(即同一行中两列的文本)
这是代码:
public class pdf
{
private static String INPUTFILE = "http://www.revuemedecinetropicale.com/TAP_519-522_-_AO_07151GT_Rasoamananjara__ao.pdf" ;
private static String OUTPUTFILE = "c:/new3.pdf";
public static void main(String[] args) throws DocumentException, IOException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(OUTPUTFILE));
document.open();
PdfReader reader = new PdfReader(INPUTFILE);
int n = reader.getNumberOfPages();
PdfImportedPage page;
// Go through all pages
for (int i = 1; i <= n; i++) {
page = writer.getImportedPage(reader, i);
Image instance = Image.getInstance(page);
document.add(instance);
}
document.close();
PdfReader readerN = new PdfReader(OUTPUTFILE);
for (int i = 1; i <= n; i++) {
String myLine = PdfTextExtractor.getTextFromPage(readerN,i);
System.out.println(myLine);
try {
FileWriter fw = new FileWriter("c:/yo.txt",true);
fw.write(myLine);
fw.close();
}catch (IOException ioe) {ioe.printStackTrace(); }
}
}
你能帮我完成这个任务吗?
PdfTextExtractor.getTextFromPage
是如何实现的,你会发现你可以提供一个可插入的策略)。如何确定列的开始和结束位置完全取决于您 - 这是一个困难的问题 - PDF 没有任何列的概念(哎呀,它甚至没有单词的概念 - 只是放在一起默认策略提供的文本提取非常棘手)。 如果您预先知道列在哪里,那么您可以在文本渲染侦听器回调上使用区域过滤器(iText 库中有用于执行此操作的代码,最新版本的 iText In Action 书中提供了详细的示例) .
如果您需要从任意数据中获取列,那么您需要完成一些算法工作(如果您能成功,我很乐意看一下)。 关于如何解决这个问题的一些想法:
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);
}
}
您想在这里实现什么目标? 您可以使用商业 OCR 引擎,让它完成所有艰苦的工作,然后处理数据。
/**
* Get plain text from a specific page in a pdf file.
* @param pdfPath
* @return
* @throws IOException
*/
public static String getPageContent(String pdfPath, int pageNumber) throws IOException
{
PdfReader reader = new PdfReader(pdfPath);
StringWriter output = new StringWriter();
try {
output.append(PdfTextExtractor.getTextFromPage(reader, pageNumber, new SimpleTextExtractionStrategy()));
} catch (OutOfMemoryError e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return output.toString();
}
如果您正在考虑提取页面的一部分,假设仅提取 1 列,那么您需要获取该列的尺寸。这仍然有点棘手,但如果您已经知道该列的开始文本(以估计宽度和高度的方式),您也许能够弄清楚这一点。这可以通过使用矩形区域来完成。请参阅下面的代码,如果我的点测量错误,抱歉。在下面的代码中,我尝试获取整个页面尺寸。
public static String getPageContent(String pdfPath, int pageNumber) throws IOException
{
PDDocument pdDoc = PDDocument.load(pdfPath);
PDPage specPage = (PDPage)pdDoc.getDocumentCatalog().getAllPages().get( 0 );
PDFTextStripperByArea stripper = new PDFTextStripperByArea();
stripper.setSortByPosition( true );
float width = (specPage.getMediaBox().getHeight())*25.4f;
float height = (specPage.getMediaBox().getWidth())*25.4f;
Rectangle rect = new Rectangle( 0, 0, Math.round(width), Math.round(height));
stripper.addRegion( "class1", rect );
List allPages = pdDoc.getDocumentCatalog().getAllPages();
PDPage firstPage = (PDPage)allPages.get( pageNumber-1 );
stripper.extractRegions( firstPage );
return stripper.getTextForRegion( "class1" );
}