[英]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.