Tengo un grande de un solo documento pdf que consiste en varios registros. Cada registro generalmente lleva de una página, sin embargo, algunos de uso de 2 páginas. Un registro se inicia con un texto definido, siempre el mismo.

Mi objetivo es dividir este pdf en distintos archivos pdf y la división debe suceder siempre antes de que el «texto del encabezado» se encuentra.

Nota: estoy en busca de una herramienta o de la biblioteca de java o python. Debe ser gratuita y está disponible en Win 7.

Alguna idea? AFAIK imagemagick no funciona para esto. Puede itext hacer esto? Yo nunca he usado y es
bastante complejo por lo tanto necesitaría algunos consejos.

EDICIÓN:

Marcada Respuesta me llevó a la solución. Para completar mi exacta aplicación:

public void splitByRegex(String filePath, String regex,
        String destinationDirectory, boolean removeBlankPages) throws IOException,
        DocumentException {

    logger.entry(filePath, regex, destinationDirectory);
    destinationDirectory = destinationDirectory == null ? "" : destinationDirectory;
    PdfReader reader = null;
    Document document = null;
    PdfCopy copy = null;
    Pattern pattern = Pattern.compile(regex);        

    try {
        reader = new PdfReader(filePath);
        final String RESULT = destinationDirectory + "/record%d.pdf";
        //loop over all the pages in the original PDF
        int n = reader.getNumberOfPages();
        for (int i = 1; i < n; i++) {

            final String text = PdfTextExtractor.getTextFromPage(reader, i);
            if (pattern.matcher(text).find()) {
                if (document != null && document.isOpen()) {
                    logger.debug("Match found. Closing previous Document..");
                    document.close();
                }
                String fileName = String.format(RESULT, i);
                logger.debug("Match found. Creating new Document " + fileName + "...");
                document = new Document();
                copy = new PdfCopy(document,
                        new FileOutputStream(fileName));
                document.open();
                logger.debug("Adding page to Document...");
                copy.addPage(copy.getImportedPage(reader, i));

            } else if (document != null && document.isOpen()) {
                logger.debug("Found Open Document. Adding additonal page to Document...");
                if (removeBlankPages && !isBlankPage(reader, i)){
                    copy.addPage(copy.getImportedPage(reader, i));
                }
            }
        }
        logger.exit();
    } finally {
        if (document != null && document.isOpen()) {
            document.close();
        }
        if (reader != null) {
            reader.close();
        }
    }
}

private boolean isBlankPage(PdfReader reader, int pageNumber)
        throws IOException {

    //see http://itext-general.2136553.n4.nabble.com/Detecting-blank-pages-td2144877.html
    PdfDictionary pageDict = reader.getPageN(pageNumber);
    //We need to examine the resource dictionary for /Font or
    ///XObject keys.  If either are present, they're almost
    //certainly actually used on the page -> not blank.
    PdfDictionary resDict = (PdfDictionary) pageDict.get(PdfName.RESOURCES);
    if (resDict != null) {
        return resDict.get(PdfName.FONT) == null
                && resDict.get(PdfName.XOBJECT) == null;
    } else {
        return true;
    }
}
  • iText puede hacer lo que quiera, si el texto en el PDF correctamente puede ser analizada. Usted dice, la biblioteca debe ser libre. iText como software libre exige respetar la licencia AGPL.
  • esto es por una cosa así AGPl es un no-problema. El texto se puede seleccionar (por ejemplo de texto) por lo que debería funcionar. Sin embargo estoy interesado en los ejemplos de código si usted conoce.
  • Actualmente estoy sólo en línea a través de mi teléfono inteligente. Voy a tratar de encontrar alguna muestra más adelante en el código.
InformationsquelleAutor beginner_ | 2013-05-03

4 Comentarios

  1. 5

    Puede crear una herramienta para sus necesidades a través de iText.

    Cuando usted está buscando muestras de código de relación (las versiones actuales de) la librería iText, usted debe consultar a iText en Acción — 2ª Edición el código de las muestras de que están en línea y se pueden buscar por palabra clave de aquí.

    En su caso, las muestras relevantes son Burst.java y ExtractPageContentSorted2.java.

    Burst.java muestra cómo dividir un PDF en varios archivos Pdf más pequeños. La central código:

    PdfReader reader = new PdfReader("allrecords.pdf");
    final String RESULT = "record%d.pdf";
    
    //We'll create as many new PDFs as there are pages
    Document document;
    PdfCopy copy;
    //loop over all the pages in the original PDF
    int n = reader.getNumberOfPages();
    for (int i = 0; i < n; ) {
        //step 1
        document = new Document();
        //step 2
        copy = new PdfCopy(document,
                new FileOutputStream(String.format(RESULT, ++i)));
        //step 3
        document.open();
        //step 4
        copy.addPage(copy.getImportedPage(reader, i));
        //step 5
        document.close();
    }
    reader.close();
    

    Esta muestra se divide un PDF en una sola página de los archivos Pdf. En su caso, usted tiene que dividir por diferentes criterios. Pero eso sólo significa que en el bucle en el que a veces tienen que agregar más de uno importado de la página (y por lo tanto disociar el índice de bucle y números de página a la importación).

    A reconocer en las páginas de un nuevo conjunto de datos se inicia, ser inspirado por ExtractPageContentSorted2.java. Este ejemplo muestra cómo analizar el contenido de texto de una página a una cadena. La central código:

    PdfReader reader = new PdfReader("allrecords.pdf");
    for (int i = 1; i <= reader.getNumberOfPages(); i++) {
        System.out.println("\nPage " + i);
        System.out.println(PdfTextExtractor.getTextFromPage(reader, i));
    }
    reader.close();
    

    Simplemente buscar el registro de inicio de texto: Si el texto de la página que contiene, un nuevo récord empieza allí.

    • Gracias, eso es muy útil. Su bucle for necesita ir hasta que me <= n, a pesar de que, o te vas a dejar la última página de su fuente de PDF.
    • Que no debería ser necesario. Como i se incrementa en el interior del cuerpo del bucle, en Esencia, esto ya es un bucle de 1 a n , ahora como getImportedPage se refiere.
  2. 1

    Si te gusta Python, hay una buena biblioteca: PyPDF2. La biblioteca es puro python2, similar a la licencia BSD.

    Código de ejemplo:

    from PyPDF2 import PdfFileWriter, PdfFileReader
    
    input1 = PdfFileReader(open("C:\Users\Jarek\Documents\x.pdf", "rb"))
    
    # analyze pdf data
    print input1.getDocumentInfo()
    print input1.getNumPages()
    text = input1.getPage(0).extractText()
    print text.encode("windows-1250", errors='backslashreplacee')
    
    # create output document
    output = PdfFileWriter()
    output.addPage(input1.getPage(0))
    fout = open("c:\temp\1\y.pdf", "wb")
    output.write(fout)
    fout.close()
    

Dejar respuesta

Please enter your comment!
Please enter your name here