Creating a PDF document from the stream of a HTTP request.
public class HomeController : Controller {
public HomeController() {
converter = new HtmlToPdf();
InitializeConverter();
}
public void Index() {
ConvertHtmlToPdf(new Uri("http://localhost:52328/CertificateOfOrigin?noCertificate=2691"));
}
public void ConvertHtmlToPdf(Uri toConvert) {
if(toConvert == null) throw new ArgumentNullException(nameof(toConvert));
using(var stream =new MemoryStream()) {
var doc = converter.ConvertUrl(toConvert.AbsoluteUri);
// The doc.AddTemplate returns a PdfTemplate and should be assigned to doc.Footer
doc.Footer = doc.AddTemplate(doc.Pages[0].ClientRectangle.Width, 100);
var pageNumbering = new PdfTextElement(20, 50, "Page {page_number} of {total_pages}", doc.Fonts[0], Color.Black);
// Once template defined, I add it to the doc Footer. But...
doc.Footer.Add(pageNumbering); // Throws a NullPointerException?
doc.Footer = template;
doc.Save(stream);
doc.Close();
using(var ms = new MemoryStream(stream.ToArray())) {
Response.AddHeader("content-disposition", "filename=certificate-of-origin.pdf");
Response.ContentType = "application/pdf";
ms.CopyTo(Response.OutputStream);
Response.End();
Response.Close();
}
}
}
private void InitializeConverter() {
converter.Options.MarginBottom = 0;
converter.Options.MarginLeft = 0;
converter.Options.MarginRight = 0;
converter.Options.MarginTop = 0;
converter.Options.PdfPageSize = PdfPageSize.Letter;
}
private readonly HtmlToPdf converter;
}
I put a breakpoint and quick watched the return of doc.AddTemplate method call and it returns an actual PdfTemplate no problem!
Other than that, everything works fine. Document is generated no problem, except when I uncomment the page numbering because the doc.Footer remains null despite its assignment.
Could it be a bug? Idk.
You need to either set the header/footer content before the conversion, like here: https://selectpdf.com/demo-mvc/HtmlToPdfHeadersAndFooters
using System;
using System.Web.Mvc;
namespace SelectPdf.Samples.Controllers
{
public class HtmlToPdfHeadersAndFootersController : Controller
{
// GET: HtmlToPdfHeadersAndFooters
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult SubmitAction(FormCollection collection)
{
// get parameters
string headerUrl = Server.MapPath("~/files/header.html");
string footerUrl = Server.MapPath("~/files/footer.html");
bool showHeaderOnFirstPage = collection["ChkHeaderFirstPage"] == "on";
bool showHeaderOnOddPages = collection["ChkHeaderOddPages"] == "on";
bool showHeaderOnEvenPages = collection["ChkHeaderEvenPages"] == "on";
int headerHeight = 50;
try
{
headerHeight = Convert.ToInt32(collection["TxtHeaderHeight"]);
}
catch { }
bool showFooterOnFirstPage = collection["ChkFooterFirstPage"] == "on";
bool showFooterOnOddPages = collection["ChkFooterOddPages"] == "on";
bool showFooterOnEvenPages = collection["ChkFooterEvenPages"] == "on";
int footerHeight = 50;
try
{
footerHeight = Convert.ToInt32(collection["TxtFooterHeight"]);
}
catch { }
// instantiate a html to pdf converter object
HtmlToPdf converter = new HtmlToPdf();
// header settings
converter.Options.DisplayHeader = showHeaderOnFirstPage ||
showHeaderOnOddPages || showHeaderOnEvenPages;
converter.Header.DisplayOnFirstPage = showHeaderOnFirstPage;
converter.Header.DisplayOnOddPages = showHeaderOnOddPages;
converter.Header.DisplayOnEvenPages = showHeaderOnEvenPages;
converter.Header.Height = headerHeight;
PdfHtmlSection headerHtml = new PdfHtmlSection(headerUrl);
headerHtml.AutoFitHeight = HtmlToPdfPageFitMode.AutoFit;
converter.Header.Add(headerHtml);
// footer settings
converter.Options.DisplayFooter = showFooterOnFirstPage ||
showFooterOnOddPages || showFooterOnEvenPages;
converter.Footer.DisplayOnFirstPage = showFooterOnFirstPage;
converter.Footer.DisplayOnOddPages = showFooterOnOddPages;
converter.Footer.DisplayOnEvenPages = showFooterOnEvenPages;
converter.Footer.Height = footerHeight;
PdfHtmlSection footerHtml = new PdfHtmlSection(footerUrl);
footerHtml.AutoFitHeight = HtmlToPdfPageFitMode.AutoFit;
converter.Footer.Add(footerHtml);
// add page numbering element to the footer
if (collection["ChkPageNumbering"] == "on")
{
// page numbers can be added using a PdfTextSection object
PdfTextSection text = new PdfTextSection(0, 10,
"Page: {page_number} of {total_pages} ",
new System.Drawing.Font("Arial", 8));
text.HorizontalAlign = PdfTextHorizontalAlign.Right;
converter.Footer.Add(text);
}
// create a new pdf document converting an url
PdfDocument doc = converter.ConvertUrl(collection["TxtUrl"]);
// custom header on page 3
if (doc.Pages.Count >= 3)
{
PdfPage page = doc.Pages[2];
PdfTemplate customHeader = doc.AddTemplate(
page.PageSize.Width, headerHeight);
PdfHtmlElement customHtml = new PdfHtmlElement(
"<div><b>This is the custom header that will " +
"appear only on page 3!</b></div>",
string.Empty);
customHeader.Add(customHtml);
page.CustomHeader = customHeader;
}
// save pdf document
byte[] pdf = doc.Save();
// close pdf document
doc.Close();
// return resulted pdf document
FileResult fileResult = new FileContentResult(pdf, "application/pdf");
fileResult.FileDownloadName = "Document.pdf";
return fileResult;
}
}
}
Or use this approach, to add headers/footers to an already generated pdf: https://selectpdf.com/demo-mvc/ExistingPdfHeadersAndFooters
using System.Web.Mvc;
using System.Drawing;
namespace SelectPdf.Samples.Controllers
{
public class ExistingPdfHeadersAndFootersController : Controller
{
// GET: ExistingPdfHeadersAndFooters
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult SubmitAction(FormCollection collection)
{
// the test file
string filePdf = Server.MapPath("~/files/selectpdf.pdf");
string imgFile = Server.MapPath("~/files/logo.png");
// resize the content
PdfResizeManager resizer = new PdfResizeManager();
resizer.Load(filePdf);
// add extra top and bottom margins
resizer.PageMargins = new PdfMargins(0, 0, 90, 40);
// add the header and footer to the existing (now resized pdf document)
PdfDocument doc = resizer.GetDocument();
// header template (90 points in height) with image element
PdfTemplate header = doc.AddTemplate(doc.Pages[0].ClientRectangle.Width, 90);
PdfImageElement img1 = new PdfImageElement(10, 10, imgFile);
header.Add(img1);
// footer template (40 points in height) with text element
PdfTemplate footer = doc.AddTemplate(new RectangleF(0,
doc.Pages[0].ClientRectangle.Height - 40,
doc.Pages[0].ClientRectangle.Width, 40));
// create a new pdf font
PdfFont font2 = doc.AddFont(PdfStandardFont.Helvetica);
font2.Size = 12;
PdfTextElement text1 = new PdfTextElement(10, 10,
"Generated by SelectPdf. Page number {page_number} of {total_pages}.",
font2);
text1.ForeColor = System.Drawing.Color.Blue;
footer.Add(text1);
// save pdf document
byte[] pdf = doc.Save();
// close pdf document
resizer.Close();
// return resulted pdf document
FileResult fileResult = new FileContentResult(pdf, "application/pdf");
fileResult.FileDownloadName = "Document.pdf";
return fileResult;
}
}
}
The best approach is the first, so try to move your footer setting before the conversion.