简体   繁体   English

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

[英]Itextsharp PDFPTable how to make a border around entire table

I'm building a table via a database in Itextsharp with PDFPTable, and the requirements are that no rows/cells in the table have a top or bottom bottom border, but the left and right sides of each cell have a black border (in other words, each column has a left a right border), and the bottom of the table needs to be closed off with a black border as well, which is where my problem lies. 我正在通过带有PDFPTable的Itextsharp中的数据库构建一个表,并且要求表中没有行/单元格具有顶部或底部底部边框,但每个单元格的左侧和右侧都有黑色边框(在其他中)单词,每列左边有一个右边框),桌子的底部也需要用黑色边框封闭,这就是我的问题所在。

What I'm doing is setting the border to 0, then manually assign borders so that I only get the left and right borders on each cell, as seen below as an example of a "Quantity" column being generated: 我正在做的是将边框设置为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); 

The issue is obviously I have no way of detecting the last row to add the border-bottom, but I imagine there has to be a way to control the border of the "table" itself, or am I taking the wrong approach to this? 问题显然是我没有办法检测最后一行添加border-bottom,但我想有一种方法来控制“表”本身的边界,或者我采取了错误的方法吗?

As you found, PdfPTable doesn't have borders, probably because PDF's don't have tables in the first place. 正如您所发现的, PdfPTable没有边框,可能是因为PDF首先没有表格。 It probably just made more sense to put the borders on the PdfPCell directly (even though PDFs don't support those, either). 将边框直接放在PdfPCell上可能更有意义(即使PDF也不支持这些)。 A table is just a collection of cells, anyway, so let them deal with it. 无论如何,表只是一个单元的集合,所以让他们处理它。

Anyway, the solution is to set the TableEvent on your instance of the PdfPTable class. 总之,解决的办法是设置TableEvent您的实例PdfPTable类。 To do this you'll need a custom implementation of the IPdfPTableEvent interface. 为此,您需要IPdfPTableEvent接口的自定义实现。 The below code should generally do this for you (see the notes at the bottom for "generally") 以下代码通常应该为您执行此操作(请参阅底部的“一般”注释)

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();

    }
}

Using it is very easy, just bind an instance to the property: 使用它非常简单,只需将实例绑定到属性:

//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);
}

Above I said "generally" it should work. 上面我说“一般”它应该工作。 If you have table headers and/or footers, however, you're going to need to take those into account, too. 但是,如果您有表格页眉和/或页脚,那么您也需要考虑这些内容。 This shouldn't be too hard but you'll need to adjust the y values accounting for table.HeaderRows and table.FooterRows . 这应该不是太难,但你需要调整y值占table.HeaderRowstable.FooterRows

I have experienced the same issue found the following solution. 我遇到了同样的问题,发现了以下解决方案。 From "iText In Action Second Edition" PdfPCell extends Rectangle, inheriting a plethora of methods to change the way borders are drawn and backgrounds are painted.. 从“iText In Action Second Edition”开始,PdfPCell扩展了Rectangle,继承了大量的方法来改变绘制边框和绘制背景的方式。

The method "DisableBorderSide(int Rectangle)" is how to go about removeing borders with any other sizing involved. 方法“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);

I solved this using nested tables 我用嵌套表解决了这个问题

'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)
 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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM