我尝试在iText中绘制一些嵌套表格,因为我认为这是定位所有内容的最简单方法。
所以我在另一个表中有多个表,它们都有背景颜色和/或笔画(通过PdfPCellEvents)。不幸的是,外表的笔划与内表的背景重叠。
我认为这来自于我的PdfPCellEvents中应用错误的订单或错误的集合saveState
或restoreState
。
任何人都可以向我解释saveState
和restoreState
的正确用法,并给我一个如何以正确的方式应用背景和笔画的提示吗?
以下是我添加条纹背景单元格的代码:
PdfPCell scaleBackground = new PdfPCell();
scaleBackground.setBorder(Rectangle.NO_BORDER);
scaleBackground.setVerticalAlignment(Element.ALIGN_TOP);
scaleBackground.setCellEvent(new StripedScaleBackground(max, scaleHeight));
StripedScaleBackground的cellLayout方法:
public void cellLayout(PdfPCell cell, Rectangle rect, PdfContentByte[] canvases)
{
PdfContentByte canvas = canvases[PdfPTable.LINECANVAS];
float llx = rect.getLeft();
float lly = rect.getBottom();
float urx = rect.getRight();
float ury = rect.getTop();
// Light scale lines with padding from left
canvas.setLineWidth(Constants.BORDER_WIDTH_THIN);
canvas.setColorStroke(Colors.LIGHT_GRAY);
float paddingLeft = 22f;
for (int i = 0; i <= this.maxValue; i++)
{
canvas.moveTo(llx + paddingLeft, lly + (this.scaleHeight * (i + 1)));
canvas.lineTo(urx, lly + (this.scaleHeight * (i + 1)));
}
// Vertical line
canvas.moveTo(llx + (((urx - llx) + paddingLeft) / 2), ury);
canvas.lineTo(llx + (((urx - llx) + paddingLeft) / 2), lly);
canvas.stroke();
// Fat line left and right
canvas.moveTo(llx, ury);
canvas.lineTo(llx, lly);
canvas.moveTo(urx, ury);
canvas.lineTo(urx, lly);
canvas.setLineWidth(0.8f);
canvas.setColorStroke(Colors.MEDIUM_GRAY);
canvas.stroke();
canvas.saveState();
canvas.restoreState();
}
条形图是表格,其中每个单元格都有渐变和边框的单元格事件。条形图被添加到第一段代码的scaleBackground
PdfPCell中,并具有以下PdfPCellEvents(图表中黑色部分的示例):
public void cellLayout(PdfPCell cell, Rectangle rect, PdfContentByte[] canvases)
{
PdfContentByte backgroundCanvas = canvases[PdfPTable.BACKGROUNDCANVAS];
float llx = rect.getLeft();
float lly = rect.getBottom();
float urx = rect.getRight();
float ury = rect.getTop();
// Draw background
// Define shading with direction and color
PdfShading shading = PdfShading.simpleAxial(this.writer,
llx, ury,
llx, lly,
Colors.BAR_CHART_BLACK_LIGHT, Colors.BAR_CHART_BLACK_DARK);
PdfShadingPattern pattern = new PdfShadingPattern(shading);
backgroundCanvas.setShadingFill(pattern);
// Draw shape with defined shading
backgroundCanvas.moveTo(llx, ury);
backgroundCanvas.lineTo(llx, lly);
backgroundCanvas.lineTo(urx, lly);
backgroundCanvas.lineTo(urx, ury);
backgroundCanvas.lineTo(llx, ury);
backgroundCanvas.fill();
backgroundCanvas.saveState();
backgroundCanvas.restoreState();
// Draw border
PdfContentByte lineCanvas = canvases[PdfPTable.LINECANVAS];
float lineWidth = Constants.BORDER_WIDTH_THIN;
lineCanvas.setLineWidth(lineWidth);
lineCanvas.moveTo(llx, ury - lineWidth);
lineCanvas.lineTo(llx, lly);
lineCanvas.lineTo(urx, lly);
lineCanvas.lineTo(urx, ury - lineWidth);
lineCanvas.setColorStroke(BaseColor.BLACK);
lineCanvas.stroke();
lineCanvas.saveState();
lineCanvas.restoreState();
}
答案 0 :(得分:0)
这是不同直接内容层的顺序:
PdfPtable.BASECANVAS
- 此处的任何内容都将在桌面下。PdfPtable.BACKGROUNDCANVAS
- 这是背景所在的图层
绘制。PdfPtable.LINECANVAS
- 这是绘制线条的图层。PdfPtable.TEXTCANVAS
- 这是文字所在的图层。放置任何东西
这里将涵盖表格。这取自第34页“动作 - 第二版中的iText”一书。&#34;
您还会询问saveState()
和restoreState()
。这在Chapter 2 of the iText 7 tutorial:
首先我们使用
saveState()
方法保存当前图形状态,然后我们更改状态并绘制我们想要绘制的任何线条或形状,最后,我们使用restoreState()
方法返回到原始图形状态。我们在saveState()
之后应用的所有更改都将被撤消。如果您更改多个值(线宽,颜色......)或难以计算反向变化(返回原始坐标系),这一点尤其有用。
您的代码太长,我无法检查,但我非常怀疑saveState()
/ restoreState()
会导致您的问题。
我会尽量避免嵌套表。使用colspan和rowspan通常更容易(也更有效)。
如果这不能解决您的问题,请用一句话解释您的问题。