I am developing a desktop application that generates a PDF file (from a PDF template) .
The method that generates the PDF receives these two variables of type DataTable
:
DataTable
tbl_template_variables:
DataTable
tbl_details_invoice:
This is the template:
Using itextsharp I use this code to generate the PDF:
private void GenerateInvoice(DataTable tbl_template_variables, DataTable tbl_details_invoice)
{
using (PdfReader pdfReader = new PdfReader(plantilla__Invoice__manual))
{
try
{
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(location_output_file, FileMode.Create));
AcroFields pdfFormFields = pdfStamper.AcroFields;
// Loop DataTable and set the value in the specified field.
for (int i = 0; i < tbl_template_variables.Rows.Count; i++)
{
pdfFormFields.SetField(tbl_template_variables.Rows[i][0].ToString(), tbl_template_variables.Rows[i][1].ToString(), true);// set form pdfFormFields
}
#region Diseño grid _Invoice_
PdfPCell cell = null;
PdfPTable table = null;
table = new PdfPTable(9);
table.HorizontalAlignment = Element.ALIGN_LEFT;
table.SetWidths(new float[] { 22f, 22f, 22f, 22f, 22f, 22f, 22f, 22f, 22f });
//table.SpacingBefore = 5;
table.TotalWidth = 800f;
for (int i = 0; i < tbl_details_invoice.Rows.Count; i++)
{
DataRow row = tbl_details_invoice.Rows[i];
object Invoice_PDFColumn0_value = row.Field<string>("PROVIDER") == null ? string.Empty : row.Field<string>("PROVIDER").ToString();
object Invoice_PDFColumn1_value = row.Field<string>("DESCRIPTION") == null ? string.Empty : row.Field<string>("DESCRIPTION").ToString();
object Invoice_PDFColumn2_value = row.Field<string>("PPTO") == null ? string.Empty : row.Field<string>("PPTO").ToString();
object Invoice_PDFColumn3_value = row.Field<string>("JOB_MEDIA_TYPE") == null ? string.Empty : row.Field<string>("JOB_MEDIA_TYPE").ToString();
object Invoice_PDFColumn4_value = row.Field<string>("VEND_INV_NO") == null ? string.Empty : row.Field<string>("VEND_INV_NO").ToString();
//object Invoice_PDFColumn5_value = row.Field<string>("ORDER_MEDIA") == null ? string.Empty : row.Field<string>("ORDER_MEDIA").ToString();
//object Invoice_PDFColumn6_value = row.Field<string>("ACTIVITY_MONTH") == null ? string.Empty : row.Field<string>("ACTIVITY_MONTH").ToString();
object Invoice_PDFColumn7_value = row.Field<string>("COMMISSIONABLE") == null ? string.Empty : row.Field<string>("COMMISSIONABLE").ToString();
object Invoice_PDFColumn8_value = row.Field<string>("NON_COMMISSIONABLE") == null ? string.Empty : row.Field<string>("NON_COMMISSIONABLE").ToString();
string Invoice_PDFColumn9_value = row.Field<string>("IVA_PROVEEDOR") == null ? string.Empty : row.Field<string>("IVA_PROVEEDOR").ToString();
string Invoice_PDFColumn10_value = row.Field<string>("TOTAL") == null ? string.Empty : row.Field<string>("TOTAL").ToString();
//Columns table
cell = PhraseCell(new Phrase(Invoice_PDFColumn0.ToString(), GettypeStyle()));
table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn1.ToString(), GettypeStyle()));
table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn2.ToString(), GettypeStyle()));
table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn3.ToString(), GettypeStyle()));
table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn4.ToString(), GettypeStyle()));
table.AddCell(cell);
//cell = PhraseCell(new Phrase(Invoice_PDFColumn5.ToString(), GettypeStyle()));
//table.AddCell(cell);
//cell = PhraseCell(new Phrase(Invoice_PDFColumn6.ToString(), GettypeStyle()));
//table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn7.ToString(), GettypeStyle()));
table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn8.ToString(), GettypeStyle()));
table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn9.ToString(), GettypeStyle()));
table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn10.ToString(), GettypeStyle()));
table.AddCell(cell);
}
ColumnText ct = new ColumnText(pdfStamper.GetOverContent(1));
ct.AddElement(table);
//iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(18, 370, 800, 36);
iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(16, 320, 900, 16);
rect.Border = iTextSharp.text.Rectangle.LEFT_BORDER | iTextSharp.text.Rectangle.RIGHT_BORDER;
rect.BorderWidth = 15;
rect.BorderColor = new BaseColor(0, 0, 0);
rect.Border = iTextSharp.text.Rectangle.BOX;
ct.SetSimpleColumn(rect);
ct.Go();
#endregion
// flatten the form to remove editting options, set it to false
// to leave the form open to subsequent manual edits
pdfStamper.FormFlattening = true;
pdfStamper.FreeTextFlattening = true;
pdfStamper.Writer.CloseStream = true;
pdfStamper.Close();// close the pdf
}
catch (Exception ex)
{
// No errors (yet).
}
}
}
And this is an example of the result I get:
The problem I have is that when the information that I highlight in RED color in the example that I attached is greater (that is, there are more than 4 rows), this information is placed in the PDF, but it does not generate more pages.
This is because when the information in the "Details" table is printed, it is printed at specific coordinates.
How can I use itextsharp so that "with the template I'm using" 1 I can generate a PDF file correctly?
1 Template created in Adobe Acrobat Pro.
Due to time issues and after researching on the internet for a week, I have come to this solution that I will describe in these steps:
If anyone is interested in how to generate multiple pages in the PDF file under construction, you can use this code:
Description: Create 8 pages in a PDF file, A4 size, landscape :
This is the code I found on Stack Overflow that joins "or merge" the PDF files into a single PDF file:
In my case I needed to generate a PDF file which is basically an invoice.
There, I divide the invoice results into blocks of 10 records (thanks to this answer ) and for each block of 10 records I generate a page.
This is the code that I have adjusted to generate a unified PDF file: