java表格圆角,如何将圆角边框应用于表格(单页/多页)?

I want to apply round corner border to a table. This table is dynamic. That means it can grow up to multiple pages or can accommodate in single page.

If table comes in single page, then outermost corner of all four corner cells should be drawn as rounded.

If table grows up to multiple pages (say 3 pages), then outermost corner of all four corner cells should be drawn as rounded for all 3 pages.

Here is the approach which I am using to implement the above scenario.

public void createPdf(String dest) throws FileNotFoundException {

PdfWriter writer = new PdfWriter(DEST);

PdfDocument pdfDoc = new PdfDocument(writer);

Document document = new Document(pdfDoc, PageSize.A4, false);

Table table = new Table(3);

for (int i=0; i < 100; i++) {

for (int j=0; j < 3; j++) {

table.addCell(new Cell().add(new Paragraph("Cell content")));

}

}

table.setNextRenderer(new TableBorderRenderer(table));

document.add(table);

document.close();

}

TableBorderRenderer.java

public class TableBorderRenderer extends TableRenderer {

public TableBorderRenderer(Table modelElement) {

super(modelElement);

}

@Override

public IRenderer getNextRenderer() {

return new TableBorderRenderer((Table) modelElement);

}

@Override

protected void drawBorders(DrawContext drawContext) {

Rectangle rect = getOccupiedAreaBBox();

PdfPage currentPage = drawContext.getDocument().getPage(getOccupiedArea().getPageNumber());

PdfCanvas aboveCanvas = new PdfCanvas(currentPage.newContentStreamAfter(), currentPage.getResources(), drawContext.getDocument());

// drawing white rectangle over table border in order to hide it.

aboveCanvas.saveState().setStrokeColor(new DeviceRgb(255,255,255)).rectangle(rect).stroke().restoreState();

// drawing red round rectangle which will be shown as boundary.

aboveCanvas.saveState().setLineWidth(0.5f).setStrokeColor(new DeviceRgb(255,0,0)).roundRectangle(rect.getLeft(), rect.getBottom(), rect.getWidth(), rect.getHeight(), 5).stroke().restoreState();

super.drawBorders(drawContext);

}

}

Now the code is working fine as it is supposed to be, but there is an issue with the rendering. when i draw the white border on top of table border it does not overlap it completely. Also the outer red border is drawn slightly outside the expected area. In simple words, white rectangle and red rectangle are not coinciding with each other. So there is some gap coming between the outer border and cell borders.

I am attaching the generated output from above code. To notice the issue you might need to zoom the PDF a little bit.

I have some doubts regarding the same:

I am using a top canvas to get the expected solution. But is there any approach in which I can modify the table border directly while rendering? I tried

drawContext.getCanvas()

.saveState()

.roundRectangle(rect.getLeft(), rect.getBottom(), rect.getWidth(), rect.getHeight(), 5).stroke().restoreState();

But in this approach border is overlapped by the cell borders (cell borders are needed as well). If I am missing something to prevent this issue, guide me.

Thanks.

解决方案

The getOccupiedAreaBBox method gives you the outer bounding box of the border area. Borders, however, have thickness on their own, and when you draw lines in PDF by default you should pass the center of the line to the drawing operation, while you are passing the outer bbox coordinates, hence the small margin and imprecise overlap.

To fix the issue, you need to add half of the border line width to all of the edges of your rectangle:

float lineWidth = 0.5f;

rect.applyMargins(lineWidth / 2, lineWidth / 2, lineWidth / 2, lineWidth / 2, false);

All in all, the following customized code:

@Override

protected void drawBorders(DrawContext drawContext) {

Rectangle rect = getOccupiedAreaBBox();

PdfPage currentPage = drawContext.getDocument().getPage(getOccupiedArea().getPageNumber());

PdfCanvas aboveCanvas = new PdfCanvas(currentPage.newContentStreamAfter(), currentPage.getResources(), drawContext.getDocument());

float lineWidth = 0.5f;

rect.applyMargins(lineWidth / 2, lineWidth / 2, lineWidth / 2, lineWidth / 2, false);

// drawing white rectangle over table border in order to hide it.

aboveCanvas.saveState().setLineWidth(lineWidth).setStrokeColor(new DeviceRgb(255,255,255)).rectangle(rect).stroke().restoreState();

// drawing red round rectangle which will be shown as boundary.

aboveCanvas.saveState().setLineWidth(lineWidth).setStrokeColor(new DeviceRgb(255,0,0))

.roundRectangle(rect.getLeft(), rect.getBottom(), rect.getWidth(), rect.getHeight(), 5).stroke().restoreState();

super.drawBorders(drawContext);

}

Yields the following visual result:

jbMca.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值