Itextsharp PDFPTable如何在整个表格周围制作边框

时间:2014-07-02 20:07:34

标签: c# itext

我正在通过带有PDFPTable的Itextsharp中的数据库构建一个表,并且要求表中没有行/单元格具有顶部或底部底部边框,但每个单元格的左侧和右侧都有黑色边框(换句话说,每列都有左边框和右边框),桌子的底部也需要用黑色边框封闭,这就是我的问题所在。

我正在做的是将边框设置为0,然后手动指定边框,以便我只在每个单元格上获得左右边框,如下面所示为生成“数量”列的示例:

    cell = new PdfPCell(new Phrase(Qty.value, subheaderFont));
    cell.HorizontalAlignment = Element.ALIGN_CENTER;
    cell.VerticalAlignment = Element.ALIGN_MIDDLE; 
    cell.BackgroundColor = new iTextSharp.text.BaseColor(220, 220, 220);
    cell.Border = 0;
    cell.BorderColorLeft = BaseColor.BLACK;
    cell.BorderWidthLeft = .5f;
    cell.BorderColorRight = BaseColor.BLACK;
    cell.BorderWidthRight = .5f;
    table.AddCell(cell); 

问题显然是我无法检测最后一行添加border-bottom,但我想必须有一种方法来控制“表”本身的边界,或者我采取了错误的方法对此?

4 个答案:

答案 0 :(得分:2)

正如您所发现的,PdfPTable没有边框,可能是因为PDF首先没有表格。将边框直接放在PdfPCell上可能更有意义(即使PDF也不支持这些边框)。无论如何,表只是一组单元格,所以让他们处理它。

无论如何,解决方案是在TableEvent类的实例上设置PdfPTable。为此,您需要IPdfPTableEvent接口的自定义实现。以下代码通常应该为您执行此操作(请参阅底部的注释“通常”)

class TopBottomTableBorderMaker : IPdfPTableEvent {
    private BaseColor _borderColor;
    private float _borderWidth;

    /// <summary>
    /// Add a top and bottom border to the table.
    /// </summary>
    /// <param name="borderColor">The color of the border.</param>
    /// <param name="borderWidth">The width of the border</param>
    public TopBottomTableBorderMaker(BaseColor borderColor, float borderWidth ) {
        this._borderColor = borderColor;
        this._borderWidth = borderWidth;
    }
    public void TableLayout(PdfPTable table, float[][] widths, float[] heights, int headerRows, int rowStart, PdfContentByte[] canvases) {
        //widths (should be thought of as x's) is an array of arrays, first index is for each row, second index is for each column
        //The below uses first and last to calculate where each X should start and end
        var firstRowWidths = widths[0];
        var lastRowWidths = widths[widths.Length - 1];

        var firstRowXStart = firstRowWidths[0];
        var firstRowXEnd = firstRowWidths[firstRowWidths.Length - 1] - firstRowXStart;

        var lastRowXStart = lastRowWidths[0];
        var lastRowXEnd = lastRowWidths[lastRowWidths.Length - 1] - lastRowXStart;

        //heights (should be thought of as y's) is the y for each row's top plus one extra for the last row's bottom
        //The below uses first and last to calculate where each Y should start and end
        var firstRowYStart = heights[0];
        var firstRowYEnd = heights[1] - firstRowYStart;

        var lastRowYStart = heights[heights.Length - 1];
        var lastRowYEnd = heights[heights.Length - 2] - lastRowYStart;

        //Where we're going to draw our lines
        PdfContentByte canvas = canvases[PdfPTable.LINECANVAS];

        //I always try to save the previous state before changinge anything
        canvas.SaveState();

        //Set our line properties
        canvas.SetLineWidth(this._borderWidth);
        canvas.SetColorStroke(this._borderColor);

        //Draw some rectangles
        canvas.Rectangle(
                        firstRowXStart,
                        firstRowYStart,
                        firstRowXEnd,
                        firstRowYEnd
                        );
        //They aren't actually drawn until you stroke them!
        canvas.Stroke();

        canvas.Rectangle(
                        lastRowXStart,
                        lastRowYStart,
                        lastRowXEnd,
                        lastRowYEnd
                        );
        canvas.Stroke();

        //Restore any previous settings
        canvas.RestoreState();

    }
}

