Apache PDFBox Java 库 - 是否有用于创建表格的 API?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3871879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 06:10:37  来源:igfitidea点击:

Apache PDFBox Java library - Is there an API for creating tables?

javaapachegraphicspdfbox

提问by Keshav

I am using the Apache PDFBox java library to create PDFs. Is there a way to create a data-table using pdfbox? If there is no such API to do it, I would require to manually draw the table using drawLine etc., Any suggestions on how to go about this?

我正在使用 Apache PDFBox java 库来创建 PDF。有没有办法使用pdfbox创建数据表?如果没有这样的 API,我需要使用 drawLine 等手动绘制表格,有关如何解决此问题的任何建议?

采纳答案by dogbane

Source: Creating tables with PDFBox

来源使用 PDFBox 创建表格

The following method draws a table with the specified table content. Its a bit of a hack and will work for small strings of text. It does not perform word wrapping, but you can get an idea of how it is done. Give it a go!

以下方法绘制具有指定表格内容的表格。它有点黑客,适用于小字符串。它不执行自动换行,但您可以了解它是如何完成的。搏一搏!

/**
 * @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;
    }
}

Usage:

用法:

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

回答by quodlibet

I created a small api for creating tables using PDFBox. It can be found on github ( https://github.com/dhorions/boxable) .

我创建了一个使用 PDFBox 创建表格的小 api。它可以在 github ( https://github.com/dhorions/boxable)上找到。

A sample of a generated pdf can be found here http://goo.gl/a7QvRM.

可以在此处找到生成的 pdf 示例http://goo.gl/a7QvRM

Any hints or suggestions are welcome.

欢迎任何提示或建议。

回答by Nicolas Filotto

The accepted answer is nice but it will work with Apache PDFBox 1.xonly, for Apache PDFBox 2.xyou will need to modify a little bit the code to make it work properly.

接受的答案很好,但它仅适用于Apache PDFBox 1.x,对于Apache PDFBox 2.x,您需要稍微修改代码以使其正常工作。

So here is the same code but that is compatible with Apache PDFBox 2.x:

所以这是相同的代码,但与Apache PDFBox 2.x兼容:

The method drawTable:

方法drawTable

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

The Usage updated to use the try-with-resourcesstatement to close the resources properly:

用法更新为使用try-with-resources语句正确关闭资源:

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

回答by philonous

Since I had the same problem some time ago I started to build a small library for it which I am also trying to keep up to date.

由于前段时间我遇到了同样的问题,因此我开始为它构建一个小型库,我也在努力保持最新状态。

It uses Apache PDFBox 2.xand can be found here: https://github.com/vandeseer/easytable

它使用Apache PDFBox 2.x,可以在这里找到:https: //github.com/vandeseer/easytable

It allows for quite some customizations like setting the font, background color, padding etc. on the cell level, vertical and horizontal alignment, cell spanning, word wrapping and images in cells.

它允许进行相当多的自定义,例如在单元格级别设置字体、背景颜色、填充等、垂直和水平对齐、单元格跨度、自动换行和单元格中的图像。

Drawing tables across several pages is also possible.

也可以跨多个页面绘制表格。

You can create tables like this for instance:

例如,您可以创建这样的表:

enter image description here

在此处输入图片说明

The code for this example can be found here– other examples in the same folder as well.

可以在此处找到此示例的代码- 同一文件夹中的其他示例也是如此。