Not able to see other tables after pdf size limit - c#

I have used iTextSharp to generate a PDF file.
I have created 6 PdfPTables but it shows only 3.
// Create new PDF document
Document document = new Document(PageSize.A4, 20f, 20f, 20f, 20f);
try {
PdfWriter writer = PdfWriter.GetInstance(document,
new FileStream(filename, FileMode.Create));
document.Open();
int spacing = 0;
for (int i = 0; i <= 6; i++) {
PdfPTable table = new PdfPTable(2);
table.TotalWidth = 144f;
table.LockedWidth = false;
PdfPCell cell = new PdfPCell(new Phrase("This is table" + i));
cell.Colspan = 3;
cell.HorizontalAlignment = 1;
table.AddCell(cell);
table.WriteSelectedRows(0, -1,
document.Left + spacing, document.Top,
writer.DirectContent);
spacing = spacing + 200;
}
}
catch (Exception ex) {}
finally {
document.Close();
ShowPdf(filename);
}
Here I have put the for loop for 6 times but it shows only 3 table.
How can I show all 6 tables? I want to show only 3 table in 1 line after that break to new line and display other 3 tables.

I think the title of your question pretty much sums up the problem actually.
When you use WriteSelectedRows it is your responsibility to provide the X and Y locations to write to and you are drawing outside of the page boundaries. A4 has 595 horizontal units and there's just not enough room. This is 100% valid however most people won't see it. I'm guessing that you want to "wrap" your table to the next line. There's a couple of ways of doing that:
Bigger page size
Switch to something like PageSize.A0 and you should have more room. The page size is just a hint, anyway, print software will scale as needed.
MOD check in loop
This is the little more complicated one but every n tables you reset the x coordinate to the left edge and increase your y by the tallest of the previous row of tables.
int spacing = 0;
//The current Y position
float curY = document.Top;
//Well ask iText how tall each table was and set the tallest to this variable
float lineHeight = 0;
//Maximum number of tables that go on a line
const int maxPerLine = 3;
for (int i = 0; i <= 6; i++) {
PdfPTable table = new PdfPTable(2);
table.TotalWidth = 144f;
table.LockedWidth = false;
PdfPCell cell = new PdfPCell(new Phrase("This is table" + i));
cell.Colspan = 3;
cell.HorizontalAlignment = 1;
table.AddCell(cell);
table.WriteSelectedRows(0, -1,
document.Left + spacing, curY,
writer.DirectContent);
spacing = spacing + 200;
//Set the height to whichever is taller, the last table or this table
lineHeight = Math.Max(lineHeight, table.TotalHeight);
//If we're at the "last" spot in the "row"
if (0 == (i + 1) % maxPerLine) {
//Offset our Y by the tallest table
curY -= lineHeight;
//Reset "row level" variables
spacing = 0;
lineHeight = 0;
}
}
Wrapper table
This is what I really recommend. If you want to "wrap" tables then just use an outer table to hold your inner tables and you get everything for free and you don't have to mess with DirectContent (although you'll probably want to change table borders).
var outerTable = new PdfPTable(3);
outerTable.DefaultCell.Border = PdfPCell.NO_BORDER;
for (int i = 0; i <= 6; i++) {
PdfPTable innerTable = new PdfPTable(2);
innerTable.TotalWidth = 144f;
innerTable.LockedWidth = false;
PdfPCell cell = new PdfPCell(new Phrase("This is table" + i));
cell.Colspan = 3;
cell.HorizontalAlignment = 1;
innerTable.AddCell(cell);
outerTable.AddCell(innerTable);
}
document.Add(outerTable);

Related

how to put outer line for a table using itextsharp in c# asp.net