使用它非常简单,只需将实例绑定到属性:

//Create your name as you normally do
var table = new PdfPTable(3);

//Bind and instance with properties set
table.TableEvent = new TopBottomTableBorderMaker(BaseColor.BLACK, 0.5f);

//The rest is the same
for (var i = 0; i < 6; i++) {
    var cell = new PdfPCell(new Phrase(i.ToString()));
    cell.HorizontalAlignment = Element.ALIGN_CENTER;
    cell.VerticalAlignment = Element.ALIGN_MIDDLE;
    cell.BackgroundColor = new iTextSharp.text.BaseColor(220, 220, 220);
    cell.Border = 0;
    cell.BorderColorLeft = BaseColor.BLACK;
    cell.BorderWidthLeft = .5f;
    cell.BorderColorRight = BaseColor.BLACK;
    cell.BorderWidthRight = .5f;
    table.AddCell(cell);
}

上面我说“一般”应该有效。但是,如果您有表格页眉和/或页脚,那么您也需要考虑这些内容。这不应该太难,但您需要调整占ytable.HeaderRows的{​​{1}}值。

答案 1 :(得分:2)

我遇到了同样的问题,发现了以下解决方案。 来自“iText In Action Second Edition” PdfPCell扩展了Rectangle,继承了大量的方法来改变绘制边框和绘制背景的方式。

方法“DisableBorderSide(int Rectangle)”是如何使用任何其他大小调整来删除边框。

PdfPCell cell = new PdfPCell(new Phrase("Some Text", FontFactory.GetFont("Arial", BaseFont.WINANSI, BaseFont.EMBEDDED, 13, Font.NORMAL, BaseColor.BLACK)));
cell.BackgroundColor = new BaseColor(255, 255, 255);
cell.HorizontalAlignment = Element.ALIGN_CENTER;
cell.BorderColor = BaseColor.BLACK;
cell.Border = Rectangle.BOX;
cell.BorderWidth = 1;
cell.DisableBorderSide(Rectangle.TOP_BORDER);
cell.DisableBorderSide(Rectangle.BOTTOM_BORDER);
cell.Padding = 3;
table.AddCell(cell);

答案 2 :(得分:2)

我使用嵌套表

解决了这个问题
'CREATE TWO PDFPTABLES
 Dim tblNested1 As New PdfPTable(1)
 Dim tblNested2 As New PdfPTable(3)

 'CREATE CELLS WITH NO BORDER AND ADD THEM TO TABLE2

 Dim cellNested1 = New PdfPCell(New Phrase("CELL1"))
 cellNested1.Border = 0
 tblNested2.AddCell(cellNested1)
 Dim cellNested2 = New PdfPCell(New Phrase("CELL2"))
 cellNested2.Border = 0
 tblNested2.AddCell(cellNested2)
 Dim cellNested3 = New PdfPCell(New Phrase("CELL3"))
 cellNested3.Border = 0
 tblNested2.AddCell(cellNested3)

 'APPEND TABLE2 TO A CELL WITH DEFAULT BORDER

  Dim cell1 As New PdfPCell
  cell1.AddElement(tblNested2)

  tblNested1.AddCell(cell1)

  document.Add(tblNested1)

答案 3 :(得分:0)

 var Rectangular = new Rectangle(56, 621, 540,385);
                Rectangular.BorderWidthLeft = 0.1f;
                Rectangular.BorderWidthRight = 0.1f;
                Rectangular.BorderWidthTop = 0.1f;
                Rectangular.BorderWidthBottom = 0.1f;
                cb.Rectangle(Rectangular);
                cb.Stroke();