- Home
- .NET tutorials
- How to create a free PDF document using HTML & CSS in ASP.NET Core
How to create a free PDF document using HTML & CSS in ASP.NET Core
Published: Thursday 1 April 2021
There are a number of Nuget packages out there that allow us to create a PDF document for free in ASP.NET Core.
Resources
To try out this application, download the code example from our code examples section.
The Application
For this application, we are going to create an ASP.NET Core Web MVC app.
Setting Up a PDF Controller
The first thing we want to do is create a new controller called PdfController.
Route attribute to it. This allows us to point the whole of the PdfController to a particular endpoint.
Route attribute to pdf. Therefore, any action created in the PDFController will prefix with /pdf.
// PDFController.cs
[Route("pdf")]
public class PdfController : Controller
{
}
Next, we need to create our action.
Task.
Route attribute and set it to website.
/pdf/website.
// PDFController.cs
[Route("pdf")]
public class PdfController : Controller
{
[Route("website")]
public async Task<IActionResult> WebsiteAsync()
{
return null;
}
}
Now that we have set up the controller, we need to bring in the Select.HtmlToPdf.NetCore Nuget package.
Install-Package Select.HtmlToPdf.NetCore
This Nuget package will allow us to create a PDF document into ASP.NET Core.
Render a Website into a PDF Document
We now have the controller set up. The Nuget package manager has been imported.
HtmlToPdf class.
HtmlToPdf class, and run the ConvertUrl method. Within that method, we will pass in a parameter which will be the website address. In our instance the parameter will be https://www.roundthecode.com.
PDFDocument instance and append to the document everytime we call the ConvertUrl
PDFDocument instance by calling the Save method.
application/pdf.
[Route("pdf")]
public class PdfController : Controller
{
[Route("website")]
public async Task<IActionResult> WebsiteAsync()
{
var mobileView = new HtmlToPdf();
mobileView.Options.WebPageWidth = 480;
var tabletView = new HtmlToPdf();
tabletView.Options.WebPageWidth = 1024;
var fullView = new HtmlToPdf();
fullView.Options.WebPageWidth = 1920;
var pdf = mobileView.ConvertUrl("https://www.roundthecode.com/");
pdf.Append(tabletView.ConvertUrl("https://www.roundthecode.com/"));
pdf.Append(fullView.ConvertUrl("https://www.roundthecode.com/"));
var pdfBytes = pdf.Save();
return File(pdfBytes, "application/pdf");
}
}
Saving the PDF Document to File Storage
It's all very well rendering a PDF document as part of the HTTP response, but what if we want to save it to file storage?
StreamWriter, saving the stream into a file called RoundTheCode.pdf.
public async Task<IActionResult> WebsiteAsync()
{
...
var pdfBytes = pdf.Save();
using (var streamWriter = new StreamWriter(@"C:\inetpub\wwwroot\RoundTheCode.Pdf\RoundTheCode.pdf"))
{
await streamWriter.BaseStream.WriteAsync(pdfBytes, 0, pdfBytes.Length);
}
return File(pdfBytes, "application/pdf");
}
And that's it! Our PDF file has been saved to file storage.
Create a PDF Document from HTML and CSS
Our next task is to render a PDF document from HTML and CSS.
wwwroot/css/invoice.css and our HTML into a partial view located inside Views/Pdf/_Invoice.cshtml.
Views/Pdf/_Invoice.cshtml.
ICompositeViewEngine into PdfController.
// PdfController.cs
public class PdfController : Controller
{
protected readonly ICompositeViewEngine _compositeViewEngine;
public PdfController(ICompositeViewEngine compositeViewEngine)
{
_compositeViewEngine = compositeViewEngine;
}
...
}
From there, we can start writing the method to turn our invoice into a PDF document.
StreamWriter. This instance will allow us to write the PDF file from the view.
FindView method from the ICompositeViewEngine instance.
ViewContext instance. This is what happens normally when rendering a view in MVC.
ViewContext instance into our StreamWriter instance. From there, we can convert our StreamWriter instance into a string, and that will give us the HTML of our invoice.
HtmlToPdf. Then, we can call the ConvertHtmlString method and pass in the HTML as the parameter.
// PdfController.cs
public class PdfController : Controller
{
...
[Route("invoice")]
public async Task<IActionResult> InvoiceAsync()
{
using (var stringWriter = new StringWriter())
{
var viewResult = _compositeViewEngine.FindView(ControllerContext, "_Invoice", false);
if (viewResult.View == null)
{
throw new ArgumentNullException($"'Views/Pdf/_Invoice.cshtml' does not match any available view");
}
var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary());
var viewContext = new ViewContext(
ControllerContext,
viewResult.View,
viewDictionary,
TempData,
stringWriter,
new HtmlHelperOptions()
);
await viewResult.View.RenderAsync(viewContext);
var htmlToPdf = new HtmlToPdf(1000, 1414);
htmlToPdf.Options.DrawBackground = true;
var pdf = htmlToPdf.ConvertHtmlString(stringWriter.ToString());
var pdfBytes = pdf.Save();
using (var streamWriter = new StreamWriter(@"C:\inetpub\wwwroot\RoundTheCode.Pdf\Invoice.pdf"))
{
await streamWriter.BaseStream.WriteAsync(pdfBytes, 0, pdfBytes.Length);
}
return File(pdfBytes, "application/pdf");
}
}
}
Dynamic PDF Documents
This now allows us to create dynamic PDF documents for our ASP.NET Core web application.
Latest tutorials
Swagger's missing in .NET 10 - How to add it back
Swagger is missing in .NET 10. Learn why it was removed, how to add it back, and explore alternatives like Scalar, Redoc, Postman, and .http files.