Melhorando a extração de texto de PDFs Multi-Coluna

Layouts multi-coluna frequentemente exigem processamento extra para melhorar a ordem de leitura e a qualidade da extração.

Extrair texto após reduzir o tamanho da fonte

Esta técnica atualiza os tamanhos de fonte dos fragmentos de texto, salva o documento ajustado na memória e então extrai o texto do resultado transformado.

  1. Abra o PDF de origem em uma instância de Document.
  2. Crie um TextFragmentAbsorber e visite todas as páginas do documento para coletar objetos TextFragment.
  3. Itere pelos fragmentos e reduza cada tamanho da Font pela proporção solicitada para que o layout denso de colunas possa ser normalizado antes da extração.
  4. Salve o ajustado Document para um fluxo de bytes em memória.
  5. Reabra um segundo Document a partir desse buffer de memória.
  6. Crie um TextAbsorber, visite todas as páginas do documento transformado e escreva o texto extraído no arquivo de saída.
public static void extractTextReduceFont(Path inputFile, Path outputFile, double reduceRatio) throws Exception {
    try (Document document = new Document(inputFile.toString())) {
        TextFragmentAbsorber fragmentAbsorber = new TextFragmentAbsorber();
        document.getPages().accept(fragmentAbsorber);
        for (TextFragment fragment : fragmentAbsorber.getTextFragments()) {
            fragment.getTextState().setFontSize((float) (fragment.getTextState().getFontSize() * reduceRatio));
        }

        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        document.save(stream);
        try (Document document2 = new Document(new ByteArrayInputStream(stream.toByteArray()))) {
            TextAbsorber textAbsorber = new TextAbsorber();
            document2.getPages().accept(textAbsorber);
            Files.writeString(outputFile, textAbsorber.getText());
        }
    }
}

Extrair texto com um fator de escala

Use TextExtractionOptions em modo de formatação pura e ajuste o fator de escala para layouts com muitas colunas.

  1. Abra o PDF de origem em uma instância de Document.
  2. Crie um TextAbsorber para extração do documento inteiro.
  3. Crie TextExtractionOptions no modo de formatação pura para que o comportamento de extração sensível ao layout seja usado.
  4. Defina o fator de escala e aplique as opções de extração ao absorvedor antes de visitar as páginas.
  5. Visite todas as páginas do documento e grave o texto extraído no arquivo de saída.
public static void extractTextScaleFactor(Path inputFile, Path outputFile, double scaleFactor) throws Exception {
    try (Document document = new Document(inputFile.toString())) {
        TextAbsorber textAbsorber = new TextAbsorber();
        TextExtractionOptions extractionOptions =
                new TextExtractionOptions(TextExtractionOptions.TextFormattingMode.Pure);
        extractionOptions.setScaleFactor(scaleFactor);
        textAbsorber.setExtractionOptions(extractionOptions);
        document.getPages().accept(textAbsorber);
        Files.writeString(outputFile, textAbsorber.getText());
    }
}