Current WebPage to Pdf in Asp.Net | |
A web application often needs to convert the page the user is looking at to pdf with a click of a button, taking into account the values the user has just entered into that page (a filled in form, for example).
Converting the page url with ConvertUrl(String) does not do this: the converter fetches the url as a new, anonymous request, so it gets a fresh copy of the page without the user's input (and without their session). The technique is to let the application render its own page to html - with the current values in it - and then convert that html string with ConvertHtmlString(String, String).
The second parameter of ConvertHtmlString(String, String) is the base url the engine resolves the captured page's relative resources against - stylesheets, images, fonts. It must be the application's http origin including the path base and a trailing slash, not a file system path. A file system path loads no stylesheets and produces an unstyled pdf. |
The page model renders its own page to a string and hands that string to the converter. Rendering a Razor page to a string is done with the Razor view engine; the complete, reusable service that does it (ViewRenderService.cs) ships with the SelectPdf samples, alongside the CurrentWebPageToPdf page that uses it.
public class CurrentWebPageToPdfModel : PageModel { private readonly IViewRenderService _viewRenderService; public CurrentWebPageToPdfModel(IViewRenderService viewRenderService) { _viewRenderService = viewRenderService; } // the values the user typed into the page - they are posted back, // so they are still set when the page is rendered again below [BindProperty] public string TxtSampleText { get; set; } [BindProperty] public bool ChkSampleCheckbox { get; set; } public void OnGet() { TxtSampleText = "sample text"; ChkSampleCheckbox = true; } public async Task<IActionResult> OnPost() { // render THIS page to a html string, with the posted values in it string htmlString = await _viewRenderService.RenderToStringAsync( "CurrentWebPageToPdf", "~/Pages/_Layout.cshtml", new CurrentWebPageToPdfModel(_viewRenderService) { TxtSampleText = this.TxtSampleText, ChkSampleCheckbox = this.ChkSampleCheckbox, }); // the http origin the engine resolves the page's relative // stylesheets, images and fonts against string baseUrl = $"{Request.Scheme}://{Request.Host}{Request.PathBase}/"; // instantiate a html to pdf converter object HtmlToPdf converter = new HtmlToPdf(); // create a new pdf document converting the html string of the page PdfDocument doc = converter.ConvertHtmlString(htmlString, baseUrl); // 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; } }
The conversion step itself is the same whatever produced the html string and whatever framework the application uses - so an application that already has the rendered html of a page (from a view engine, a template engine, or its own string building) only needs the following:
// instantiate a html to pdf converter object HtmlToPdf converter = new HtmlToPdf(); // create a new pdf document converting the html string of the page // (baseUrl resolves the relative resources referenced by that html) PdfDocument doc = converter.ConvertHtmlString(htmlString, baseUrl); // save pdf document doc.Save("Sample.pdf"); // close pdf document doc.Close();