I would like the page Header and Footer content (images, text, etc) to come from two separate html URLs, and the central content to come from another html URL.
Generally, it is structured like this:
---------------------------------------------------------------------------------------------
HEADER: IMG Title
---------------------------------------------------------------------------------------------
CONTENT: Text/Table
---------------------------------------------------------------------------------------------
FOOTER: Text
---------------------------------------------------------------------------------------------
Based on code samples from docs and some other forum posts, I have put together the following:
- Code: Select all
public StatusMessage CreatePdf(string SavePath, string ContentUrl)
{
var returnStatus = new StatusMessage();
var mappedSavePath = Helpers.Files.GetMappedPath(SavePath);
//create a PDF document
PdfDocument doc = new PdfDocument();
doc.PageSettings.Size = PdfPageSize.Letter;
doc.PageSettings.Orientation = PdfPageOrientation.Landscape;
//reset the default margins to 0
doc.PageSettings.Margins = new PdfMargins(0);
//Content Format settings
PdfHtmlLayoutFormat htmlLayoutFormat = new PdfHtmlLayoutFormat();
htmlLayoutFormat.FitToPage = Clip.None;
htmlLayoutFormat.Layout = PdfLayoutType.Paginate;
htmlLayoutFormat.IsWaiting = false;
//All Templates and Content
doc.PageSettings.SetMargins(SideMargins,HeaderHeight, SideMargins, FooterHeight);
PdfMargins margins = doc.PageSettings.Margins;
var topTemplate = CreateHeaderTemplate(doc);
var bottomTemplate = CreateFooterTemplate(doc);
var htmlContent = GetHtml(ContentUrl);
Thread thread = new Thread(() =>
{
try
{
//create a header template with content and apply it to page template
doc.Template.Top = topTemplate;
//create a footer template with content and apply it to bottom page template
doc.Template.Bottom = bottomTemplate;
//apply blank templates to other parts of page template
doc.Template.Left = new PdfPageTemplateElement(SideMargins, doc.PageSettings.Size.Height);
doc.Template.Right = new PdfPageTemplateElement(SideMargins, doc.PageSettings.Size.Height);
//Add Content
doc.LoadFromHTML(htmlContent, true, doc.PageSettings, htmlLayoutFormat);
//draw dynamic field in footer space
if (this.IncludePageNums)
{
doc = AddPageNums(doc);
}
}
catch (Exception e)
{
returnStatus.Success = false;
returnStatus.Message = "An Error occurred which prevented PDF generation.";
returnStatus.RelatedException = e;
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
//Save pdf file.
doc.SaveToFile(mappedSavePath);
doc.Close();
return returnStatus;
}
private PdfPageTemplateElement CreateHeaderTemplate(PdfDocument doc)
{
//get page size
PdfMargins margins = doc.PageSettings.Margins;
SizeF pageSize = doc.PageSettings.Size;
//create a PdfPageTemplateElement object as header space
PdfPageTemplateElement headerSpace = new PdfPageTemplateElement(pageSize.Width, HeaderHeight);
headerSpace.Foreground = true;
//declare two float variables
float leftPoint = margins.Left;
float topPoint = 0;
//RENDER
var displayHtml =[CODE WHICH RETURNS HTML STRING]
//Render HTML text
PdfBrush brush = PdfBrushes.Black;
PdfTrueTypeFont font = new PdfTrueTypeFont(_BrandFooterFont);
PdfHTMLTextElement richTextElement = new PdfHTMLTextElement(displayHtml, font, brush);
richTextElement.TextAlign = TextAlign.Left;
PdfMetafileLayoutFormat format = new PdfMetafileLayoutFormat();
format.Layout = PdfLayoutType.OnePage;
format.Break = PdfLayoutBreakType.FitElement;
//Draw htmlString
PointF point = new PointF(leftPoint, topPoint);
richTextElement.Draw(headerSpace.Graphics, point, headerSpace.Width, headerSpace.Height);
return headerSpace;
}
private PdfPageTemplateElement CreateFooterTemplate(PdfDocument doc)
{
//get page size
PdfMargins margins = doc.PageSettings.Margins;
SizeF pageSize = doc.PageSettings.Size;
//create a PdfPageTemplateElement object which works as footer space
PdfPageTemplateElement footerSpace = new PdfPageTemplateElement(pageSize.Width, margins.Bottom);
footerSpace.Foreground = true;
//declare two float variables
float leftPoint = margins.Left;
float topPoint = pageSize.Height - FooterHeight ;
//Get HTML
var displayHtml =[CODE WHICH RETURNS HTML STRING]
//Render HTML text
PdfBrush brush = PdfBrushes.Black;
PdfTrueTypeFont font = new PdfTrueTypeFont(_BrandFooterFont);
PdfHTMLTextElement richTextElement = new PdfHTMLTextElement(displayHtml, font, brush);
richTextElement.TextAlign = TextAlign.Left;
PdfMetafileLayoutFormat format = new PdfMetafileLayoutFormat();
format.Layout = PdfLayoutType.OnePage;
format.Break = PdfLayoutBreakType.FitElement;
//Draw htmlString
PointF point = new PointF(leftPoint, topPoint);
richTextElement.Draw(footerSpace.Graphics, point, footerSpace.Width, footerSpace.Height);
return footerSpace;
}
private PdfDocument AddPageNums(PdfDocument doc)
{
SizeF pageSize = doc.Pages[0].Size;
float x = 90;
float y = pageSize.Height - 72;
for (int i = 0; i < doc.Pages.Count; i++)
{
//draw page number and page count at bottom
PdfTrueTypeFont font = new PdfTrueTypeFont(_BrandFooterFont, true);
PdfPageNumberField number = new PdfPageNumberField();
PdfPageCountField count = new PdfPageCountField();
PdfCompositeField compositeField = new PdfCompositeField(font, _BrandFooterColor, "Page {0} of {1}", number, count);
compositeField.StringFormat = new PdfStringFormat(PdfTextAlignment.Right, PdfVerticalAlignment.Top);
SizeF size = font.MeasureString(compositeField.Text);
compositeField.Bounds = new RectangleF(pageSize.Width - x, y + 2, size.Width, size.Height);
compositeField.Draw(doc.Pages[i].Canvas);
}
return doc;
}
The Content is loaded into the PDF correctly, but the Header and Footer are just white areas. I also want to add the Page Number to all pages, in the bottom right, but that isn't rendering either.
Additionally, I am a bit confused about the Margins - it seems that the Page margins need to be large enough to accommodate the header/footer content, so setting the top and bottom margins only affects the main page content which is loaded in. But I am unclear about what the unit of the Margins is - is it pixels? or points? or something else?
Is there anything obviously wrong with my code?
NOTE: Using Acrobat 9.0 software, I see the following info:
"Show preview" on the hidden text shows the footer text and page numbers... I assume the "cropped" content would be the header... so how can I get these to be displayed?