I'am creating a 2*2 table on pdf file. I Just want to put outer border for the table, No need to show the inner cells border. I have tried like this
var back= new PdfPTable(2); //table for back
back.DefaultCell.Border = 1;
PdfPCell cell20 = new PdfPCell(new Phrase("cell1", body));
cell20.Border = 0;
back.AddCell(cell20);
PdfPCell cell21 = new PdfPCell(new Phrase("cell2", body));
cell21.Border = 0;
cell21.HorizontalAlignment = 1; //0=Left, 1=Centre, 2=Right
back.AddCell(cell21);
PdfPCell cell22 = new PdfPCell(new Phrase("cell3"));
cell22.Border = 0;
cell22.HorizontalAlignment = 1; //0=Left, 1=Centre, 2=Right
back.AddCell(cell22);
PdfPCell cell23 = new PdfPCell(new Phrase("cell4", body));
cell23.Border = 0;
cell23.HorizontalAlignment = 1; //0=Left, 1=Centre, 2=Right
back.AddCell(cell23);
but it results a table without any border, please help
You need to create a table event, for instance:
public class OuterBorder implements PdfPTableEvent {
public void tableLayout(PdfPTable table, float[][] width, float[] height,
int headerRows, int rowStart, PdfContentByte[] canvas) {
float widths[] = width[0];
float x1 = widths[0];
float x2 = widths[widths.length - 1];
float y1 = height[0];
float y2 = height[height.length - 1];
PdfContentByte cb = canvas[PdfPTable.LINECANVAS];
cb.rectangle(x1, y1, x2 - x1, y2 - y1);
cb.stroke();
}
}
As you can see, we use the width and height parameter passed to the tableLayout() method to define the borders of a rectangle, and we draw that rectangle to the LINECANVAS.
For this table event to work, you need to declare it to the table. In your case, that would be:
back.setTableEvent(new OuterBorder());
Note that my code is written in Java based on the PressPreviews example from my book. For the corresponding C# code, please consult the iTextSharp examples.

print an icard in pdf using itextsharp

I want to create a PDF file with Icard showing in it.
Following is the code:
iTextSharp.text.Font custFont = new iTextSharp.text.Font() { Size=6f};
int borderSize = 1;
Document IcardDoc = new Document(PageSize.HALFLETTER);
PdfWriter.GetInstance(IcardDoc, Response.OutputStream);
IcardDoc.Open();
PdfPTable icardTable = new PdfPTable(2);
iTextSharp.text.Image logoImage = iTextSharp.text.Image.GetInstance(Server.MapPath("~/images/logo.jpg"));
logoImage.WidthPercentage = 15f;
PdfPCell cell = new PdfPCell(logoImage, false);
cell.PaddingLeft = 10f;
cell.PaddingTop = 10f;
cell.PaddingBottom = 10f;
cell.PaddingRight = 10f;
cell.Colspan = 2;
cell.Border = 0;
cell.HorizontalAlignment = 1;
icardTable.AddCell(cell);
icardTable.AddCell(new PdfPCell(new Phrase("Name:", custFont)) { Border = borderSize });
icardTable.AddCell(new PdfPCell(new Phrase(student.firstname + " " + student.lastname, custFont)) { Border = borderSize });
The print document size will be 8.5 cm in height and 5.4 cm in width.
So need to fit it that way, is there any solution to this because the above code is not fitting the table on page and in proper size?
Any other format will also do like word etc.
figured out the solution :
Document IcardDoc = new Document(new Retangele(200f, 315f),35f,35f,0f,0f);
and adjust the width of the table accordingly:
PdfPTable icardTable = new PdfPTable(2);
icardTable.WidthPercentage = 140f;
to fit table exactly on page, if decrease rectangle width then increase table WidthPercentage and vice versa.
You also need to care of left and right margins defined as 35f in Document class constructor
This worked for me.
var pgSize = new iTextSharp.text.Rectangle(1042, 651);
var doc = new iTextSharp.text.Document(pgSize, 0, 0, 0, 0);

iTextSharp: How to find the first and second row height in a table?

