I am having a table
PdfPTable tblSummary = new PdfPTable(1);
And it does have 2 tables nested within it. How can I make the tblSummary to appear as a whole (the rows must not break to another page) or entire table be shifted to another page if it doesn't fits in the current page.
I have tried SplitLate and SplitRows
And my code is like this
PdfPTable tblSummary = new PdfPTable(1);
PdfPCell csummarycell = new PdfPCell();
PdfPTable tblSummaryFirst = new PdfPTable(3);
.
.
csummarycell.AddElement(tblSummaryFirst);
.
.
tblSummary.AddCell(csummarycell);
tblSummary.SplitLate = true;
tblSummary.SplitRows = false;
like this I add up one more table(s) to the tblSummary while the resulting table height is always less than that of pagesize so there is certainty that the table's content won't be more than the page height.
Any suggestions would be really helping.
Have you tried this:
tblSummary.KeepTogether = true;
PdfPTable tabla = new PdfPTable(2);
float[] anchosTablaTituloDescripcion = new float[] { 4f, 4f };
tabla.SetWidths(anchosTablaTituloDescripcion);
tabla.WidthPercentage = 100;
tabla.KeepTogether = true;
Related
I am having header in this format --
"Heading" "Image" "Title"
Below is the code snippet i am using to achieve this -
Paragraph header = section.Headers.Primary.AddParagraph("Heading");
header.Format.Font.Bold = true;
header.AddTab();
Image image = header.AddImage("../../Images/logo.png");
image.Height = Unit.FromMillimeter(6);
header.AddFormattedText("Title", TextFormat.NotBold);
I need to align my "Image" and "Title" in such a way that title is vertically centrally aligned with respect to image's height, how can i achieve this ?
Any pointers/code snippet is much appreciated.
You could use a table to fit all the information in a certain structure:
// create document
Document MigraDokument = new Document();
// create section.
Section section = MigraDokument.AddSection();
section.PageSetup.PageFormat = PageFormat.A4;
// create a table
Table t = section.AddTable();
// size to use for the image and the image cell in the table
int size = 6;
// create 3 columns
Column column_header = t.AddColumn("6cm");
column_header.Format.Alignment = ParagraphAlignment.Center;
Column column_image = t.AddColumn(Unit.FromMillimeter(size));
column_image.Format.Alignment = ParagraphAlignment.Center;
Column column_text = t.AddColumn("4cm");
column_text.Format.Alignment = ParagraphAlignment.Center;
// Add 1 row to fill it with the content
Row r = t.AddRow();
// add you Header
Paragraph header = r.Cells[0].AddParagraph("Heading");
header.Format.Font.Bold = true;
header.AddTab();
// add the image
Image image = r.Cells[1].AddImage("../../logo.png");
image.Height = Unit.FromMillimeter(size);
// Add your Title
r.Cells[2].AddParagraph("Title");
// allign all of them
r.Cells[0].VerticalAlignment = VerticalAlignment.Center;
r.Cells[1].VerticalAlignment = VerticalAlignment.Center;
r.Cells[2].VerticalAlignment = VerticalAlignment.Center;
In my document the result looks the following:
Thanks to #MongZhu for suggesting the table way , posting the code snippet that i am using now just for future reference.
Table table = section.Headers.Primary.AddTable();
table.AddColumn("11cm");
table.AddColumn("2cm");
table.AddColumn("8cm");
Row row = table.AddRow();
row.VerticalAlignment = VerticalAlignment.Center;
Paragraph header = row.Cells[0].AddParagraph("Heading");
header.Format.Font.Bold = true;
Image image = row.Cells[1].AddImage("../../Images/logo.png");
image.Height = Unit.FromMillimeter(6);
row.Cells[2].AddParagraph("Title");
Hello and thanks for reading this post.
I'm using ItextSharp to create a pdf with content from my database but thats not the important part.
My footer stick the bottom of every page except the last page because there might not be enought content to "push" it down.
Document ResultPDF = new Document(iTextSharp.text.PageSize.A4, 25, 10, 20, 30);
PdfWriter Write = PdfWriter.GetInstance(ResultPDF, new FileStream(Server.MapPath("~") + "/PDF/" + fileName, FileMode.Create));
ResultPDF.Open();
PdfPTable Headtable = new PdfPTable(7);
Headtable.TotalWidth = 525f;
Headtable.LockedWidth = true;
Headtable.HeaderRows = 5;
Headtable.FooterRows = 2;
Headtable.KeepTogether = true;
.....
PdfPCell Footer = new PdfPCell(new Phrase(" ")) { Colspan = 7, UseVariableBorders = true, BorderColorTop = BaseColor.BLACK, BorderColorLeft = BaseColor.WHITE, BorderColorBottom = BaseColor.WHITE, BorderColorRight = BaseColor.WHITE };
PdfPCell Footer2 = new PdfPCell(new Phrase(Session["Surveyname"].ToString() + " - " + DateTime.Now.Date.ToString("dd-MM-yyyy") + " - " + email, smallText)) { Colspan = 6 };
PdfPCell Footer3 = new PdfPCell(new Phrase("", smallText)) { Colspan = 1, HorizontalAlignment = 1 };
Headtable.AddCell(Footer);
Headtable.AddCell(Footer2);
Headtable.AddCell(Footer3);
How can I make sure that my footer stay at the bottom of every page no matter what?
Thanks for your time.
Please take a look at the source code of PdfPTable, more specifically at the SetExtendLastRow() method:
/**
* When set the last row on every page will be extended to fill
* all the remaining space to the bottom boundary; except maybe the
* final row.
*
* #param extendLastRows true to extend the last row on each page; false otherwise
* #param extendFinalRow false if you don't want to extend the final row of the complete table
* #since iText 5.0.0
*/
public void SetExtendLastRow(bool extendLastRows, bool extendFinalRow) {
extendLastRow[0] = extendLastRows;
extendLastRow[1] = extendFinalRow;
}
If you want the last row to extend to the bottom of the last page, you need to set extendFinalRow to true (the default for extendLastRows and extendFinalRow is false).
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?
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.
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);
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();
I can not figure out how to vertically align text in table cell. horizontal alignment is ok. I use itextsharp to generate pdf. Alignment should be applied to cells in table kitosKalbosTable. Any help would be appreciated. here's my code:
var table = new PdfPTable(new float[]
{
36, 1, 63
});
table.WidthPercentage = 100.0f;
table.HorizontalAlignment = Element.ALIGN_LEFT;
table.DefaultCell.Border = Rectangle.NO_BORDER;
table.SplitRows = false;
.........
PdfPTable kitosKalbosTable = new PdfPTable(new float[] {10, 30});
kitosKalbosTable.TotalWidth = 40f;
kitosKalbosTable.SplitRows = false;
kitosKalbosTable.AddCell("Kalba", FontType.SmallTimes, vAligment: Element.ALIGN_MIDDLE, hAligment: Element.ALIGN_CENTER);
..........
table.AddCell(kitosKalbosTable);
//method in other file
public static PdfPCell CreateCell(
string text,
FontType? fontType = FontType.RegularTimes,
int? rotation = null,
int? colspan = null,
int? rowspan = null,
int? hAligment = null,
int? vAligment = null,
int? height = null,
int? border = null,
int[] disableBorders = null,
int? paddinLeft = null,
int? paddingRight = null,
bool? splitLate = null)
{
var cell = new PdfPCell();
............
if (vAligment.HasValue)
{
cell.VerticalAlignment = vAligment.Value;
}
return cell;
}
You have a complex example that appears to be using nested tables and extension methods. As Alexis pointed out, the VerticalAlignment is the correct property to use. Below is a full working example of this. I recommend getting rid of your extension method for now and just starting with this example.
//Our test file to output
var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");
//Standard PDF setup, nothing special here
using (var fs = new FileStream(testFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (var doc = new Document()) {
using (var writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();
//Create our outer table with two columns
var outerTable = new PdfPTable(2);
//Create our inner table with just a single column
var innerTable = new PdfPTable(1);
//Add a middle-align cell to the new table
var innerTableCell = new PdfPCell(new Phrase("Inner"));
innerTableCell.VerticalAlignment = Element.ALIGN_MIDDLE;
innerTable.AddCell(innerTableCell);
//Add the inner table to the outer table
outerTable.AddCell(innerTable);
//Create and add a vertically longer second cell to the outer table
var outerTableCell = new PdfPCell(new Phrase("Hello\nWorld\nHello\nWorld"));
outerTable.AddCell(outerTableCell);
//Add the table to the document
doc.Add(outerTable);
doc.Close();
}
}
}
This code produces this PDF:
Use
cell.VerticalAlignment = Element.ALIGN_MIDDLE; // or ALIGN_TOP or ALIGN_BOTTOM
Also, you can set a default vertical alignment for all cells by setting
kitosKalbosTable.DefaultCell.VerticalAlignment
It seems Element.ALIGN_MIDDLE only works, when the cell height is large i.r.t the text height.
In a PDF, margins for text in cells are large by default, see iText developers
You could append a \n and a space to your string to solve this, but the cell height will become much larger.
For normal text, one way to lift text in a chunk a few pixels is:
myChunk.SetTextRise(value);
Only drawback: when the text is underlined (like a link) it only raises the text ! not the underline..
The following seems to work for underlined text also,
myCell.PaddingBottom = value;
The idea was to put a link in a table cell.. blue font, underlined, vertical centering.
My code now:
iTextSharp.text.Font linksFont =
FontFactory.GetFont(FontFactory.HELVETICA,
10, Font.UNDERLINE, BaseColor.BLUE);
PdfPTable myTable = new PdfPTable(1);
Chunk pt = new Chunk("Go Google Dutch", linksFont);
pt.SetAnchor(new Uri("https://www.google.nl"));
Phrase ph1 = new Phrase(pt);
PdfPCell cellP = new PdfPCell();
cellP.PaddingBottom = linksFont.CalculatedSize/2;
cellP.AddElement(ph1);
myTable.AddCell(cellP);
How can i hide the table border using iTextSharp. I am using following code to generate a file:
var document = new Document(PageSize.A4, 50, 50, 25, 25);
// Create a new PdfWriter object, specifying the output stream
var output = new MemoryStream();
var writer = PdfWriter.GetInstance(document, output);
document.Open();
PdfPTable table = new PdfPTable(3);
var bodyFont = FontFactory.GetFont("Arial", 10, Font.NORMAL);
PdfPCell cell = new PdfPCell(new Phrase("Header spanning 3 columns"));
cell.Colspan = 3;
cell.HorizontalAlignment = 1; //0=Left, 1=Centre, 2=Right
table.AddCell(cell);
Font arial = FontFactory.GetFont("Arial", 6, BaseColor.BLUE);
cell = new PdfPCell(new Phrase("Font test is here ", arial));
cell.PaddingLeft = 5f;
cell.Colspan = 1;
table.AddCell(cell);
cell = new PdfPCell(new Phrase("XYX"));
cell.Colspan = 2;
table.AddCell(cell);
cell = new PdfPCell(new Phrase("Hello World"));
cell.PaddingLeft = 5f;
cell.Colspan = 1;
table.AddCell(cell);
cell = new PdfPCell(new Phrase("XYX"));
cell.Colspan = 2;
table.AddCell(cell);
table.SpacingBefore = 5f;
document.Add(table);
document.Close();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment;filename=Receipt-test.pdf");
Response.BinaryWrite(output.ToArray());
Do I need to specify no borders for individual cells or I can specify no borders for table itself.
Thank you
Although I upvoted the answer by Martijn, I want to add a clarification.
Only cells have borders in iText; tables don't have a border. Martijn's suggestion to set the border of the default cell to NO_BORDER is correct:
table.DefaultCell.Border = Rectangle.NO_BORDER;
But it won't work for the code snippet provided in the question. The properties of the default cell are only used if iText needs to create a PdfPCell instance implicitly (for instance: if you use the addCell() method passing a Phrase as parameter).
In the code snippet provided by #Brown_Dynamite, the PdfPCell objects are created explicitly. This means that you need to set the border of each of these cells to NO_BORDER.
Usually, I write a factory class to create cells. That way, I can significantly reduce the amount of code in the class that creates the table.
This should do the trick:
table.DefaultCell.Border = Rectangle.NO_BORDER;
or
table.borderwidth= 0;
First we can set all cell borders as 0 and After assigning all cell to table we can use the following code for for only pdfptable outer border.
PdfPCell cell = new PdfPCell();
cell.AddElement(t);
cell.BorderWidthBottom=1f;
cell.BorderWidthLeft=1f;
cell.BorderWidthTop=1f;
cell.BorderWidthRight = 1f;
PdfPTable t1 = new PdfPTable(1);
t1.AddCell(cell);
Here we can add table to one cell and can set border and again add that cell to another table and we can use as per our requirement.
If your PdfPTable is nested within another PdfPTable, the nested table will show table borders. The only way to get rid of the table borders is to put the nested PdfPTable into a PdfPCell of the main PdfPTable and set the border width of that cell to 0.
iTextSharp.text.pdf.PdfPTable table = new iTextSharp.text.pdf.PdfPTable(1); //<-- Main table
table.TotalWidth = 540f;
table.LockedWidth = true;
float[] widths = new float[] { 540f };
table.SetWidths(widths);
table.HorizontalAlignment = 1; //0=Left, 1=Centre, 2=Right
table.SpacingAfter = 10;
PdfPTable bodyTable = new PdfPTable(1); //<--Nested Table
bodyTable.TotalWidth = 540f;
bodyTable.LockedWidth = true;
float[] bodyWidths = new float[] { 540f };
bodyTable.SetWidths(bodyWidths);
bodyTable.HorizontalAlignment = 0;
bodyTable.SpacingAfter = 10;
bodyTable.DefaultCell.Border = iTextSharp.text.Rectangle.NO_BORDER;
var para1 = new Paragraph("This is a long paragraph", blackNormal);
para1.SetLeading(3f, 1f);
PdfPCell bodyCell1 = new PdfPCell();
bodyCell1.AddElement(para1);
bodyCell1.Border = 0;
bodyTable.AddCell(bodyCell1);
iTextSharp.text.pdf.PdfPCell cellBody = new iTextSharp.text.pdf.PdfPCell(bodyTable);
cellBody.BorderWidth = 0; //<--- This is what sets the border for the nested table
table.AddCell(cellBody);
Took me a long time to figure this out. It works for me now.
PdfPTable table = new PdfPTable(4);
table.TotalWidth = 400f;
table.LockedWidth = true;
PdfPCell header = new PdfPCell(new Phrase("Header"));
header.Colspan = 4;
table.AddCell(header);
table.AddCell("Cell 1");
table.AddCell("Cell 2");
table.AddCell("Cell 3");
table.AddCell("Cell 4");
PdfPTable nested = new PdfPTable(1);
nested.AddCell("Nested Row 1");
nested.AddCell("Nested Row 2");
nested.AddCell("Nested Row 3");
PdfPCell nesthousing = new PdfPCell(nested);
nesthousing.Padding = 0f;
table.AddCell(nesthousing);
PdfPCell bottom = new PdfPCell(new Phrase("bottom"));
bottom.Colspan = 3;
table.AddCell(bottom);
doc.Add(table);
PdfPTable table = new PdfPTable(3);
table.TotalWidth = 144f;
table.LockedWidth = true;
table.HorizontalAlignment = 0;
PdfPCell left = new PdfPCell(new Paragraph("Rotated"));
left.Rotation = 90;
table.AddCell(left);
PdfPCell middle = new PdfPCell(new Paragraph("Rotated"));
middle.Rotation = -90;
table.AddCell(middle);
table.AddCell("Not Rotated");
doc.Add(table);
Check this link pls
try this code
yourtable.DefaultCell.Border = 0;