使用iText创建一个带有重复标题的表

时间:2018-05-22 11:23:09

标签: java pdf itext

我想创建一个包含重复读取器的表,例如我附加到帖子中的图像。

我想将左边的前三列填充到表的末尾,然后填充表右侧的后三列。

我使用了一个包含6列的表,如页面所示。​​我根据日期顺序从数据库中获取数据,我想将数据放在表格中,如图片所示。

我可以在java中用iText创建一个表,但我不知道如何用iText创建一个带有这种风格的表。如果有可能请帮助我。

Table style

2 个答案:

答案 0 :(得分:2)

这是相对简单的。

首先,我创建了一个代表单个数据条目的类。

static class Record{
    public String firstname;
    public String lastname;
    public Record(String firstname, String lastname){
        this.firstname = firstname;
        this.lastname = lastname;
    }
    public String getFirstname(){return firstname;}
    public String getLastname(){return lastname;}
    public boolean equals(Object o){
        if(o instanceof Record){
            Record r = (Record) o;
            return r.firstname.equals(firstname) && r.lastname.equals(lastname);
        }
        return false;
    }
}

我还制作了一个方法,使用“辛普森一家”中的字符随机生成此类对象。

private static Random RANDOM = new Random(System.currentTimeMillis());
public Record randomRecord(){
    String[] fn = {"Marge", "Homer", "Bart", "Lisa", "Nelson", "Apu", "Doris", "Seymour"};
    String[] ln = {"Bouvier", "Simpson", "Muntz", "Nahasapeemapetilan", "Skinner"};
    return new Record(fn[RANDOM.nextInt(fn.length)], ln[RANDOM.nextInt(ln.length)]);
}

生成表格的代码如下所示:

    List<Record> recordList = new ArrayList<>();
    for(int i=0;i<17;i++)
        recordList.add(randomRecord());

    File outputFile = getOutputFile();
    PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outputFile));
    Document layoutDocument = new Document(pdfDocument);

    int numberOfItemsInFirstHalf = (int) Math.ceil(recordList.size() / 2.0);

    Table table = new Table(new float[]{0.16f, 0.16f, 0.16f, 0.16f, 0.16f, 0.16f});

    // header
    for(int i=0;i<2;i++) {
        table.addCell(new Cell().add(new Paragraph("Number")).setBackgroundColor(new DeviceRgb(74,189,172)));
        table.addCell(new Cell().add(new Paragraph("Firstname")).setBackgroundColor(new DeviceRgb(74,189,172)));
        table.addCell(new Cell().add(new Paragraph("Lastname")).setBackgroundColor(new DeviceRgb(74,189,172)));
    }

    // table
    for(int i=0;i<numberOfItemsInFirstHalf;i++){
        Record r0 = recordList.get(i);
        Record r1 = (i+numberOfItemsInFirstHalf) < recordList.size() ? recordList.get(i + numberOfItemsInFirstHalf) : null;

        table.addCell(new Cell().add(new Paragraph((i + 1)+"")));
        table.addCell(new Cell().add(new Paragraph(r0.getFirstname())));
        table.addCell(new Cell().add(new Paragraph(r0.getLastname())));

        if(r1 == null){
            table.addCell(new Cell().add(new Paragraph("")));
            table.addCell(new Cell().add(new Paragraph("")));
            table.addCell(new Cell().add(new Paragraph("")));
        }else{
            table.addCell(new Cell().add(new Paragraph((i + numberOfItemsInFirstHalf + 1)+"")));
            table.addCell(new Cell().add(new Paragraph(r1.getFirstname())));
            table.addCell(new Cell().add(new Paragraph(r1.getLastname())));
        }
    }

    layoutDocument.add(table);

    pdfDocument.close();

生成以下PDF文档:

enter image description here

答案 1 :(得分:0)

我不太明白你希望如何在分割时处理你的表,并且假设你正在寻找一个两列的布局。如果是这种情况,那么您可以预定义ColumnDocumentRenderer课程。如果在Document实例上设置,则允许将文档内容布局为列。

所以我定义了列:

Rectangle pageSize = pdfDocument.getDefaultPageSize(); Rectangle[] areas = new Rectangle[2]; areas[0] = new Rectangle(36, 36, ((float) pageSize.getWidth() / 2) - 35.75f, pageSize.getHeight() - 72); areas[1] = new Rectangle((float) pageSize.getWidth() / 2 - 0.25f, 36, ((float) pageSize.getWidth() / 2) - 35.75f , pageSize.getHeight() - 72);

然后我在Document实例上应用了渲染器: layoutDocument.setRenderer(new ColumnDocumentRenderer(layoutDocument, areas));

分裂的结果看起来如此: enter image description here

完整的代码:

    @Test
public void tableTest02() throws Exception {
    String outFileName = destinationFolder + "tableTest02.pdf";
    String cmpFileName = sourceFolder + "cmp_tableTest02.pdf";

    PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
    Document layoutDocument = new Document(pdfDocument);


    Table table = new Table(3);
    table.setWidth(UnitValue.createPercentValue(100));

    Rectangle pageSize = pdfDocument.getDefaultPageSize();
    Rectangle[] areas = new Rectangle[2];
    areas[0] = new Rectangle(36, 36, ((float) pageSize.getWidth() / 2) - 35.75f, pageSize.getHeight() - 72);
    areas[1] = new Rectangle((float) pageSize.getWidth() / 2 - 0.25f, 36, ((float) pageSize.getWidth() / 2) - 35.75f , pageSize.getHeight() - 72);

    layoutDocument.setRenderer(new ColumnDocumentRenderer(layoutDocument, areas));
    // header
    for(int i=0;i<1;i++) {
        table.addHeaderCell(new Cell().add(new Paragraph("Number")).setBackgroundColor(new DeviceRgb(74,189,172)));
        table.addHeaderCell(new Cell().add(new Paragraph("Firstname")).setBackgroundColor(new DeviceRgb(74,189,172)));
        table.addHeaderCell(new Cell().add(new Paragraph("Lastname")).setBackgroundColor(new DeviceRgb(74,189,172)));
    }

    // table
    for(int i=0;i<500;i++){

        table.addCell(new Cell().add(new Paragraph((i + 1)+"")));
        table.addCell(new Cell().add(new Paragraph("Hello")));
        table.addCell(new Cell().add(new Paragraph("World")));

    }

    layoutDocument.add(table);

    pdfDocument.close();

    Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff"));
}

棘手的时刻是折叠桌面边框但是用0.25f增加宽度并在左边移动右边的列0.25f我实现了一个放在另一个上的边框。