I want to get the first and second column height to know if I need to call document.NewPage() or not. But, I can't find a way to do this without adding the table to the document.
Example:
PdfPRow firstRow = new PdfPRow(cells1.ToArray());
table.Rows.Add(firstRow);
PdfPRow secondRow = new PdfPRow(cells2.ToArray());
table.Rows.Add(secondRow);
float h1 = table.GetRowHeight(0), h2 = table.GetRowHeight(1);
if (currentY - h1 - h2 < 30) document.NewPage();
document.Add(table);
See my answer here. Basically, you can't know the dimensions of a table until it renders. However, you can render the table to a document that you just throw away and then re-render it later.
Interesting question, so +1. And already marked as answered, but...
"But, I can't find a way to do this without adding the table to the document."
It is possible. Wrap the PdfPTable in a ColumnText object and take advantage of the ColumnText.Go() overload to get the total height of any arbitrary/number of rows you want without adding the PdfPTable to the Document. Here's a simple helper method:
public static float TotalRowHeights(
Document document, PdfContentByte content,
PdfPTable table, params int[] wantedRows)
{
float height = 0f;
ColumnText ct = new ColumnText(content);
// respect current Document.PageSize
ct.SetSimpleColumn(
document.Left, document.Bottom,
document.Right, document.Top
);
ct.AddElement(table);
// **simulate** adding the PdfPTable to calculate total height
ct.Go(true);
foreach (int i in wantedRows) {
height += table.GetRowHeight(i);
}
return height;
}
And a simple use case tested with 5.2.0.0:
using (Document document = new Document()) {
PdfWriter writer = PdfWriter.GetInstance(document, STREAM);
document.Open();
PdfPTable table = new PdfPTable(4);
for (int i = 1; i < 20; ++i) {
table.AddCell(i.ToString());
}
int[] wantedRows = {0, 2, 3};
document.Add(new Paragraph(string.Format(
"Simulated table height: {0}",
TotalRowHeights(document, writer.DirectContent, table, wantedRows)
)));
// uncomment block below to verify correct height is being calculated
/*
document.Add(new Paragraph("Add the PdfPTable"));
document.Add(table);
float totalHeight = 0f;
foreach (int i in wantedRows) {
totalHeight += table.GetRowHeight(i);
}
document.Add(new Paragraph(string.Format(
"Height after adding table: {0}", totalHeight
)));
*/
document.Add(new Paragraph("Test paragraph"));
}
In the use case rows 1, 3, and 4 are used, but only to demonstrate any combination/number of rows will work.
Unless you set the width of the table, table.GetRowHeight(0) will always return zero.
// added
table.TotalWidth = 400f;
//
PdfPRow firstRow = new PdfPRow(cells1.ToArray());
table.Rows.Add(firstRow);
PdfPRow secondRow = new PdfPRow(cells2.ToArray());
table.Rows.Add(secondRow);
float h1 = table.GetRowHeight(0), h2 = table.GetRowHeight(1);
if (currentY - h1 - h2 < 30) document.NewPage();
document.Add(table);
There is another way to do this:
Create the table at first.
this.table = new PdfPTable(relativeColumnWidths);
this.table.SetTotalWidth(absoluteColumnWidths);
this.rowCells.Clear();
You may now fill the List with table cells:
Paragraph pText = new Paragraph(text, this.font);
PdfPCell cell = new PdfPCell(pText);
this.rowCells.Add(cell);
When you are ready to create the new row:
PdfPRow row = new PdfPRow(this.rowCells.ToArray());
this.table.Rows.Add(row);
This is nothing special. But if you now set the table width again, you are able to calculate the row height properly:
this.table.SetTotalWidth(this.table.AbsoluteWidths);
this.rowCells.Clear();
float newRowsHeight = this.table.GetRowHeight(this.table.Rows.Count - 1);
If the row is not fitting your conditions you can simply remove it from the rows collection of the table. The total height of the table will be calculated properly also.

Problem using tables in itextsharp

i am trying to generate a pdf file using itextsharp in asp.net c#.
I came across table concept in itextsharp n i am trying to use it ie my application. I am having the following problem while using tables.
The pdf cell which contains Name of treasery the word treasery comes on next line. I am setting width for each cell. if i increase the width than also no changes come. The gap which is shown using arrow in below image remain as it is al the time. Why is that gap?How to remove that gap?
I want a dotted line as a border to only one cell. how to do that?here is my code
PdfPTable line6table = new PdfPTable (3);
float[] width = new float[] { 2.5F, 1.5F, 3.0F };
line6table.SetWidths(width);
line6table.HorizontalAlignment = 0;
line6table.WidthPercentage = 100.0f;
line6table.SpacingBefore = 6.0f;
PdfPCell a1 = new PdfPCell(new Phrase("Head Of Account"));
a1.Border = 1;
a1.Indent = 2.2f;
a1.PaddingTop = 5.0f;
line6table.AddCell(a1);
PdfPCell a2 = new PdfPCell(new Phrase("CHARGED"));
a2.Border = 1;
a2.PaddingTop = 5.0f;
line6table.AddCell(a2);
PdfPCell a3 = new PdfPCell(new Phrase("Name of the treasry"));
a3.Border = 0;
a3.Indent = 15.0f;
a3.RightIndent = 0.0f;
a3.HorizontalAlignment = 1;
line6table.AddCell(a3);
pdfDocument.Add(line6table);
Please help me to resolve my problem.
line6table.WidthPercentage = 100.0f;
This did it for me.
Increase the width of the column.

