Reputation:
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.
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:
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?
Upvotes: 4
Views: 40916
Reputation: 739
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();
Upvotes: 0
Reputation: 91
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)
Upvotes: 3
Reputation: 21
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..
The method "DisableBorderSide(int Rectangle)" is how to go about removeing borders with any other sizing involved.
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);
Upvotes: 2
Reputation: 55427
As you found, PdfPTable
doesn't have borders, probably because PDF's don't have tables in the first place. It probably just made more sense to put the borders on the PdfPCell
directly (even though PDFs don't support those, either). 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. To do this you'll need a custom implementation of the IPdfPTableEvent
interface. 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
.
Upvotes: 3