Pregunta

Estoy utilizando la biblioteca de Java Apache PDFBox para crear archivos PDF. ¿Hay una manera de crear una tabla de datos usando PDFBox? Si no hay tal API para hacerlo, lo que requeriría para dibujar manualmente la tabla usando drawLine etc., ¿Alguna sugerencia sobre cómo hacer esto?

¿Fue útil?

Solución

Fuente creación de tablas con PDFBox

La siguiente método dibuja una tabla con el contenido de la tabla especificado. Es un poco de un truco y va a trabajar para pequeñas cadenas de texto. No realiza el ajuste de texto, pero se puede tener una idea de cómo se hace. Darle una oportunidad!

/**
 * @param page
 * @param contentStream
 * @param y the y-coordinate of the first row
 * @param margin the padding on left and right of table
 * @param content a 2d array containing the table data
 * @throws IOException
 */
public static void drawTable(PDPage page, PDPageContentStream contentStream, 
                            float y, float margin, 
                            String[][] content) throws IOException {
    final int rows = content.length;
    final int cols = content[0].length;
    final float rowHeight = 20f;
    final float tableWidth = page.findMediaBox().getWidth() - margin - margin;
    final float tableHeight = rowHeight * rows;
    final float colWidth = tableWidth/(float)cols;
    final float cellMargin=5f;

    //draw the rows
    float nexty = y ;
    for (int i = 0; i <= rows; i++) {
        contentStream.drawLine(margin, nexty, margin+tableWidth, nexty);
        nexty-= rowHeight;
    }

    //draw the columns
    float nextx = margin;
    for (int i = 0; i <= cols; i++) {
        contentStream.drawLine(nextx, y, nextx, y-tableHeight);
        nextx += colWidth;
    }

    //now add the text        
    contentStream.setFont( PDType1Font.HELVETICA_BOLD , 12 );        

    float textx = margin+cellMargin;
    float texty = y-15;        
    for(int i = 0; i < content.length; i++){
        for(int j = 0 ; j < content[i].length; j++){
            String text = content[i][j];
            contentStream.beginText();
            contentStream.moveTextPositionByAmount(textx,texty);
            contentStream.drawString(text);
            contentStream.endText();
            textx += colWidth;
        }
        texty-=rowHeight;
        textx = margin+cellMargin;
    }
}

Uso:

PDDocument doc = new PDDocument();
PDPage page = new PDPage();
doc.addPage( page );

PDPageContentStream contentStream = new PDPageContentStream(doc, page);

String[][] content = {{"a","b", "1"}, 
                      {"c","d", "2"}, 
                      {"e","f", "3"}, 
                      {"g","h", "4"}, 
                      {"i","j", "5"}} ;

drawTable(page, contentStream, 700, 100, content);
contentStream.close();
doc.save("test.pdf" );

Otros consejos

He creado una pequeña API para crear tablas usando PDFBox. Se puede encontrar en github ( https://github.com/dhorions/boxable ).

Una muestra de un PDF generado se puede encontrar aquí http://goo.gl/a7QvRM .

¿Alguna pista o sugerencias son bienvenidos.

La respuesta aceptada es agradable, pero que trabajará con Apache 1.x PDFBox solamente, para Apache 2.x PDFBox que tendrá que modificar un poco el código para que funcione correctamente.

Así que aquí es el mismo código, pero que es compatible con Apache 2.x PDFBox

El drawTable método:

public static void drawTable(PDPage page, PDPageContentStream contentStream,
    float y, float margin, String[][] content) throws IOException {
    final int rows = content.length;
    final int cols = content[0].length;
    final float rowHeight = 20.0f;
    final float tableWidth = page.getMediaBox().getWidth() - 2.0f * margin;
    final float tableHeight = rowHeight * (float) rows;
    final float colWidth = tableWidth / (float) cols;

    //draw the rows
    float nexty = y ;
    for (int i = 0; i <= rows; i++) {
        contentStream.moveTo(margin, nexty);
        contentStream.lineTo(margin + tableWidth, nexty);
        contentStream.stroke();
        nexty-= rowHeight;
    }

    //draw the columns
    float nextx = margin;
    for (int i = 0; i <= cols; i++) {
        contentStream.moveTo(nextx, y);
        contentStream.lineTo(nextx, y - tableHeight);
        contentStream.stroke();
        nextx += colWidth;
    }

    //now add the text
    contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12.0f);

    final float cellMargin = 5.0f;
    float textx = margin + cellMargin;
    float texty = y - 15.0f;
    for (final String[] aContent : content) {
        for (String text : aContent) {
            contentStream.beginText();
            contentStream.newLineAtOffset(textx, texty);
            contentStream.showText(text);
            contentStream.endText();
            textx += colWidth;
        }
        texty -= rowHeight;
        textx = margin + cellMargin;
    }
}

El uso actualiza para utilizar la tratar -con-recursos instrucción para cerrar adecuadamente los recursos:

try (PDDocument doc = new PDDocument()) {
    PDPage page = new PDPage();
    doc.addPage(page);

    try (PDPageContentStream contentStream = new PDPageContentStream(doc, page)) {
        String[][] content = {{"a", "b", "1"},
            {"c", "d", "2"},
            {"e", "f", "3"},
            {"g", "h", "4"},
            {"i", "j", "5"}};
        drawTable(page, contentStream, 700.0f, 100.0f, content);
    }
    doc.save("test.pdf");
}

Desde que tuve el mismo problema hace un tiempo empecé a construir una pequeña biblioteca para ello las cuales yo también estoy tratando de mantenerse al día.

Utiliza Apache 2.x PDFBox y se puede encontrar aquí: https://github.com/vandeseer/easytable

Permite que desde hace algunos personalizaciones como establecer el tipo de letra, color de fondo, relleno, etc. en el nivel celular, la alineación vertical y horizontal, que se extiende celular, ajuste de texto y las imágenes en las células.

Dibujo tablas en varias páginas también es posible.

Se puede crear tablas como esta por ejemplo:

 introducir descripción de la imagen aquí

El código para este ejemplo se puede encontrar aquí - otros ejemplos en la misma carpeta también.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top