Code isn't drawing a horizontal line in my PDF

I'm trying to add a horizontal line on top to divide the header text from the actual values in my pdf file:
Here's my code:
public class StudentList
{
public void PrintStudentList(int gradeParaleloID)
{
StudentRepository repo = new StudentRepository();
var students = repo.FindAllStudents()
.Where(s => s.IDGradeParalelo == gradeParaleloID);
try
{
Document document = new Document(PageSize.LETTER);
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\Alumnos.pdf", FileMode.Create));
document.Open();
PdfContentByte cb = writer.DirectContent;
cb.SetLineWidth(2.0f); // Make a bit thicker than 1.0 default
cb.SetGrayStroke(0.95f); // 1 = black, 0 = white
cb.MoveTo(20, 30);
cb.LineTo(400, 30);
cb.Stroke();
PdfPTable table = new PdfPTable(3);
float[] widths = new float[] { 0.6f, 0.75f, 2f };
table.SetWidths(widths);
PdfPCell numeroCell = new PdfPCell(new Phrase("Nro."));
numeroCell.Border = 0;
numeroCell.HorizontalAlignment = 0;
table.AddCell(numeroCell);
PdfPCell codigoCell = new PdfPCell(new Phrase("RUDE"));
codigoCell.Border = 0;
codigoCell.HorizontalAlignment = 0;
table.AddCell(codigoCell);
PdfPCell nombreCell = new PdfPCell(new Phrase("Apellidos y Nombres"));
nombreCell.Border = 0;
nombreCell.HorizontalAlignment = 0;
table.AddCell(nombreCell);
int c = 1;
foreach (var student in students)
{
PdfPCell cell = new PdfPCell(new Phrase(c.ToString()));
cell.Border = 0;
cell.HorizontalAlignment = 0;
table.AddCell(cell);
cell = new PdfPCell(new Phrase(student.Rude.ToString()));
cell.Border = 0;
cell.HorizontalAlignment = 0;
table.AddCell(cell);
cell = new PdfPCell(new Phrase(student.LastNameFather + " " + student.LastNameMother + " " + student.Name));
cell.Border = 0;
cell.HorizontalAlignment = 0;
table.AddCell(cell);
c++;
}
table.SpacingBefore = 20f;
table.SpacingAfter = 30f;
document.Add(table);
document.Close();
}
catch (DocumentException de)
{
Debug.WriteLine(de.Message);
}
catch (IOException ioe)
{
Debug.WriteLine(ioe.Message);
}
}
}
I don't understand why the cb.Stroke() isn't working. Any suggestions?
Drawing with iTextSharp's PdfContentByte class can be a little confusing. The height is actually relative to the bottom, not the top. So the top of the page is not 0f, but instead is actually document.Top, which on your page size of PageSize.LETTER is 726f. So if you want to draw your line 30 units from the top, try:
cb.MoveTo(20, document.Top - 30f);
cb.LineTo(400, document.Top - 30f);
Just curious -- why do it the hard way instead of using table borders? (I noticed you set your borders to 0) Trying to space out lines by hand is the biggest pain. If you ever move content in your PDF around, you'll have to make sure your measurements still work.
Try this:
numeroCell.Border = 0;
numeroCell.BorderColorBottom = new BaseColor(System.Drawing.Color.Black);
numeroCell.BorderWidthBottom = 1f;
codigoCell.Border = 0;
codigoCell.BorderColorBottom = new BaseColor(System.Drawing.Color.Black);
codigoCell.BorderWidthBottom = 1f;
nombreCell.Border = 0;
nombreCell.BorderColorBottom = new BaseColor(System.Drawing.Color.Black);
nombreCell.BorderWidthBottom = 1f;
That should give you a nice solid black line under your header row, no measurements needed:

Categories