2016-05-23 55 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

相關問題