Reputation: 33
I have a template split into 3 files(header, body and footer), all of them in html. I need to export a pdf file using
itextsharp lib.
I use the folowing code to do that.
Function to export the file
public string GeneratePDF(Dictionary<string, object> fieldValues, string pdfPath, string templatePath)
{
//Inicializes a New Document
Document document = new Document(PageSize.A4,0,0,0,0);
try
{
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(pdfPath, FileMode.Create));
PdfPageEvents events = new PdfPageEvents();
//Initializes page events
writer.PageEvent = events;
//Open Document
document.Open();
//Gerar efetivamente o html
TemplateHelper objTemplate = new TemplateHelper();
//This function is not important, only replaces the content by a dictionary
string htmlContent = objTemplate.GenerateHTML(fieldValues, templatePath);
//Gerar o PD
StringReader reader = new StringReader(htmlContent);
XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, reader);
}
catch (Exception ex)
{
throw;
}
finally
{
document.Close();
}
return pdfPath;
}
and the page events
public class PdfPageEvents : PdfPageEventHelper
{
public override void OnStartPage(PdfWriter writer, Document document)
{
StreamReader template = new StreamReader(@"d:\Header.html");
string htmlContent = template.ReadToEnd();
StringReader reader = new StringReader(htmlContent);
ElementList e = XMLWorkerHelper.ParseToElementList(htmlContent, "");
PdfDiv div = (PdfDiv)e.First();
document.Add(div.Content.First());
template.Close();
template = new StreamReader(@"d:\Footer.html");
htmlContent = template.ReadToEnd();
reader = new StringReader(htmlContent);
}
//começa com o cabeçalho
public override void OnEndPage(PdfWriter writer, Document document)
{
StreamReader template = new StreamReader(@"d:\Footer.html");
string htmlContent = template.ReadToEnd();
StringReader reader = new StringReader(htmlContent);
ElementList elementListFooter = XMLWorkerHelper.ParseToElementList(htmlContent, "");
PdfDiv div = (PdfDiv)elementListFooter.First();
PdfPTable t = (PdfPTable)div.Content.First();
document.Add(t);
template.Close();
}
}
When I export to pdf, the header works fine, but the footer don't work. I tried to put the footer content on the footer of
the document, but unsuccessfully. If the content of the body is to large to fit in one page, the footer content is set
below the header and below the content on the last page. The follow image illustrates this problem.
Upvotes: 1
Views: 4110
Reputation: 55457
To explain what Bruno is saying in the comments in a little more detail, if you Add()
content in a page event, you could conceivably cause the document to generate a new page which would cause your page event to fire again. Even more fun, if your page event added too much content you could actually run into an infinite loop of add, overflow, new page, repeat.
If you want a true header and footer, set your Document
margins to account for the heights of both and normal Document.Add()
code will respect it. If you don't know how tall your header and/or footer is going to be each time you can try using this code to calculate the height.
Then you can use page events or two-pass to just add your header and footer and known fixed locations using DirectContent
or ColumnText
. Your content seems rather simple so you could probably convert it to just normal iTextSharp commands but if you want to stay in HTML for your header and footer see this post for parsing HTML to an element list and adding that to a ColumnText
.
Upvotes: 1