2016-05-23 60 views
1

我试图在iText中绘制一些嵌套表格,因为我认为这将是定位一切的最简单方法。有人可以解释iTexts画布的绘制顺序吗?

enter image description here

所以我还有一个表谁都有背景颜色和/或中风(通过PdfPCellEvents)内的多个表。不幸的是,外表的笔画与内表的背景重叠。 我假设来自错误的申请顺序或一些错误的设置saveStaterestoreState在我的PdfPCellEvents。

任何人都可以解释saveStaterestoreState对我的正确用法,并给我一个提示如何应用背景和笔画正确的方式吗?

这是我的用于添加条纹背景细胞代码:StripedScaleBackground的

PdfPCell scaleBackground = new PdfPCell(); 
scaleBackground.setBorder(Rectangle.NO_BORDER); 
scaleBackground.setVerticalAlignment(Element.ALIGN_TOP); 
scaleBackground.setCellEvent(new StripedScaleBackground(max, scaleHeight)); 

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

这是不同的直接内容层的顺序:

  • PdfPtable.BASECANVAS - 这里放置的东西都在桌子下面。
  • PdfPtable.BACKGROUNDCANVAS - 这是绘制背景为 的图层。
  • PdfPtable.LINECANVAS - 这是绘制线条的图层。
  • PdfPtable.TEXTCANVAS - 这是文本所在的图层。这里放置的任何东西 将覆盖表格。

这是取自“iText in Action - Second Edition”一书。

您还可以问问saveState()restoreState()。这在Chapter 2 of the iText 7 tutorial解释说:

首先,我们保存当前的图形状态与saveState()方法,那么我们就改变状态,并绘制任何线条或形状,我们想绘制,最后,我们使用restoreState()方法返回原始图形状态。我们在saveState()之后应用的所有更改都将被撤消。如果您更改多个值(线宽,颜色...)或难以计算反转更改(返回到原始坐标系),这一点尤其有趣。

您的代码太长,我来检查,但我非常怀疑saveState()/restoreState()将是你的问题的原因。

我会尽量避免嵌套表。使用colspan和rowspan通常更容易(也更高效)。

如果这不能解决您的问题,请用一句话解释您的问题。

+0

感谢您的快速回答!我的问题是,我使用PdfPtable.LINECANVAS作为条纹背景,尽管它用作背景。我将其更改为PdfPtable.BACKGROUNDCANVAS,现在它可以正常工作! – odaa

相关问题