|
Rank: Newbie Groups: Member
Joined: 7/13/2015 Posts: 7
|
Hi, I am trying to get some html content to render inside a generated PDF. But i can either get no render or it always adds it to the bottom of the PDF. Further explanation. I create the PDF and store a reference to the AcmBlock that will be used as the destination for the HTML. Once the PDF is rendered i then call the HtmlToPdf to add in my HTML content. How do i get the HTML to render where the AcmBlock was placed?
Code: C#
using EO.Pdf;
using EO.Pdf.Acm;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace pdftext
{
class Program
{
static void Main(string[] args)
{
EO.Pdf.Runtime.AddLicense([u][b]OMITTED[/b][/u]);
CreatePDF();
}
private static List<KeyValuePair<String, AcmBlock>> htmlBlocks = new List<KeyValuePair<String, AcmBlock>>();
static void CreatePDF()
{
//Create a new PdfDocument
PdfDocument doc = new PdfDocument();
//Create a new AcmRender object
AcmRender render = new AcmRender(doc, new AcmPageLayout(PdfPageSizes.A4));
AcmContent container = new AcmContent();
addFormTitle(ref container, "Title");
for (int i = 0; i < 9; i++)
{
addSection(ref container, "Section " + i);
}
//Render the text
render.Render(container);
foreach (var item in htmlBlocks)
{
HtmlToPdf.Options.PageSize = PdfPageSizes.A4;
PdfDestination pdfDest = item.Value.CreateDestination();
pdfDest.FitMode = PdfDestFitMode.BoundingBox;
HtmlToPdf.Options.StartPageIndex = pdfDest.Page.Index;
HtmlToPdf.Options.ZoomLevel = 1.0F;
HtmlToPdf.Options.StartPosition = pdfDest.FitRect.Y1;
HtmlToPdf.Options.OutputArea = new RectangleF(pdfDest.FitRect.X1, pdfDest.FitRect.Y1, pdfDest.FitRect.Width, pdfDest.FitRect.Height);
HtmlToPdfResult result = HtmlToPdf.ConvertHtml(item.Key, render.Document);
}
//Save the PDF file
doc.Save("tmp.pdf");
}
private static void addFormTitle(ref AcmContent Parent, String Title)
{
AcmText title = new AcmText(Title);
SetTitleFont(ref title);
Parent.Children.Add(title);
}
private static void addSection(ref AcmContent Parent, String SectionTitle)
{
AcmBlock SectionContainer = new AcmBlock();
AcmBlock SectionContent = new AcmBlock();
SectionContainer.Style.Margin.Top = 0.1f;
AcmParagraph Paragraph = new AcmParagraph();
SetSubtitleFont(ref Paragraph);
Paragraph.Children.Add(new AcmText(SectionTitle));
SectionContent.Children.Add(Paragraph);
SectionContent.Style.Padding = new AcmPadding(0.1f);
SectionContent.Style.BackgroundColor = Color.FromArgb(230, 230, 230);
SectionContainer.Children.Add(SectionContent);
AcmBlock SectionContent2 = new AcmBlock();
SectionContent2.Style.Padding = new AcmPadding(0.5f);
if (SectionTitle.Contains('3'))
htmlBlocks.Add(new KeyValuePair<String, AcmBlock>(HTML, SectionContent2));
else
SectionContent2.Children.Add(new AcmText(TEXT));
SectionContainer.Children.Add(SectionContent2);
Parent.Children.Add(SectionContainer);
}
private static void SetSubtitleFont(ref AcmParagraph obj)
{
obj.Style.FontName = "Helvetica";
obj.Style.FontSize = 10;
obj.Style.FontStyle = FontStyle.Bold;
}
private static void SetTitleFont(ref AcmText obj)
{
obj.Style.FontName = "Helvetica";
obj.Style.FontSize = 14;
obj.Style.FontStyle = FontStyle.Bold;
}
private static string HTML = "<span style=\"color: #0b0c0c; letter-spacing: normal; font-family: Arial; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; background-color: #ffffff;\">The National Minimum Wage rate per hour depends on your age and whether you’re an apprentice - you must be at least </span><a href=\"https://www.gov.uk/know-when-you-can-leave-school\" style=\"color: #2e8aca; letter-spacing: normal; font-family: Arial; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; font-stretch: normal; background-color: #ffffff;\">school leaving age</a><span style=\"color: #0b0c0c; letter-spacing: normal; font-family: Arial; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; background-color: #ffffff;\"> to get it.</span><br style=\"color: #404040; letter-spacing: normal; font-family: Arial; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: normal;\" /><table style=\"margin: 1em -1em 2em; width: 609px; color: #0b0c0c; letter-spacing: normal; font-family: Arial; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: normal; border-spacing: 0px; font-stretch: normal; background-color: #ffffff;\"> <thead> <tr> <th style=\"padding: 0.7em 0.5em 0.7em 1em; border: 1px solid #a1acb2; border-image: none; text-align: left; font-size: 16px; background-color: #dee0e2;\">Year</th> <th style=\"padding: 0.7em 0.5em 0.7em 1em; border: 1px solid #a1acb2; border-image: none; text-align: left; font-size: 16px; background-color: #dee0e2;\">21 and over</th> <th style=\"padding: 0.7em 0.5em 0.7em 1em; border: 1px solid #a1acb2; border-image: none; text-align: left; font-size: 16px; background-color: #dee0e2;\">18 to 20</th> <th style=\"padding: 0.7em 0.5em 0.7em 1em; border: 1px solid #a1acb2; border-image: none; text-align: left; font-size: 16px; background-color: #dee0e2;\">Under 18</th> <th style=\"padding: 0.7em 0.5em 0.7em 1em; border: 1px solid #a1acb2; border-image: none; text-align: left; font-size: 16px; background-color: #dee0e2;\">Apprentice*</th> </tr> </thead> <tbody> <tr> <td style=\"border-color: #b8c6cc; padding: 0.7em 0.5em 0.7em 1em; text-align: left; font-size: 16px; background-color: #eaedef;\"><span style=\"font-weight: 600;\">2013 (current rate)</span></td> <td style=\"border-color: #b8c6cc; padding: 0.7em 0.5em 0.7em 1em; text-align: left; font-size: 16px; background-color: #eaedef;\"><span style=\"font-weight: 600;\">£6.31</span></td> <td style=\"border-color: #b8c6cc; padding: 0.7em 0.5em 0.7em 1em; text-align: left; font-size: 16px; background-color: #eaedef;\"><span style=\"font-weight: 600;\">£5.03</span></td> <td style=\"border-color: #b8c6cc; padding: 0.7em 0.5em 0.7em 1em; text-align: left; font-size: 16px; background-color: #eaedef;\"><span style=\"font-weight: 600;\">£3.72</span></td> <td style=\"border-color: #b8c6cc; padding: 0.7em 0.5em 0.7em 1em; text-align: left; font-size: 16px; background-color: #eaedef;\"><span style=\"font-weight: 600;\">£2.68</span></td> </tr> </tbody></table><p style=\"margin: 0.75em 0px; color: #0b0c0c; letter-spacing: normal; font-family: Arial; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; background-color: #ffffff;\">*This rate is for <a href=\"https://www.gov.uk/apprenticeships-guide\" style=\"color: #2e8aca; text-decoration: none; background-color: transparent;\">apprentices</a> aged 16 to 18 and those aged 19 or over who are in their first year. All other apprentices are entitled to the National Minimum Wage for their age.</p><p style=\"margin: 0.75em 0px; color: #0b0c0c; letter-spacing: normal; font-family: nta, Arial, sans-serif; font-size: 19px; font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; background-color: #ffffff;\"><span style=\"font-family: Arial; font-size: 10pt;\">The rates are usually updated every October, so the current rates apply from October 2013.</span></p>";
const string TEXT = "Facin exeraessisit la consenim iureet dignibh eu facilluptat vercil dunt autpat. " +
"Ecte magna faccum dolor sequisc iliquat, quat, quipiss equipit accummy niate magna " +
"facil iure eraesequis am velit, quat atis dolore dolent luptat nulla adio odipissectet " +
"lan venis do essequatio conulla facillandrem zzriusci bla ad minim inis nim velit eugait " +
"aut aut lor at ilit ut nulla ate te eugait alit augiamet ad magnim iurem il eu feuissi.\n" +
"Guer sequis duis eu feugait luptat lum adiamet, si tate dolore mod eu facidunt adignisl in " +
"henim dolorem nulla faccum vel inis dolutpatum iusto od min ex euis adio exer sed del " +
"dolor ing enit veniamcon vullutat praestrud molenis ciduisim doloborem ipit nulla consequisi.\n" +
"Nos adit pratetu eriurem delestie del ut lumsandreet nis exerilisit wis nos alit venit praestrud " +
"dolor sum volore facidui blaor erillaortis ad ea augue corem dunt nis iustinciduis euisi.\n" +
"Ut ulputate volore min ut nulpute dolobor sequism olorperilit autatie modit wisl illuptat dolore " +
"min ut in ute doloboreet ip ex et am dunt at.";
}
}
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,229
|
Hi, There are two main mistakes in your code: 1. You can not modify the PdfDestionation object returned by CreateDestionation. This method basically just returns the Y position to you (all other members are zero). Changing FitMode to other values will not automatically fill in other values to you; 2. The coordination system used by PdfDestination and Html to PDF are different. The coordination system used by PdfDestination is in PDF user space (unit is 1/72 inch and Y axis grows from bottom to top): http://www.essentialobjects.com/doc/eo.pdf.pdfdestination.fitrect.aspxThe coordination system used by HTML to PDF is in inches, and the Y axis grows from top to bottom. Once you take these two into consideration, it should give you the right result. Thanks!
|
|
Rank: Newbie Groups: Member
Joined: 7/13/2015 Posts: 7
|
Hi,
I have take into account your points, and can now get the html to start rendering at the correct position.
However the html is rendered on top of the content below.
I assume this is because i have not set the height of the AcmBlock that i will render the HTML to.
Is there some way to work out the height of the HTML content before hand?
Cheers, Ben
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,229
|
Hi, The only way for you to work out the height of the HTML is to render them. You can call HtmlToPdf.ConvertHtml into a PdfDocument object and then use these two properties to find out HTML height: http://www.essentialobjects.com/doc/eo.pdf.htmltopdfresult.startposition.aspxhttp://www.essentialobjects.com/doc/eo.pdf.htmltopdfresult.lastposition.aspxThanks!
|
|
Rank: Newbie Groups: Member
Joined: 7/13/2015 Posts: 7
|
Hi, Thanks for your help, i have almost achieved the result that i want. 1) Measure the size of the HTML by rendering it into a temporary document
Code: Visual Basic.NET
Private Shared Sub CalculateHtmlSize(ByVal HTML As String, ByRef HtmlBlock As Acm.AcmBlock)
Dim doc As New PdfDocument()
Dim render As New Acm.AcmRender(doc, New Acm.AcmPageLayout(New Acm.AcmPadding(PagePadding)))
render.SetDefPageSize(EO.Pdf.PdfPageSizes.A4)
Dim TestContainer As New Acm.AcmBlock()
TestContainer.Style.Width = PdfPageSizes.A4.Width - (2 * PagePadding)
render.Render(TestContainer)
HtmlToPdf.Options.PageSize = PdfPageSizes.A4
Dim pdfDest As PdfDestination = TestContainer.CreateDestination()
HtmlToPdf.Options.StartPageIndex = pdfDest.Page.Index
HtmlToPdf.Options.ZoomLevel = 1.0F
HtmlToPdf.Options.StartPosition = PdfPageSizes.A4.Height - (pdfDest.FitRect.Y1 / 72.0F) - PagePadding
Dim result As HtmlToPdfResult = HtmlToPdf.ConvertHtml(HTML, render.Document)
HtmlBlock.Style.Height = ((result.LastPageIndex - result.StartPageIndex) * PdfPageSizes.A4.Height) + result.LastPosition
End Sub
2) Set the size of the destination AcmBlock to the calculated
Code: Visual Basic.NET
HtmlBlock.Style.Height = ((result.LastPageIndex - result.StartPageIndex) * PdfPageSizes.A4.Height) + result.LastPosition
3) When the document is rendered then render the html inside its target AcmBlock using HtmlToPdf This works in almost all cases. Except when the content is rendered over a page break As you can see it is forcing the content onto the new page, such that the destination created is no longer big enough to contain the HTML Do you have any suggestions on how to get around this? Cheers, Ben
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,229
|
Hi,
In that case you have to measure the HTML blocks as you are building your ACM contents instead of measuring them all upfront. The key is when you call ConvertHtml to measure the height of the HTML block, you must set HtmlToPdf.Options.StartPosition to the actual start position. This way the HTML to PDF converter will have exactly the same page break behavior during the "trial run" and the "actual run", thus producing the same value in both cases.
Thanks!
|
|
Rank: Newbie Groups: Member
Joined: 7/13/2015 Posts: 7
|
Hi,
Thanks for the support, I have managed to achieve the desired output.
Thanks, Ben
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,229
|
Great. Glad to hear that it works for you!
|
|