|
Rank: Member Groups: Member
Joined: 10/10/2011 Posts: 13
|
I'm using HtmlToPdf.ConvertUrl to convert a webpage to PDF. I would like the PDF pages to have a background image on each page that frames the text content (kind of like stationary graphics that go all around the edge of the page). How do I go about doing that? Could someone please provide a code sample?
Cheers!
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi,
You can handle HtmlToPdf.Options.beforeRenderPage and then render the background image inside that handler. Inside the handler you can either call HtmlToPdf.ConvertUrl/ConvertImage again or use the ACM (PDF Creator) interface to render the background image. The only difference is in both cases you are outputting to a PdfPage object instead of a PdfDocument object (For example, ConvertHtml("htm_with_images", e.Page)).
Thanks!
|
|
Rank: Member Groups: Member
Joined: 10/10/2011 Posts: 13
|
I added this code: private void OnBeforeRenderPage(object sender, PdfPageEventArgs e) { HtmlToPdf.ConvertHtml(@"<img src=""http://corememberguide.hostplus.staging.clickdm.com.au/PDF/MemberGuide_Template.png"" />", e.Page); } but it is appearing behind the text content. I think my margin settings are causing a problem. Is there a way to have the image not be affected by the margin but have the text content use the margin? Here's the code I'm using:
Code: C#
private void EssentialObjectsUrl()
{
string url = "http://corememberguide.hostplus.staging.clickdm.com.au/pdf/pdf-fees-and-costs";
var doc = new PdfDocument();
HtmlToPdf.Options.BeforeRenderPage += this.OnBeforeRenderPage;
HtmlToPdf.Options.AutoFitX = HtmlToPdfAutoFitMode.None;
HtmlToPdf.Options.ZoomLevel = .8f;
// Setting header and footer format
//HtmlToPdf.Options.HeaderHtmlFormat = "";
HtmlToPdf.Options.FooterHtmlFormat = "We're here to help - call 1300 HOST<strong>PLUS</strong> (1300 467 875), 8am - 8pm, Monday to Friday or visit hostplus.com.au";
SizeF pageSize = PdfPageSizes.A4;
float marginLeft = 1.8f;
float marginTop = 1f;
float marginRight = 1.8f;
float marginBottom = 1f;
HtmlToPdf.Options.PageSize = pageSize;
HtmlToPdf.Options.OutputArea = new RectangleF(
marginLeft,
marginTop,
pageSize.Width - marginLeft - marginRight,
pageSize.Height - marginTop - marginBottom);
HtmlToPdfResult result = HtmlToPdf.ConvertUrl(url, doc);
// Now search for all elements with class name set to "sflistTitle"
HtmlElement[] elements = result.HtmlDocument.GetElementsByClassName("sflistTitle");
// Create a bookmark for each of these elements
foreach (HtmlElement element in elements)
{
// Skip invisible elements
if (!element.IsVisible)
{
continue;
}
// Create the bookmark
PdfBookmark bookmark = element.CreateBookmark();
doc.Bookmarks.Add(bookmark);
//To create child bookmarks, create a new
//PdfBookmark object and then add it to the
//parent bookmark's ChildNodes collection
}
// Merge cover page and last page
//var doc1 = new PdfDocument(Server.MapPath(@"/PDF/MemberGuide_FrontCover.pdf"));
//var doc2 = new PdfDocument(Server.MapPath(@"/PDF/MemberGuide_BackCover.pdf"));
//doc = PdfDocument.Merge(doc1, doc);
//doc = PdfDocument.Merge(doc, doc2);
doc.Save(@"c:\temp\EssentialObjectsUrl.pdf");
}
/// <summary>
/// Adds a background image to the page before any text is added.
/// </summary>
/// <param name="sender">
/// The sender.
/// </param>
/// <param name="e">
/// The PDF page event args.
/// </param>
private void OnBeforeRenderPage(object sender, PdfPageEventArgs e)
{
HtmlToPdf.ConvertHtml(@"<img src=""http://corememberguide.hostplus.staging.clickdm.com.au/PDF/MemberGuide_Template.png"" />", e.Page);
}
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi,
I am not sure what you mean by "it is appearing behind the text content". Isn't that background image is for? If you wish it to have different margins, just set HtmlToPdf.Options.OutputArea again in your OnBeforeRenderPage handler. Conversion options you set inside the handler will not affect the values used by the outer conversion.
Thanks
|
|
Rank: Member Groups: Member
Joined: 10/10/2011 Posts: 13
|
Setting the margin fixed it.
With the background image, it takes much longer to create the PDF. The same image is used for every page. Is there a way to optimize adding a background image? Maybe a way to cache the rendered elements?
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Yes. Use the ACM interface will be faster (but more code). You can take a look of the "PDF Creator" samples to see how to render an AcmImage to an PdfPage.
Thanks!
|
|
Rank: Member Groups: Member
Joined: 10/10/2011 Posts: 13
|
the sample adds an image to a paragraph. is there a way to just add it to the page?
Code: C#
//Create a new PdfDocument
PdfDocument doc = new PdfDocument();
//Create a new AcmRender object
AcmRender render = new AcmRender(doc);
//Create the root paragraph
AcmParagraph p1 = new AcmParagraph(
new AcmText("This is our logo:"));
//Create a new image
AcmImage image = new AcmImage(LoadImage("EOLogo.gif"));
image.Style.Padding.Left = 0.1f;
image.Style.OffsetY = 0.12f;
p1.Children.Add(image);
//Render the text
render.Render(p1);
//Save the PDF file
doc.Save(outputFileName);
|
|
Rank: Member Groups: Member
Joined: 10/10/2011 Posts: 13
|
when I try this code I get an out of memory error. Is there a better way?
Code: C#
// Create a new AcmRender object
var render = new AcmRender(e.Page.Document);
var block = new AcmBlock();
var image = new AcmImage(System.Drawing.Image.FromFile(Server.MapPath("/PDF/MemberGuide_Template.png")));
block.Children.Add(image);
render.Render(block);
|
|
Rank: Member Groups: Member
Joined: 10/10/2011 Posts: 13
|
I tried using the below code but the image only displayed on the first page and it didn't display right. To get around the memory problems, I used a global variable to store the System.Drawing.Image object.
Code: C#
// Create a new AcmRender object
var render = new AcmRender(e.Page.Document);
var block = new AcmBlock();
if (this.backgroundImage == null)
{
this.backgroundImage = System.Drawing.Image.FromFile(Server.MapPath("/PDF/MemberGuide_Template.png"));
}
var image = new AcmImage(this.backgroundImage);
block.Children.Add(image);
render.Render(block);
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi,
As you do with HTML to PDF, you would pass the PdfPage object instead of the PdfDocument object to the AcmRender:
var render = new AcmRender(e.Page, 0);
Thanks
|
|