有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我想将圆角边框应用到桌子上。这张桌子是动态的。这意味着它可以扩展到多个页面,也可以容纳在单个页面中

如果表格是单页的,则所有四个角单元格的最外角应画为圆角。 如果表格可以扩展到多页(比如3页),那么所有四个角单元格的最外角都应该为所有3页绘制为圆角

下面是我用来实现上述场景的方法

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

桌面渲染器。爪哇

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

现在,代码按预期运行良好,但渲染存在问题。当我在桌面边框顶部绘制白色边框时,它不会完全重叠。此外,外部红色边框也在预期区域的稍外侧绘制。简单地说,白色矩形和红色矩形并不重合。所以在外边界和细胞边界之间有一些间隙。 我附上了上述代码生成的输出。要注意这个问题,您可能需要将PDF放大一点

我对此也有一些疑问: 我正在使用顶部画布来获得预期的解决方案。但是,有没有什么方法可以在渲染时直接修改表边框?我试过了

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

但在这种方法中,边界与单元边界重叠(也需要单元边界)。如果我错过了防止这个问题的方法,请指导我

谢谢


共 (1) 个答案

  1. # 1 楼答案

    getOccupiedAreaBBox方法提供边界区域的外部边界框。但是,边框本身有厚度,在PDF中绘制线条时,默认情况下,当您传递外部bbox坐标时,应将线条的中心传递给绘图操作,从而产生较小的边距和不精确的重叠

    要解决此问题,需要将边框线宽度的一半添加到矩形的所有边上:

    float lineWidth = 0.5f;
    rect.applyMargins(lineWidth / 2, lineWidth / 2, lineWidth / 2, lineWidth / 2, false);
    

    总之,以下定制代码:

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

    产生以下视觉效果:

    result