使用pdfbox将表格绘制成pdf

时间:2019-02-28 07:32:23

标签: javafx pdfbox

所以我的任务是将应用程序的结果(与JavaFX一起使用)打印为pdf文件,以保存或打印它们。现在,我尝试将表格添加到pdf中,我正在寻找一种执行此操作的好方法(外观和性能)。我想到了两种可能的方法。第一个是创建表的快照并将其添加到pdf中。这对我来说似乎是一种简单的方法,但是后来我认为,如果表中有太多行以至于它可以容纳在一页上(我使用的是A4格式),那将是行不通的。另一种方法是在pdf文件中绘制一个新表。如果表格的高度在某个点,我可以添加一个分页符,然后继续下一页。我将能够处理外观并使它看起来不错,但是从性能角度来看,我不知道这是否是最佳方法。有人这样做吗?或者有人有我没想到的其他方式?

1 个答案:

答案 0 :(得分:1)

我正计划尽快实现与我的应用类似的功能。
使用PDF文件的最佳方法(我认为)是 iTextPDF 库。
您可以在https://itextpdf.com中找到示例和有关如何使用该库的信息。
快速示例(来源:https://itextpdf.com/en/resources/examples/itext-7/tables):

import com.itextpdf.kernel.color.Color;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.VerticalAlignment;
import com.itextpdf.test.annotations.WrapToTest;
import java.io.File;
import java.io.IOException;

@WrapToTest
public class HelloWorldTable {
    public static final String DEST
        = "results/javaone16/hello_table.pdf";  

    public static void main(String[] args) throws IOException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new HelloWorldTable().createPdf(DEST);
    }

    public void createPdf(String dest) throws IOException {
        PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
        try (Document document = new Document(pdf)) {
            Table table = new Table(3);
            Cell cell = new Cell(1, 3)
                .setTextAlignment(TextAlignment.CENTER)
                .add("Cell with colspan 3");
            table.addCell(cell);
            cell = new Cell(2, 1)
                .add("Cell with rowspan 2")
                .setVerticalAlignment(VerticalAlignment.MIDDLE);
            table.addCell(cell);
            table.addCell("Cell 1.1");
            table.addCell(new Cell().add("Cell 1.2"));
            table.addCell(new Cell()
                .add("Cell 2.1")
                .setBackgroundColor(Color.LIGHT_GRAY)
                .setMargin(5));
            table.addCell(new Cell()
                .add("Cell 1.2")
                .setBackgroundColor(Color.LIGHT_GRAY)
                .setPadding(5));
            document.add(table);
        }
    }
}

您可以通过从源代码(TreeTableView,ListView等)创建一个foreach循环来自动添加行,也可以在 for if 循环。 >循环以限制要添加到表中的行。
快速示例代码如何执行:

//how much free space you have on your pdf page
int rowLimit = 15;
for (int i=0; i<rowLimit; i++){
    //add rows to your table
    //...
    }

,或者如果达到限制,则可以继续在新页面中添加新行。
示例代码:

//how much free space you have on your pdf page
int rowLimit = 15;
int i=0;
//MyDataObject is an Object example where to get data from
//myListOfData is a List where all MyDataObject are stored
for (MyDataObject object : myListOfData){
    if(i=rowLimit){
        //create new page if limit is reached
        document.newPage();
        i=0; //reset row counter
    }
    i++;
    //add rows to your table
    //...
}
  

更新:

如果要使用 PDFBox 库,可以使用以下示例:
(原始/未经编辑的源代码:http://pdfboxtutorial.blogspot.com/2014/08/pdfbox-tutorial-creating-table-in-pdf.html

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;

/**
 * @author Bharathi Raja
 */
public class CreatePDFBOXTable {

public static void main(String[] args) {
    try {
        createTable();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void createTable() throws Exception {
    String path = "d:\\tablepdf.pdf";  //location to store the pdf file
    PDDocument document = new PDDocument();
    PDPage page = new PDPage(PDPage.PAGE_SIZE_A4);
    document.addPage(page);
    PDPageContentStream contentStream = new PDPageContentStream(document, page);

    PDRectangle mediabox = page.findMediaBox();
    float margin = 50;
    float startX = mediabox.getLowerLeftX() + margin;
    float startY = mediabox.getUpperRightY() - margin;
    final float rowHeight = 20f;



    //SPECIFY THE NUMBER OF ROWS TO BE CREATED
    //example: use list.size() to get the number of elements
    final int rows = 3;



    final float tableWidth = page.findMediaBox().getWidth() - (2 * margin);

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

    contentStream.drawLine(margin, 300, margin + tableWidth, 300);
    int y = 650;

    //drawing columns the columns
    float nextx = 50;

    int h = 300;
    contentStream.drawLine(nextx, y, nextx, h);
    nextx = 100;
    contentStream.drawLine(nextx, y, nextx, h);
    nextx = 350;
    contentStream.drawLine(nextx, y, nextx, h);
    nextx = 420;
    contentStream.drawLine(nextx, y, nextx, h);
    nextx = 475;
    contentStream.drawLine(nextx, y, nextx, h);
    nextx = 545;
    contentStream.drawLine(nextx, y, nextx, h);

    //now add the text

    contentStream.close();

    document.save(path);
    document.close();
    }
}

如果您想使用 foreach 循环继续写到下一页,则可以在上面编辑我的示例,替换为:

document.newPage();

具有:

//set page format
PDPage page = new PDPage(PDPage.PAGE_SIZE_A4);
document.addPage(page);

希望有帮助!