В вашем вопросе не упоминалась выбранная вами библиотека PDF. Ваши теги представили на выбор itext, pdfbox и pdftotext. Здесь я выбрал iText 5.5.x для Java; аналоговое решение также должно быть возможно с использованием PDFBox. Я не уверен в Pdftotext.
Осматривая внутренности вашего PDF, можно заметить:
Текст, показывающий инструкции, расположен в порядке чтения.
Таким образом, вам не нужно сортировать их для извлечения текста, и вы можете основывать свое решение на SimpleTextExtractionStrategy
.
Здесь или там есть множество одиночных пробельных символов, которые не имеют смысла и мешают реальному тексту.
Вы должны отфильтровать эти лишние символы пробела.
Разделительные линии набора данных являются единственными заполненными путями. Кроме того, эти разделительные линии также рисуются в порядке чтения.
Таким образом, вы уже можете распознавать их по операции заполнения и не нужно анализировать форму пути, а сразу после их распознания вы можете добавить маркер в вывод стратегии извлечения текста.
Таким образом, вы можете реализовать свою задачу, расширив SimpleTextExtractionStrategy
:
public class SimpleDividerAwareTextExtractionStrategy extends SimpleTextExtractionStrategy implements TextExtractionStrategy, ExtRenderListener {
@Override
public void renderText(TextRenderInfo renderInfo) {
if (!" ".equals(renderInfo.getText()))
super.renderText(renderInfo);
}
@Override
public void modifyPath(PathConstructionRenderInfo renderInfo) { }
@Override
public Path renderPath(PathPaintingRenderInfo renderInfo) {
if (renderInfo.getOperation() == PathPaintingRenderInfo.FILL)
appendTextChunk("\n----------\n");
return null;
}
@Override
public void clipPath(int rule) { }
}
(вспомогательный класс SimpleDividerAwareTextExtractionStrategy)
Применение этой стратегии к вашему образцу PDF:
PdfReader reader = new PdfReader(SOURCE);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
SimpleDividerAwareTextExtractionStrategy strategy = new SimpleDividerAwareTextExtractionStrategy();
for (int i = 1; i <= reader.getNumberOfPages(); i++)
parser.processContent(i, strategy);
String content = strategy.getResultantText();
System.out.println(content);
(DividerAwareTextExtraction тест testSimple419494453ThisIsASampleDocument
)
один получает:
This is a sample document
----------
SAM PARTNERS LLC.
Existing Client with Premium
Support, Retail Client
123 Popsicle Ave
Candyville IA 50325
512-512-5555
Order Number Order Quantity
RTL123 45
RTL456 25
RTL324 95
RTL457 100
----------
DUNDER MIFFLIN
Existing Client with Standard
Support, Corporate Client
123 Lolipop Ave
Candyville PA 21325
215-512-5555
Order Number Order Quantity
RTL1234 400
RTL4565 200
----------
Mobile PARTNERS LLC.
New Client with Premium
Support, Retail Client
123 First Ave
Nashville TN 51325
514-512-5555
Order Number Order Quantity
RTL123 45
RTL456 25
RTL324 95
RTL457 25
RTL457 25
RTL457 25
RTL457 25
----------
BLUEBERRY MUFFIN
New Client, Corporate Client
123 STORM Ave
Hershey PA 50325
216-512-5555
Order Number Order Quantity
RTL1234 400
RTL4565 200
----------
Чтобы извлечь наборы данных, вам просто нужно найти строку разделителя ----------
(конечно, вы можете использовать другую строку в SimpleDividerAwareTextExtractionStrategy
), затем прочитать все строки до Order Number Order Quantity
для данных имени и адреса, а затем прочитать все строки до следующего разделителя. строка для информации о заказе.
person
mkl
schedule
09.08.2019