|
This behavior can be observed when the Documentation.chm
file has been blocked because Windows determined that the file or the archive from
where the file was extracted is downloaded from Internet and the files downloaded
from Internet are considered to be insecure in general. In order to fix this, right
click on the file in Windows Explorer and in the Properties, General tab check if
there is the Unblock button. If this button exists then
click on it to unblock the file. Open the documentation file again. The content
should be visible without problems now.
In case the documentation file was blocked it is possible that other important files
like HiQPdf.dll and HiQPdf.dep
were also blocked by Windows which can lead to an unexpected behavior of the library.
Unblock these files too before you start using them.
|
|
|
|
In order to capture the values filled in the ASP.NET page, you have to override
the Render method of the ASP.NET page to get the HTML
code that would be generated during Render phase of the page processing and convert
that HTML code to PDF passing the page URL as base URL parameter to the converter.
The sample code below, copied from the online help, demonstrates this procedure.
When a 'Convert to PDF' button in the page is pressed, the convertToPdf boolean
field is set to true. This field is checked in the overridden Render method and
if it is true then the HTML code is captured, converted to PDF and the generated
PDF is sent as response to browser instead of the normal HTML:
Source Code Example
using System.Text;
using System.IO;
using HiQPdf;
namespace WebApplication
{
public partial class GetHtmlCode : System.Web.UI.Page
{
bool convertToPdf = false;
protected override void Render(HtmlTextWriter writer)
{
if (convertToPdf)
{
// setup a TextWriter to capture the current page HTML code
TextWriter tw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(tw);
// render the HTML markup into the TextWriter
base.Render(htw);
// get the current page HTML code
string htmlCode = tw.ToString();
// convert the HTML code to PDF
// create the HTML to PDF converter
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
// the base URL used to resolve images, CSS and script files
string currentPageUrl = HttpContext.Current.Request.Url.AbsoluteUri;
// convert HTML code to a PDF memory buffer
byte[] pdfBuffer = htmlToPdfConverter.ConvertHtmlToMemory(htmlCode, currentPageUrl);
// inform the browser about the binary data format
HttpContext.Current.Response.AddHeader("Content-Type", "application/pdf");
// let the browser know how to open the PDF document, attachment or inline, and the file name
HttpContext.Current.Response.AddHeader("Content-Disposition",
String.Format("attachment; filename=HtmlToPdf.pdf;
size={0}", pdfBuffer.Length.ToString()));
// write the PDF buffer to HTTP response
HttpContext.Current.Response.BinaryWrite(pdfBuffer);
// call End() method of HTTP response to stop ASP.NET page processing
HttpContext.Current.Response.End();
}
else
{
base.Render(writer);
}
}
protected void buttonConvertCurrentPageToPdf_Click(object sender, EventArgs e)
{
convertToPdf = true;
}
}
|
|
|
|
When you convert an ASP.NET page given by an URL, the converter will make a GET
request to the page URL in a new session and the values stored in the current ASP.NET
Session are not available. There are two situations to consider when resolving this
problem:
1. If you want to convert to PDF the same ASP.NET page with the page from where
you call the converter (the current page) then the solution is to override the Render
method of the current ASP.NET page, get the HTML code to be rendered and convert
that HTML code to PDF. This method is described in detail, including sample C# code,
in response to the previous question.
2. If you want to convert a different ASP.NET page of the same application then
the solution is to get the HTML code of the ASP.NET page to convert with a call
to HttpServerUtility.Execute() method from ASP.NET.
An object of the HttpServerUtility type is exposed by the Server property of the
ASP.NET page object. The only restriction is that the ASP.NET page to convert must
be in the same application with the ASP.NET page from where the converter is called.
The sample code below, copied from the online help, demonstrates the solution for
this second situation. When a 'Convert to PDF' button in the current ASP.NET page
is pressed, another ASP.NET page in the same application is converted to PDF.
Source Code Example
using System.IO;
using HiQPdf;
namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void buttonConvertToPdf_Click(object sender, EventArgs e)
{
// setup a TextWriter to capture the HTML code of the page to convert
TextWriter tw = new StringWriter();
// execute the 'AspNetPage.aspx' page in the same application and capture the HTML code
Server.Execute("PageToConvert.aspx", tw);
// get the HTML code from writer
string htmlCode = tw.ToString();
// convert the HTML code to PDF
// create the HTML to PDF converter
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
// the base URL used to resolve images, CSS and script files
string baseUrl = HttpContext.Current.Request.Url.AbsoluteUri;
// convert HTML code to a PDF memory buffer
byte[] pdfBuffer = htmlToPdfConverter.ConvertHtmlToMemory(htmlCode, baseUrl);
// inform the browser about the binary data format
HttpContext.Current.Response.AddHeader("Content-Type", "application/pdf");
// let the browser know how to open the PDF document, attachment or inline, and the file name
HttpContext.Current.Response.AddHeader("Content-Disposition",
String.Format("attachment; filename=HtmlToPdf.pdf;
size={0}", pdfBuffer.Length.ToString()));
// write the PDF buffer to HTTP response
HttpContext.Current.Response.BinaryWrite(pdfBuffer);
// call End() method of HTTP response to stop ASP.NET page processing
HttpContext.Current.Response.End();
}
}
}
|
|
|
|
When you convert an ASP.NET MVC URL, the converter will make a GET request to the
URL in a new session and the values stored in the current ASP.NET Session are not
available. The solution is to get the HTML code rendered by the MVC view in the
current context of the MVC controller and to convert that HTML code to PDF giving
the appropriate base URL.
The sample code below demonstrates this solution. When the 'Convert This Page to
PDF' button in the Index view is pressed the Index view itself is converted. When
the 'Convert About Page to PDF' button in the Index view is pressed the About view
in the same application is converted to PDF.
Source Code Example - MVC Controller C# Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.IO;
using HiQPdf;
namespace HiQPdfMvcRazorApplication.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
Session["MySessionVariable"] = "My Session Variable Value assigned in Index";
return View();
}
public ActionResult About()
{
return View();
}
public string RenderViewAsString(string viewName, object model)
{
// create a string writer to receive the HTML code
StringWriter stringWriter = new StringWriter();
// get the view to render
ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, viewName, null);
// create a context to render a view based on a model
ViewContext viewContext = new ViewContext(
ControllerContext,
viewResult.View,
new ViewDataDictionary(model),
new TempDataDictionary(),
stringWriter
);
// render the view to a HTML code
viewResult.View.Render(viewContext, stringWriter);
// return the HTML code
return stringWriter.ToString();
}
[HttpPost]
public ActionResult ConvertThisPageToPdf()
{
// get the HTML code of this view
string htmlToConvert = RenderViewAsString("Index", null);
// the base URL to resolve relative images and css
String thisPageUrl = this.ControllerContext.HttpContext.Request.Url.AbsoluteUri;
String baseUrl = thisPageUrl.Substring(0, thisPageUrl.Length - "Home/ConvertThisPageToPdf".Length);
// instantiate the HiQPdf HTML to PDF converter
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
// hide the button in the created PDF
htmlToPdfConverter.HiddenHtmlElements = new string[] { "#convertThisPageButtonDiv" };
// render the HTML code as PDF in memory
byte[] pdfBuffer = htmlToPdfConverter.ConvertHtmlToMemory(htmlToConvert, baseUrl);
// send the PDF file to browser
FileResult fileResult = new FileContentResult(pdfBuffer, "application/pdf");
fileResult.FileDownloadName = "ThisMvcViewToPdf.pdf";
return fileResult;
}
[HttpPost]
public ActionResult ConvertAboutPageToPdf()
{
// get the About view HTML code
string htmlToConvert = RenderViewAsString("About", null);
// the base URL to resolve relative images and css
String thisPageUrl = this.ControllerContext.HttpContext.Request.Url.AbsoluteUri;
String baseUrl = thisPageUrl.Substring(0, thisPageUrl.Length - "Home/ConvertAboutPageToPdf".Length);
// instantiate the HiQPdf HTML to PDF converter
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
// render the HTML code as PDF in memory
byte[] pdfBuffer = htmlToPdfConverter.ConvertHtmlToMemory(htmlToConvert, baseUrl);
// send the PDF file to browser
FileResult fileResult = new FileContentResult(pdfBuffer, "application/pdf");
fileResult.FileDownloadName = "AboutMvcViewToPdf.pdf";
return fileResult;
}
}
}
Source Code Example - Index View Razor Code
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
<p>
To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET
MVC Website">
http://asp.net/mvc</a>.
</p>
<br />
@using (Html.BeginForm("ConvertThisPageToPdf", "Home", FormMethod.Post, new { id = "convertForm" }))
{
<div id="convertThisPageButtonDiv">
<input type="submit" value="Convert
This Page To PDF"
/>
</div>
}
<br />
@using (Html.BeginForm("ConvertAboutPageToPdf", "Home", FormMethod.Post, new { id = "convertForm" }))
{
<div id="convertAboutPageButtonDiv">
<input type="submit" value="Convert
About Page To PDF"
/>
</div>
}
<br />
<br />
<h1>
@Session["MySessionVariable"].ToString()</h1>
<br />
<br />
<img alt=""
style="height: 100px"
src="/Images/banner.png" />
Source Code Example - Index View MVC Code
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site
.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>
<%: (String)ViewBag.Message %></h2>
<p>
To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET
MVC Website">
http://asp.net/mvc</a>.
</p>
<br />
<form action="/Home/ConvertThisPageToPdf" id="convertThisPageForm" method="post">
<div id="convertThisPageButtonDiv">
<input type="submit" value="Convert
This Page To PDF"
/>
</div>
</form>
<br />
<form action="/Home/ConvertAboutPageToPdf" id="convertAboutPageForm"
method="post">
<div id="convertAboutPageButtonDiv">
<input type="submit" value="Convert
About Page To PDF"
/>
</div>
</form>
<br />
<br />
<h1>
<%: Session["MySessionVariable"].ToString()%></h1>
<br />
<br />
<img alt=""
style="height: 100px"
src="/Images/banner.png" />
</asp:Content>
|
|
|
|
The HTML to PDF converter can handle various types of HTTP authentication, including
Integrated Windows Authentication. When a web page require HTTP authentication and
you access that page in browser the browser will prompt you to enter a username
and a password. Similar, the HiQPdf converters have the Authentication
property which exposes an object with the Username and
Password properties that can be set with the same values
you would enter in a browser.
|
|
|
|
Once a user is authenticated, Forms Authentication maintains an authentication ticket
in a cookie or in the URL so that an authenticated user does not need to supply
credentials with each request. When you are already authenticated and you want to
convert a page of the same application you can simply set the authentication cookie before converting the web page. The converter can
be set to send the authentication cookie to the web server. A simple code to create
a HTML to PDF converter object, set the forms authentication cookie and convert
an URL to a memory buffer is given below:
Source Code Example
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
htmlToPdfConverter.HttpCookies.AddCookie(
FormsAuthentication.FormsCookieName,
Request.Cookies[FormsAuthentication.FormsCookieName].Value
);
byte[] pdfBuffer = htmlToPdfConverter.ConvertUrlToMemory(url);
|
|
|
|
When the application is implementing a custom authentication mechanism, like storing
the logged in user credentials in ASP.NET session and verifying the stored credentials
at each page access, a possible solution to handle this type of authentication is
to get the HTML code of the web page using the Render method overriding or calling
the HttpServerUtility.Execute method as explained below. As a base URL when converting
the HTML code you can use the URL of the web page to be converted.
Methods to Get the HTML Code of a Web Page
1. Overriding the Render Method to Get the HTML Code of the
Current ASP.NET Page
The Page.Render(HtmlTextWriter) method of the ASP.NET page can be overridden to
get the HTML code of the page as it would be sent to the browser. Using this method
it is even possible to capture the values entered in a web form and posted back
to ASP.NET page when a button in page is pressed. In the example below, when a 'Convert
to PDF' button in the page is pressed, the convertToPdf boolean field is
set to true. This field is checked in the overridden Render method and if it is
true then the HTML code is captured, converted to PDF and the generated PDF is sent
as response to browser instead of the normal HTML:
Source Code Example
using System.Text;
using System.IO;
using HiQPdf;
namespace WebApplication
{
public partial class GetHtmlCode : System.Web.UI.Page
{
bool convertToPdf = false;
protected override void Render(HtmlTextWriter writer)
{
if (convertToPdf)
{
// setup a TextWriter to capture the current page HTML code
TextWriter tw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(tw);
// render the HTML markup into the TextWriter
base.Render(htw);
// get the current page HTML code
string htmlCode = tw.ToString();
// convert the HTML code to PDF
// create the HTML to PDF converter
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
// the base URL used to resolve images, CSS and script files
string currentPageUrl = HttpContext.Current.Request.Url.AbsoluteUri;
// convert HTML code to a PDF memory buffer
byte[] pdfBuffer = htmlToPdfConverter.ConvertHtmlToMemory(htmlCode, currentPageUrl);
// inform the browser about the binary data format
HttpContext.Current.Response.AddHeader("Content-Type", "application/pdf");
// let the browser know how to open the PDF document, attachment or inline, and the file name
HttpContext.Current.Response.AddHeader("Content-Disposition",
String.Format("attachment; filename=HtmlToPdf.pdf;
size={0}", pdfBuffer.Length.ToString()));
// write the PDF buffer to HTTP response
HttpContext.Current.Response.BinaryWrite(pdfBuffer);
// call End() method of HTTP response to stop ASP.NET page processing
HttpContext.Current.Response.End();
}
else
{
base.Render(writer);
}
}
protected void buttonConvertCurrentPageToPdf_Click(object sender, EventArgs e)
{
convertToPdf = true;
}
}
2. Calling the Server.Execute Method to Get the HTML Code of
Another ASP.NET Page of the Same Application
The HttpServerUtility.Execute(String, TextWriter) method can be called from an ASP.NET
page to get the HTML code of another ASP.NET page in the same application. The ASP.NET
page for which to retrieve the HTML code is accessed in the session of the calling
ASP.NET page. Below there is a simple example of getting the HTML code of an ASP.NET
page and converting it to PDF when a 'Convert to PDF' button from the current page
is pressed:
Source Code Example
using System.IO;
using HiQPdf;
namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void buttonConvertToPdf_Click(object sender, EventArgs e)
{
// setup a TextWriter to capture the HTML code of the page to convert
TextWriter tw = new StringWriter();
// execute the 'AspNetPage.aspx' page in the same application and capture the HTML code
Server.Execute("PageToConvert.aspx", tw);
// get the HTML code from writer
string htmlCode = tw.ToString();
// convert the HTML code to PDF
// create the HTML to PDF converter
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
// the base URL used to resolve images, CSS and script files
string baseUrl = HttpContext.Current.Request.Url.AbsoluteUri;
// convert HTML code to a PDF memory buffer
byte[] pdfBuffer = htmlToPdfConverter.ConvertHtmlToMemory(htmlCode, baseUrl);
// inform the browser about the binary data format
HttpContext.Current.Response.AddHeader("Content-Type", "application/pdf");
// let the browser know how to open the PDF document, attachment or inline, and the file name
HttpContext.Current.Response.AddHeader("Content-Disposition",
String.Format("attachment; filename=HtmlToPdf.pdf;
size={0}", pdfBuffer.Length.ToString()));
// write the PDF buffer to HTTP response
HttpContext.Current.Response.BinaryWrite(pdfBuffer);
// call End() method of HTTP response to stop ASP.NET page processing
HttpContext.Current.Response.End();
}
}
}
|
|
|
|
The HtmlToPdf class has a Proxy property which exposes
an object with NetworkProxy type. In order to access the web page through the proxy
server you have to set the Host, Port, Protocol, Username and Password properties
of this NetworkProxy object with the appropriate values. Normally these values should
be the same to the values you use in a web browser to access the web page.
|
|
|
|
Normally these errors occur when loading the web page takes longer than expected.
The converter is configured by default to stop the loading of a web page after 120
seconds. This interval is in general sufficient to load most of the web pages. If
the web page is too large or the connection is too slow the 120 seconds loading
time limit might be exceeded and in this case the interval should be extended by
setting the HtmlLoadedTimeout property of the HtmlToPdf
class.
|
|
|
|
The methods to convert a HTML code of the HtmlToPdf,
HtmlToImage and HtmlToSvg
classes and the constructors of the PdfHtml and PdfHtmlImage classes have a baseUrl parameter
that can be used by the HiQPdf HTML converters to resolve the relative URLs found
in the HTML code you convert.
For example, if an image is referenced in the HTML code you convert with <img src="Images/image.png" />
and the image can be accessed from the http://www.mydomain.com/Images/image.png
fully qualified URL, then you have to set http://www.mydomain.com/
as base URL in your application code. Similar for the style and script files referenced
in the HTML code you convert.
|
|
|
|
The HTML width is given by the BrowserWidth property
of the HiQPdf.HtmlToPdf class which is 1200 pixels by default. At a default
DPI of 96 the HTML width is 12.5 inch which is larger than the default A4 portrait
page width of 8.27 inch and the HTML is scaled down to fit the PDF page which means
that the text and images might appear smaller than they are in HTML.
There are two options to avoid scaling down the HTML rendered in PDF:
1. To set to false the FitPageWidth property of the HiQPdf.PdfDocumentControl class
An object of the HiQPdf.PdfDocumentControl type is exposed by the Document
property of the HiQPdf.HtmlToPdf class. In this case the PDF page size width
will be automatically resized to display the whole HTML. You can disable this behavior
if you set the ResizePageWidth property of the HiQPdf.PdfDocumentControl
class to false.
2. To set the BrowserWidth property of the HiQPdf.HtmlToPdf
class to a smaller value
For a A4 portrait PDF page without margins the BrowserWidth property
should be set to 793 pixels which is the result of multiplying the width of the PDF
page 8.27 inch with 96 DPI. If you have set the left or the right margin for the PDF
pages you should take this in consideration when calculating the browser width.
|
|
|
|
The HiQPdf HTML to PDF Converter offers a great flexibility in setting the PDF document
headers and footers. Per PDF page customization of header and footer can be done
in PdfPageCreating event handler.
Basically you can add anything in the header and footer from plain text to full
HTML documents, override the default document header and footer in any page with
a customized header and footer, hide the header and footer in any PDF page.
In the code sample below, the default header on the second page will be replaced
with a bigger header containing the rendering of a whole website like www.google.com.
There also options to hide the header or footer on the first or on the second page
of the generated PDF document.
The headers and footers demo runs online here.
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using HiQPdf;
namespace HiQPdf_Demo
{
public partial class PdfHeadersAndFooters : System.Web.UI.Page
{
protected void buttonCreatePdf_Click(object sender, EventArgs e)
{
// create the HTML to PDF converter
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
// set the default header and footer of the document
SetHeader(htmlToPdfConverter.Document);
SetFooter(htmlToPdfConverter.Document);
// set a handler for PageCreatingEvent where to configure the PDF document pages
htmlToPdfConverter.PageCreatingEvent +=
new PdfPageCreatingDelegate(htmlToPdfConverter_PageCreatingEvent);
try
{
byte[] pdfBuffer = htmlToPdfConverter.ConvertUrlToMemory(textBoxUrl.Text);
// inform the browser about the binary data format
HttpContext.Current.Response.AddHeader("Content-Type", "application/pdf");
// let the browser know how to open the PDF document,
// attachment or inline, and the file name
HttpContext.Current.Response.AddHeader("Content-Disposition",
String.Format("attachment; filename=PdfHeadersAndFooters.pdf; size={0}",
pdfBuffer.Length.ToString()));
// write the PDF buffer to HTTP response
HttpContext.Current.Response.BinaryWrite(pdfBuffer);
// call End() method of HTTP response to stop ASP.NET page processing
HttpContext.Current.Response.End();
}
finally
{
// dettach from PageCreatingEvent event
htmlToPdfConverter.PageCreatingEvent -=
new PdfPageCreatingDelegate(htmlToPdfConverter_PageCreatingEvent);
}
}
void htmlToPdfConverter_PageCreatingEvent(PdfPageCreatingParams eventParams)
{
PdfPage pdfPage = eventParams.PdfPage;
int pdfPageNumber = eventParams.PdfPageNumber;
if (pdfPageNumber == 1)
{
// set the header and footer visibility in first page
pdfPage.DisplayHeader = checkBoxDisplayHeaderInFirstPage.Checked;
pdfPage.DisplayFooter = checkBoxDisplayFooterInFirstPage.Checked;
}
else if (pdfPageNumber == 2)
{
// set the header and footer visibility in second page
pdfPage.DisplayHeader = checkBoxDisplayHeaderInSecondPage.Checked;
pdfPage.DisplayFooter = checkBoxDisplayFooterInSecondPage.Checked;
if (pdfPage.DisplayHeader && checkBoxCustomizedHeaderInSecondPage.Checked)
{
// override the default document header in this page
// with a customized header of 200 points in height
pdfPage.CreateHeaderCanvas(200);
// layout a HTML document in header
PdfHtml htmlInHeader = new PdfHtml("http://www.google.com");
htmlInHeader.FitDestHeight = true;
pdfPage.Header.Layout(htmlInHeader);
// create a border for the customized header
PdfRectangle borderRectangle = new PdfRectangle(0, 0,
pdfPage.Header.Width - 1, pdfPage.Header.Height - 1);
borderRectangle.LineStyle.LineWidth = 0.5f;
borderRectangle.ForeColor = System.Drawing.Color.Navy;
pdfPage.Header.Layout(borderRectangle);
}
}
}
private void SetHeader(PdfDocumentControl htmlToPdfDocument)
{
// enable header display
htmlToPdfDocument.Header.Enabled = true;
// set header height
htmlToPdfDocument.Header.Height = 50;
float pdfPageWidth = htmlToPdfDocument.PageOrientation == PdfPageOrientation.Portrait ?
htmlToPdfDocument.PageSize.Width : htmlToPdfDocument.PageSize.Height;
float headerWidth = pdfPageWidth - htmlToPdfDocument.Margins.Left
- htmlToPdfDocument.Margins.Right;
float headerHeight = htmlToPdfDocument.Header.Height;
// set header background color
htmlToPdfDocument.Header.BackgroundColor = System.Drawing.Color.WhiteSmoke;
string headerImageFile = Server.MapPath("~") + @"\DemoFiles\Images\HiQPdfLogo.png";
PdfImage logoHeaderImage = new PdfImage(5, 5, 40,
System.Drawing.Image.FromFile(headerImageFile));
htmlToPdfDocument.Header.Layout(logoHeaderImage);
// layout HTML in header
PdfHtml headerHtml = new PdfHtml(50, 5,
@"<span style=""color:Navy; font-family:Times New Roman; font-style:italic"">
Quickly Create High Quality PDFs with </span>
<a href=""http://www.hiqpdf.com"">HiQPdf</a>", null);
headerHtml.FitDestHeight = true;
htmlToPdfDocument.Header.Layout(headerHtml);
// create a border for header
PdfRectangle borderRectangle = new PdfRectangle(1, 1, headerWidth - 2, headerHeight - 2);
borderRectangle.LineStyle.LineWidth = 0.5f;
borderRectangle.ForeColor = System.Drawing.Color.Navy;
htmlToPdfDocument.Header.Layout(borderRectangle);
}
private void SetFooter(PdfDocumentControl htmlToPdfDocument)
{
// enable footer display
htmlToPdfDocument.Footer.Enabled = true;
// set footer height
htmlToPdfDocument.Footer.Height = 50;
// set footer background color
htmlToPdfDocument.Footer.BackgroundColor = System.Drawing.Color.WhiteSmoke;
float pdfPageWidth = htmlToPdfDocument.PageOrientation == PdfPageOrientation.Portrait ?
htmlToPdfDocument.PageSize.Width : htmlToPdfDocument.PageSize.Height;
float footerWidth = pdfPageWidth - htmlToPdfDocument.Margins.Left -
htmlToPdfDocument.Margins.Right;
float footerHeight = htmlToPdfDocument.Footer.Height;
// layout HTML in footer
PdfHtml footerHtml = new PdfHtml(5, 5,
@"<span style=""color:Navy; font-family:Times New Roman; font-style:italic"">
Quickly Create High Quality PDFs with </span>
<a href=""http://www.hiqpdf.com"">HiQPdf</a>", null);
footerHtml.FitDestHeight = true;
htmlToPdfDocument.Footer.Layout(footerHtml);
if (checkBoxDisplayPageNumbersInFooter.Checked)
{
// add page numbering
System.Drawing.Font pageNumberingFont =
new System.Drawing.Font(
new System.Drawing.FontFamily("Times New Roman"),
8, System.Drawing.GraphicsUnit.Point);
PdfText pageNumberingText = new PdfText(5, footerHeight - 12,
"Page {CrtPage} of {PageCount}", pageNumberingFont);
pageNumberingText.HorizontalAlign = PdfTextHAlign.Center;
pageNumberingText.EmbedSystemFont = true;
pageNumberingText.ForeColor = System.Drawing.Color.DarkGreen;
htmlToPdfDocument.Footer.Layout(pageNumberingText);
}
string footerImageFile = Server.MapPath("~") + @"\DemoFiles\Images\HiQPdfLogo.png";
PdfImage logoFooterImage = new PdfImage(footerWidth - 40 - 5, 5, 40,
System.Drawing.Image.FromFile(footerImageFile));
htmlToPdfDocument.Footer.Layout(logoFooterImage);
// create a border for footer
PdfRectangle borderRectangle = new PdfRectangle(1, 1,
footerWidth - 2, footerHeight - 2);
borderRectangle.LineStyle.LineWidth = 0.5f;
borderRectangle.ForeColor = System.Drawing.Color.DarkGreen;
htmlToPdfDocument.Footer.Layout(borderRectangle);
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
textBoxUrl.Text = "http://www.hiqpdf.com/html/html5_introduction.html";
Master.SelectNode("pdfHeadersAndFooters");
}
}
}
}
|
|
|
|
The header and footer can be hidden or changed on any page of the generated PDF
document, including the first page. For a complete example of working with headers
and footers in PDF please check the question above 'How can I replace, in only one
or a few PDF pages, the header and footer of the created PDF document with a customized
header and footer'.
|
|
|
|
The {CrtPage} and {PageCount} place holders for page numbering work only in the
plain text objects laid out in header and footer.
To have page numbering in HTML, you have to layout a different HTML in each page
header or footer. For a complete example of how to change the default header and
footer in PDF and render HTML in the customized header or footer please check the
question above ' How can I replace, in only one or a few PDF pages, the header and
footer of the created PDF document with a customized header and footer'.
The example below shows how to add page numbering in footer using page numbering
place holders in a plain text object.
Adding Page Numbering in Text Objects
In this demo you can see how to enable the header and footer and how to add HTML,
text, images and page numbering to header and footer:
Source Code Example
private void buttonConvertToPdf_Click(object sender, EventArgs e)
{
// create the HTML to PDF converter
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
// set header and footer
SetHeader(htmlToPdfConverter.Document);
SetFooter(htmlToPdfConverter.Document);
Cursor = Cursors.WaitCursor;
// convert HTML to PDF
string pdfFile = null;
try
{
// convert URL
string url = textBoxUrl.Text;
pdfFile = Application.StartupPath + @"\DemoOutput\HeaderAndFooter.pdf";
htmlToPdfConverter.ConvertUrlToFile(url, pdfFile);
}
catch (Exception ex)
{
MessageBox.Show(String.Format("Conversion failed. {0}", ex.Message));
return;
}
finally
{
Cursor = Cursors.Arrow;
}
// open the PDF document
try
{
System.Diagnostics.Process.Start(pdfFile);
}
catch (Exception ex)
{
MessageBox.Show(String.Format("Conversion succeeded but
cannot open '{0}'. {1}", pdfFile, ex.Message));
}
}
private void SetHeader(PdfDocumentControl htmlToPdfDocument)
{
// enable header display
htmlToPdfDocument.Header.Enabled = checkBoxAddHeader.Checked;
if (!htmlToPdfDocument.Header.Enabled)
return;
// set header height
htmlToPdfDocument.Header.Height = 50;
float headerWidth = htmlToPdfDocument.PageSize.Width - htmlToPdfDocument.Margins.Left - htmlToPdfDocument.Margins.Right;
float headerHeight = htmlToPdfDocument.Header.Height;
// set header background color
htmlToPdfDocument.Header.BackgroundColor = Color.WhiteSmoke;
string headerImageFile = Application.StartupPath + @"\DemoFiles\Images\HiQPdfLogo.png";
PdfImage logoHeaderImage = new PdfImage(5, 5, 40, Image.FromFile(headerImageFile));
// use alpha blending to render a transparent image if the document was not restricted to PDF/A standard
logoHeaderImage.AlphaBlending = !checkBoxPdfA.Checked;
htmlToPdfDocument.Header.Layout(logoHeaderImage);
// layout HTML in header
PdfHtml headerHtml = new PdfHtml(50, 5, 0, headerHeight,
@"<span style=""color:Navy;
font-family:Times New Roman; font-style:italic"">
Quickly Create High Quality PDFs with </span><a href=""http://www.hiqpdf.com"">HiQPdf</a>",
null);
headerHtml.FitDestHeight = true;
headerHtml.FontEmbedding = checkBoxFontEmbedding.Checked;
htmlToPdfDocument.Header.Layout(headerHtml);
// create a border for header
PdfRectangle borderRectangle = new PdfRectangle(1, 1, headerWidth - 2, headerHeight - 2);
borderRectangle.LineStyle.LineWidth = 0.5f;
borderRectangle.ForeColor = Color.Navy;
htmlToPdfDocument.Header.Layout(borderRectangle);
}
private void SetFooter(PdfDocumentControl htmlToPdfDocument)
{
// enable footer display
htmlToPdfDocument.Footer.Enabled = checkBoxAddFooter.Checked;
if (!htmlToPdfDocument.Footer.Enabled)
return;
// set footer height
htmlToPdfDocument.Footer.Height = 50;
// set footer background color
htmlToPdfDocument.Footer.BackgroundColor = Color.WhiteSmoke;
float footerHeight = htmlToPdfDocument.Footer.Height;
float footerWidth = htmlToPdfDocument.PageSize.Width - htmlToPdfDocument.Margins.Left -
htmlToPdfDocument.Margins.Right;
// layout HTML in footer
PdfHtml footerHtml = new PdfHtml(5, 5, 0, footerHeight,
@"<span style=""color:Navy;
font-family:Times New Roman; font-style:italic"">
Quickly Create High Quality PDFs with </span><a href=""http://www.hiqpdf.com"">HiQPdf</a>",
null);
footerHtml.FitDestHeight = true;
footerHtml.FontEmbedding = checkBoxFontEmbedding.Checked;
htmlToPdfDocument.Footer.Layout(footerHtml);
// add page numbering
Font pageNumberingFont = new Font(new FontFamily("Times New Roman"), 8, GraphicsUnit.Point);
PdfText pageNumberingText = new PdfText(5, footerHeight - 12, "Page {CrtPage} of {PageCount}", pageNumberingFont);
pageNumberingText.HorizontalAlign = PdfTextHAlign.Center;
pageNumberingText.EmbedSystemFont = true;
pageNumberingText.ForeColor = Color.DarkGreen;
htmlToPdfDocument.Footer.Layout(pageNumberingText);
string footerImageFile = Application.StartupPath + @"\DemoFiles\Images\HiQPdfLogo.png";
PdfImage logoFooterImage = new PdfImage(footerWidth - 40 - 5, 5, 40, Image.FromFile(footerImageFile));
// use alpha blending to render a transparent image if the document was not restricted to PDF/A standard
logoFooterImage.AlphaBlending = !checkBoxPdfA.Checked;
htmlToPdfDocument.Footer.Layout(logoFooterImage);
// create a border for footer
PdfRectangle borderRectangle = new PdfRectangle(1, 1, footerWidth - 2, footerHeight - 2);
borderRectangle.LineStyle.LineWidth = 0.5f;
borderRectangle.ForeColor = Color.DarkGreen;
htmlToPdfDocument.Footer.Layout(borderRectangle);
}
|
|
|
|
In general, using the HiQPdf HTML to PDF conversion engine it is possible to determine
the position in PDF of any HTML element. It is also possible to hide from the created
PDF document any HTML element. Using these two features it is possible to configure
the converter to hide an image from PDF and to determine where that image would
have been located in PDF. Based on this information, after the HTML to PDF conversion,
a PdfImage object can be laid out in the same place where the image from
HTML would have been laid out.
The HiQPdf library package that can be downloaded from the website contains a complete
sample application for this approach. You can also find online the source code and documentation and the live demo for this sample.
|
|
|
|
When you convert HTML to PDF you can create a PDF/A compliant document if you set
HtmlToPdf.Document.PdfStandard = PdfStandard.PdfA. Similar for PDF/X compliant documents.
You can also create PDF documents compliant to PDF/A and PDF/X using the PdfDocument.CreateStandardPdf()
static method.
|
|
|
|
You can set the page-break-inside:avoid CSS attribute in the HTML element style.
This will ensure that the entire HTML element will be rendered on only one page
in PDF if it is possible.
You can read
more about page breaks control in PDF in the our online help.
|
|
|
|
You can set the page-break-before:always CSS attribute in the HTML element style
to force a page break in PDF right before the position where the HTML element is
rendered. You can set the page-break-after:always CSS attribute in the HTML element
style to force a page break in PDF right after the position where the HTML element
is rendered.
You can read
more about page breaks control in PDF in the our online help.
|
|
|
|
Using the HiQPdf library you can write a small JavaScript code in PDF to set the
document zoom level when the document is opened:
// the JavaScript code to execute
string javaScriptCode = "this.zoom=100;";
// create a JavaScript action
PdfJavaScriptAction javaScriptAction = new PdfJavaScriptAction(javaScriptCode);
// create an empty PDF document
PdfDocument document = new PdfDocument();
// set the document JavaScript open action
document.SetOpenAction(javaScriptAction);
|
|
|
|
There are two possible reasons for this behavior:
1. By default the conversion to PDF starts immediately
after the HTML document was loaded in converter and this default behavior is suitable
for converting most of the HTML documents. However, there are situations when some
JavaScript scripts continue execution even after the document was loaded. In this
case it is necessary to configure the converter to wait a predefined interval before
starting the rendering to PDF or to configure the converter to wait for the hiqPdfConverter.startConversion()
method to be manually called from JavaScript.
You can find more details about triggering modes in the online documentation.
To configure the converter to wait an additional time before starting conversion
you can use the sample code below:
Source Code Example
// set conversion triggering mode
htmlToPdfConverter.TriggerMode = ConversionTriggerMode.WaitTime;
// wait 5 seconds for the scripts to execute before starting conversion
htmlToPdfConverter.WaitBeforeConvert = 5;
2. The converter is configured by default to stop the
loading of a web page after 120 seconds. The conversion to PDF can continue even
if only a partial layout of the page was performed when the timeout occurred. The
120 seconds interval is in general sufficient to load most of the web pages. If
the web page is too large or the connection is too slow the 120 seconds loading
time limit might be exceeded and in this case the interval should be extended by
setting the HtmlLoadedTimeout property of the HtmlToPdf
class.
|
|
|
|
These types of errors can occur in 32-bit processes when there is not enough memory
in the process address space. The available address space for a .NET application
in a 32-bit process is about 1 GB. This limit applies also to the IIS worker process
and it should be enough in general for converting to PDF most of the HTML documents.
When converting very large HTML documents with many large images or with a background
image repeated in width and height the available memory might not be enough during
conversion and one of the errors above can be thrown.
In order to fix this you can try two approaches:
1. Reference images with smaller physical dimensions
in HTML to speed up conversion and to reduce the memory usage during conversion.
It is a common practice to reference in HTML very large images of thousands of pixels
even if the image box in HTML given by the src tag is ten times smaller.
In this case it is recommended to get a smaller thumbnail of the big image and reference
it in HTML instead of the large full size image.
2. Run the HiQPdf library in a 64-bit process on a 64-bit
Windows machine. A Windows Forms application targeting 'Any CPU' in Visual Studio
will run in the 64-bit mode on a 64-bit Windows machine. An ASP.NET application
hosted in IIS might run in 32-bit mode even on a 64-bit machine if the 'Enable 32-bit
Applications' property is true in the IIS application pool advanced properties and
you should set this property to false in order to run the ASP.NET application in
64-mode.
|
|
|
|
This error can occur if the HiQPdf.dep resource file there is not in the same folder
with HiQPdf.dll assembly at runtime. When you reference the HiQPdf.dll in your application
in Visual Studio and you build that application, HiQPdf.dll and HiQPdf.dep will
be automatically copied in the Bin folder of the application. Moreover, the HiQPdf.dep
file will be automatically copied near the HiQPdf.dll when you add the assembly
to GAC. This means that in general the two files will stay together, but there might
be situations when this does not happen for example when you manually copy the files
on a server and you forget to copy the HiQPdf.dep or if the assembly is automatically
copied in a temporary location at runtime by a shadow copy mechanism which doesn't
take into account the assembly resources.
The HiQPdf API offers the SetDepFilePath() method in
HtmlToPdf and PdfHtml classes which you can call with the fully qualified
name of HiQPdf.dep file (e.g. C:\Resources\HiQPdf.dep ) as parameter to explicitly
indicate the HiQPdf.dep resource file you want to use at runtime.
The user running the HiQPdf HTML to PDF Converter should have execute permission
for the HiQPdf.dep file. To make sure this condition is satisfied, you can right
click on the file in Windows Explorer and in Properties, Security tab give Everyone
user the Read and Execute permission for this file. Also make sure the HiQPdf.dll
and HiQPdf.dep files were not blocked by Windows. For this you can right click on
the file in Windows Explorer and in the Properties, General tab check if there is
the Unblock button. If this button exists then click on it to unblock the file.
|
|
|
|
For Azure App Service which runs the applications in a sandbox with many restrictions you have to use the
multi-platform solution described at Multi-Platform PDF Library for .NET Core.
HiQPdf library can be used without restrictions in Windows Azure Cloud Services and Virtual Machines.
In the software Zip package, in 'Samples\Azure\CloudService' folder, there is a demo application for using the library in an Azure Cloud Service.
The 'Notes.txt' file from the same folder contains instructions for deploying the application in cloud and also instructions for how to transform
your own ASP.NET application into the Web Role of an Azure Cloud Service.
|
|
|
|
For Linux you have to use the multi-platform solution described at Multi-Platform PDF Library for .NET Core.
The HiQPdf Client-Server Architecture consists in HiQPdf Server application which can run as a Windows Service or as an Azure Cloud Service
and a client library for .NET Core that can be used in any .NET Core application for any platform which offers support for
.NET Core or .NET Standard 2.0 and above.
You can deploy your .NET Core applications on Windows, Linux and MacOS operating systems
or in Azure App Service for Windows and Linux.
|
|
|
|
For .NET Core there is a separate library you can use in your .NET Core applications on Windows.
|
|
|
|
HiQPdf library is a .NET library and it cannot be referenced directly into a native
Windows application. You can register the HiQPdf classes for COM clients and produce
a type library file by executing the following command in an Administrator command
prompt:
regasm
HiQPdf.dll /tlb:HiQPdf.tlb
The HiQPdf.tlb will be included in the C++ application code to offer the prototypes
for HiQPdf classes and methods. The compiler will produce a C++ header file named
HiQPdf.tlh from the TLB file, containing the HiQPdf library types and methods prototypes.
The HiQPdf.dll and HiQPdf.dep files must be copied near the application executable
or otherwise you have to install the HiQPdf.dll in GAC to make it available for
COM infrastructure. The C++ code of a simple console application which converts
an URL and saves the resulted PDF document to a file on disk looks like below:
#include <windows.h>
#include <iostream>
#import "HiQPdf.tlb" raw_interfaces_only
using namespace HiQPdf;
int main()
{
CoInitialize(0);
{
// create the HTML to PDF converter
_HtmlToPdfPtr htmlToPdfConverter(__uuidof(HtmlToPdf));
// get a reference to the PDF document control object from converter
_PdfDocumentControl * pdfDocumentControl;
htmlToPdfConverter->get_Document(&pdfDocumentControl);
// set PDF page orientation
pdfDocumentControl->put_PageOrientation(PdfPageOrientation_Portrait);
// set PDF page margins
_PdfMargins* pdfMargins;
pdfDocumentControl->get_Margins(&pdfMargins);
pdfMargins->put_Left(10);
pdfMargins->put_Right(10);
pdfMargins->put_Top(10);
pdfMargins->put_Bottom(10);
// create the URL to convert and output PDF file name strings
BSTR urlToConvert = SysAllocString(L"http://www.google.com");
BSTR outPdfFile = SysAllocString(L"out.pdf");
// call the converter to convert the HTML document to a PDF file
htmlToPdfConverter->ConvertUrlToFile(urlToConvert, outPdfFile);
// free the allocated strings
SysFreeString(urlToConvert);
SysFreeString(outPdfFile);
}
CoUninitialize();
return 0;
}
|
|
|
Purchase FAQs
|
|
|
You can choose a license for our software based on the number of developers working
to develop your application, as described in the license agreement. If you don't know in advance how many developers will
be working on your application you can consider purchasing a license which covers
many developer seats. The license cost increases very little when the number of
developer seats increases and therefore with a small additional amount you can cover
all the current and future needs for software development in your company. The purchased
license can be reused in other applications developed by you or by the software
development companies you employ to create your software which makes the purchased
license a good and safe investment for your company. A Team License covers up to
5 developer seats and for a small additional amount you can purchase an Enterprise
License which covers an unlimited number of developers seats and also includes better
technical support.
|
|
|
|
The license should be purchased by your client because your client is the owner
of the software you develop. You can use the license purchased by your client only
in applications developed for that client. You cannot use the license purchased
by a client in applications developed for another client.
The type of license your client should purchase is given by the number of developers
developing the application as described in the license agreement. If you don't know in advance how many developers will
be working to develop the application you should advice your client to purchase
a license which covers many developer seats. The license cost increases very little
when the number of developer seats increases and therefore with a small additional
amount a large or an unlimited number of developer seats can be covered. A Team
License covers up to 5 developer seats and for a small additional amount your client
can purchase an Enterprise License which covers an unlimited number of developers
seats and also includes better technical support.
|
|
|
|
No, our software is licensed per developer seat, not per deployment. If you are
the owner of an application using a licensed version of our software component you
can deploy the application on any number of servers you need and you can distribute
your application to any number of end users without any additional cost.
|
|
|
|
A purchased license is perpetual and it never expires but the software upgrades
and the technical support are covered by the initial license price only for the
first year from purchase. After the first year you have the possibility to renew
the maintenance for one more year at a discounted price of 50% of the initial price.
In order to renew the software maintenance please contact our sales department by email and provide the initial purchase
order ID or the serial number you obtained after purchase.
|
|
|
|
It is not possible to upgrade from a type of license to another type of license.
You are encouraged to initially purchase a license for multiple developer seats
because the license cost increases very little when the number of developer seats
increases and therefore with a small additional amount you can cover all the current
and future needs for software development in your company. The purchased license
can be reused in other applications developed by you or by the software development
companies you employ to create your software which makes the purchased license a
good and safe investment for your company. A Team License covers up to 5 developer
seats and for a small additional amount you can purchase an Enterprise License which
covers an unlimited number of developers seats and also includes better technical
support.
|
|
|
|
The latest version of the software is available for download on the downloads page. During the maintenance period you
can upgrade for free to a newer version of the software. In order to obtain a serial
number for the latest version you have to contact our sales department by email and request a license key for the
latest version. Please include in the email body the initial purchase order ID or
the latest maintenance renewal order ID.
If you are not under the maintenance period anymore you have to renew the software
maintenance first. In order to renew the software maintenance please contact our sales department by email and provide the
initial purchase order ID or the serial number you obtained after initial purchase.
|
|
|