vandeseer / easytable

Small table drawing library built upon Apache PDFBox
MIT License
239 stars 91 forks source link

Overlapping borders #42

Open aatoma opened 5 years ago

aatoma commented 5 years ago

I'm facing an issue with borders of different color and width. The output of the following snippet of code is attached test.pdf

public static void main(String[] args) {

        try (PDDocument doc = new PDDocument()) {

            String header = "HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER "
                    + "HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER "
                    + "HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER "
                    + "HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER HEADER ";

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

                    final TableBuilder tableBuilder = Table.builder()
                            .addColumnsOfWidth(250, 250);
                    final org.vandeseer.easytable.structure.Row headerRow = org.vandeseer.easytable.structure.Row.builder()
                            .add(CellText.builder().text(header).horizontalAlignment(CENTER).colSpan(2).borderColor(Color.BLACK).borderWidth(1).build())
                            .backgroundColor(Color.WHITE)
                            .textColor(Color.BLACK)
                            .font(PDType1Font.HELVETICA_BOLD)
                            .fontSize(11)
                            .build();
                    tableBuilder.addRow(headerRow);

                    for (int row = 0; row < 10 ; row++) {

                        final org.vandeseer.easytable.structure.Row dataRow = org.vandeseer.easytable.structure.Row.builder()
                                .add(CellText.builder()
                                        .text("Name"+row)
                                        .horizontalAlignment(LEFT)
                                        .backgroundColor(Color.WHITE)
                                        .textColor(Color.BLACK)
                                        .borderColor(Color.WHITE)
                                        .borderWidth(0.5f).build())
                                .add(CellText.builder()
                                        .text("Value"+row)
                                        .horizontalAlignment(RIGHT)
                                        .backgroundColor(Color.CYAN)
                                        .textColor(Color.BLUE)
                                        .borderColor(Color.BLACK)
                                        .borderWidth(0.5f).build())

                                .font(PDType1Font.HELVETICA_BOLD)
                                .fontSize(9)
                                .build();
                        tableBuilder.addRow(dataRow);
                        final org.vandeseer.easytable.structure.Row spareRow = org.vandeseer.easytable.structure.Row.builder()
                                .add(CellText.builder()
                                        .text("Spare"+row)
                                        .horizontalAlignment(LEFT)
                                        .backgroundColor(Color.WHITE)
                                        .textColor(Color.BLACK)
                                        .font(PDType1Font.HELVETICA_OBLIQUE)
                                        .borderColor(Color.WHITE)
                                        .borderWidth(1).build())
                                .add(CellText.builder()
                                        .text("")
                                        .horizontalAlignment(RIGHT)
                                        .backgroundColor(Color.WHITE)
                                        .textColor(Color.BLUE)
                                        .borderColor(Color.WHITE)
                                        .borderWidth(1).build())

                                .font(PDType1Font.HELVETICA_BOLD).fontSize(9)
                                .build();
                        tableBuilder.addRow(spareRow);
                    }
                    String footer = "FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER "
                            + "FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER "
                            + "FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER "
                            + "FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER FOOTER ";
                    final org.vandeseer.easytable.structure.Row footerRow = org.vandeseer.easytable.structure.Row.builder()
                            .add(CellText.builder().text(footer).horizontalAlignment(CENTER).colSpan(2).borderWidth(1).build())
                            .backgroundColor(TURQUOISE)
                            .textColor(Color.BLACK)
                            .font(PDType1Font.HELVETICA_BOLD).fontSize(9)
                            .build();
                    tableBuilder.addRow(footerRow);
                    try (final PDPageContentStream contentStream = new PDPageContentStream(doc, page)) {

                        float startY = page.getMediaBox().getHeight() - PADDING;
                        Table pdfTable = tableBuilder.build();
                        TableDrawer.builder()
                                .contentStream(contentStream)
                                .table(pdfTable)
                                .startX(PADDING)
                                .startY(startY)
                                .build()
                                .draw();

                    }
                    String fileName="test.pdf";
            doc.save(fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

the upper white border of the first name cell, falls in the middle of the thicker black header border, while the upper white border of spare rows hides the lower black border of value cells. Is this a real issue or am I doing something wrong?

vandeseer commented 5 years ago

Hey @aatoma,

even though I can't have a proper look right now (I am traveling and I don't have a computer with me), I can hopefully already give you some ideas on how to overcome your issue: The drawing of the borders is done from top left cell to bottom right cell, one by one (if I recall that correctly). That means if there is a cell with all borders (top, bottom, left, right) being red and the cell below has all borders blue the top border of that cell will override the bottom border of the cell above, i.e. the line will be "collapsed" and will be blue.

So the thing is there is no concept of non collapsible borders in the current implementation. What can be done though (which is a little bit cumbersome) is to only explicitly specify the borders that are actually needed (e.g. omitting a top border).

Another option is to write a TableDrawer class of its own that has a different way of handling borders.

Hope this helps!