簡體   English   中英

如何在iText7中將背景顏色應用於帶有圓角的表格單元格?

[英]How to apply background color to table cell with round corners in iText7?

我正在畫圓角的桌子。 該表是動態的,可以增長到多個頁面。 現在我想為單元格應用一些背景顏色。 每個單元格可以有自己不同的顏色(非硬編碼)。 但問題是當我將背景顏色應用於角落單元格時,顏色會從角落溢出。 角單元的外角是圓形的。 圓角的實現是使用這種方法https://stackoverflow.com/a/62764267/13446374完成的。

為了實現這一點,我創建了一個單元格渲染器,它覆蓋了 drawBackground() 方法來繪制預期的結果。

CellBackgroundColorRenderer.java

public class CellBackgroundColorRenderer extends CellRenderer {
    protected Color color;
    protected boolean isColoredBackground;
 
    public CellBackgroundColorRenderer(Cell modelElement, Color color, boolean isColoredBackground) {
        super(modelElement);
        this.color = color;
        this.isColoredBackground = isColoredBackground;
    }
 
    @Override
    public void drawBackground(DrawContext drawContext) {
        Rectangle rect = getOccupiedAreaBBox();
        PdfCanvas canvas = drawContext.getCanvas();
        
        // drawing white rectangle on top any pre existing background color. 
        canvas.saveState().rectangle(rect).setFillColor(new DeviceRgb(255, 255, 255)).fillStroke().restoreState();
        
        // drawing round corner rectangle for colored bg.
        canvas.saveState().roundRectangle(rect.getLeft(),rect.getBottom(), rect.getWidth(), rect.getHeight(), 5).setFillColor(color).fillStroke();
       
        // TODO fill color in those cell corners which are in conjuntion with other cells. 
        canvas.restoreState();
 
    }
}

TableBorderRenderer.java

public class TableBorderRenderer extends TableRenderer {
    
    private int numberOfColumns;
    public TableBorderRenderer(Table modelElement) {
        super(modelElement);
        numberOfColumns = modelElement.getNumberOfColumns();
    }

    @Override
    public IRenderer getNextRenderer() {
        return new TableBorderRenderer((Table) modelElement);
    }

    @Override
    public void draw(DrawContext drawContext) {

        CellRenderer[] cellRenderers = rows.get(0);
        
        Cell cell = (Cell) cellRenderers[0].getModelElement();
        ((Cell) cellRenderers[0].getModelElement()).setNextRenderer(new CellBackgroundColorRenderer((Cell) cellRenderers[0].getModelElement(), new DeviceRgb(255, 150, 255), true));
        
        ((Cell) cellRenderers[numberOfColumns-1].getModelElement()).setNextRenderer(new CellBackgroundColorRenderer((Cell) cellRenderers[numberOfColumns-1].getModelElement(), new DeviceRgb(255, 150, 255), true));

        super.draw(drawContext);
    }
    
    @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);
        
        aboveCanvas.saveState().setStrokeColor(new DeviceRgb(255,255,255)).rectangle(rect).stroke().restoreState();
        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);
    }
}

表Test.java

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 的 draw() 中,我將 CellBackgroundColorRenderer 設置為模態元素,即單元格。 現在,我只為第一行設置 CellBackgroudnColorRenderer。 但是當我運行程序時,cellRenderer的drawBackground()中甚至沒有go。

我不確定我在這里缺少什么。 我的方法正確嗎? 如果沒有,你能用正確的方法指導我嗎?

謝謝。

無需手動繪制單元格的背景顏色 - 該功能已經存在:

Table table = new Table(3);
for (int i=0; i < 100; i++) {
    for (int j=0; j < 3; j++) {
        table.addCell(new Cell()
                .setBackgroundColor(ColorConstants.GREEN)
                .add(new Paragraph("Cell content")));
    }
}
table.setNextRenderer(new TableBorderRenderer(table));
document.add(table);

您唯一需要做的就是剪裁那些在圓角之外繪制的背景。 為此,您可以在TableRenderer中重載drawChildren

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

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

        aboveCanvas.saveState().setLineWidth(lineWidth).setStrokeColor(new DeviceRgb(255,255,255)).rectangle(rect).stroke().restoreState();
        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);
    }

    @Override
    public void drawChildren(DrawContext drawContext) {
        Rectangle rect = getOccupiedAreaBBox();
        float lineWidth = 0.5f;
        rect.applyMargins(lineWidth, lineWidth, lineWidth, lineWidth, false);

        PdfCanvas canvas = drawContext.getCanvas();
        canvas.saveState();
        canvas.roundRectangle(rect.getLeft(), rect.getBottom(), rect.getWidth(), rect.getHeight(), 5);
        canvas.clip().endPath();
        super.drawChildren(drawContext);
        canvas.restoreState();
    }
}

視覺結果:

結果

我更新了 TableRenderer,所以它用給定的顏色和給定的半徑繪制圓角邊框。

using iText.Kernel.Colors;
using iText.Kernel.Pdf.Canvas;
using iText.Layout.Element;
using iText.Layout.Renderer;
using iText.Kernel.Colors;


public class TableBorderRenderer : TableRenderer
{
    private const float lineWidth = 0.5f;
    private readonly float _radius;
    private readonly Color _color;

    public TableBorderRenderer(Table modelElement, float radius, Color color = null) : base(modelElement)
    {
        _radius = radius;
        _color = color ?? PdfColors.White;
    }

    public override IRenderer GetNextRenderer()
    {
        return new TableBorderRenderer((Table)modelElement, _radius, _color);
    }

    protected override void DrawBorders(DrawContext drawContext)
    {
        var rect = GetOccupiedAreaBBox();
        var currentPage = drawContext
            .GetDocument()
            .GetPage(GetOccupiedArea().GetPageNumber());

        var aboveCanvas = new PdfCanvas(currentPage.NewContentStreamAfter(), currentPage.GetResources(), drawContext.GetDocument());

        rect.ApplyMargins(lineWidth, lineWidth, lineWidth, lineWidth, false);

        aboveCanvas
            .SaveState()
            .SetLineWidth(lineWidth)
            .SetStrokeColor(_color)
            .RoundRectangle(rect.GetLeft(), rect.GetBottom(), rect.GetWidth(), rect.GetHeight(), _radius)
            .Stroke()
            .RestoreState();

        base.DrawBorders(drawContext);
    }

    public override void DrawChildren(DrawContext drawContext)
    {
        var rect = GetOccupiedAreaBBox();
        rect.ApplyMargins(lineWidth, lineWidth, lineWidth, lineWidth, false);

        var canvas = drawContext
            .GetCanvas()
            .SaveState()
            .RoundRectangle(rect.GetLeft(), rect.GetBottom(), rect.GetWidth(), rect.GetHeight(), _radius)
            .Clip()
            .EndPath();

        base.DrawChildren(drawContext);
        canvas.RestoreState();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM