Извлечение столбцов текста из PDF-файла, используя iText - PullRequest
5 голосов
/ 27 октября 2010

Мне нужно извлечь текст из PDF-файлов с помощью iText.

Проблема в том, что некоторые 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(); }
    }
}

Не могли бы вы помочь мне с заданием?

Ответы [ 6 ]

25 голосов
/ 27 октября 2010

Я являюсь автором подсистемы извлечения текста из iText.Что вам нужно сделать, так это разработать собственную стратегию извлечения текста (если вы посмотрите, как реализовано PdfTextExtractor.getTextFromPage, вы увидите, что вы можете предоставить сменную стратегию).

Как вы собираетесь определять, где столбцызапуск и остановка полностью зависит от вас - это сложная проблема - у PDF нет концепции столбцов (черт, у нее даже нет слов) - достаточно просто собрать извлечение текста, которое обеспечивает стратегия по умолчанию,довольно сложно).Если вы заранее знаете, где находятся столбцы, тогда вы можете использовать региональный фильтр для обратного вызова слушателя текстового рендера (для этого есть код в библиотеке iText, и последняя версия книги iText In Action приводит подробный пример).

Если вам нужно получить столбцы из произвольных данных, у вас есть какой-то алгоритм работы впереди (если вы получите что-то работающее, я бы с удовольствием посмотрел).Некоторые идеи о том, как подойти к этому:

  1. Используйте алгоритм, аналогичный тому, который используется в стратегии извлечения текста по умолчанию (LocationAware ...), чтобы получить список слов и местоположений X / Y (обязательнодля учета угла поворота)
  2. Для каждого слова нарисуйте воображаемую линию, проходящую на всю высоту страницы.Сканирование для всех других слов, которые начинаются в той же X позиции.
  3. Во время сканирования также ищите слова, которые пересекают позицию X (но не начинаются с позиции X).Это даст вам потенциальное местоположение для позиций начала / остановки столбца Y на странице.
  4. Получив столбцы X и Y, вы можете прибегнуть к подходу, отфильтрованному по регионам

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

1 голос
/ 06 октября 2016

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);
   }
}

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

1 голос
/ 13 февраля 2014

Я знаю, что мой ответ немного опоздал.Но я использую следующий код для чтения определенных страниц из файлов PDF.У меня не было проблем с чтением столбцов, без объединенного текста, каждый столбец печатается отдельно от другого.

    /**
 * 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" );

}

1 голос
/ 27 октября 2010

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

0 голосов
/ 27 октября 2010

Таблицы не существуют как структуры в PDF, если файл не использует структурированное содержимое.Вы понимаете, что такое файл PDF?Я написал статью в блоге, объясняющую проблемы извлечения текста на http://www.jpedal.org/PDFblog/?p=228

0 голосов
/ 27 октября 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...