How to export view as pdf in Asp.Net Core
Hello, guys! Welcome to Code2Night. In this blog post, we'll explore how to export view as pdf in Asp.Net Core using the iTextSharp library, which is a powerful and free tool.
ASP.NET Core MVC provides a flexible framework for building web applications, and iTextSharp complements it perfectly by enabling us to generate high-quality PDF documents with ease. By exporting views to PDF, we can effortlessly create printable reports, invoices, or any other document that requires a standardized format.
Throughout this tutorial, we'll walk through the process step by step, ensuring that even beginners can follow along. We'll start by introducing the iTextSharp library and explaining its advantages. Then, we'll dive into the implementation details, demonstrating how to install the library and set up the necessary configurations.
By the end of this tutorial, you'll have a solid understanding of how to export views to PDF in your ASP.NET Core MVC application. You'll also have a handy reference point to revisit whenever you need to implement PDF export functionality in your future projects.
So, let's get started and empower our applications with the ability to generate PDFs effortlessly!
ITextSharp
ITextSharp is a widely used library for pdf export in asp.net core. This library is free and provides you various features while exporting pdf. You can add custom css, custom fonts and images in the pdf export and also include html. We will see how to do that in this article.
Add New View
So first of all what you have to do is , you have to add new partial view in your Asp.Net Core application , We will add this view in shared folder , you can copy sample view from below and give the name _pdfDemo.cshtml. We will use this name later while exporting.
@model Employee <!DOCTYPE html> <html> <head><meta http-equiv="X-UA-Compatible" content="IE=Edge" /> </head> <body> <table> <tr> <th>Name</th> <th>@Model.Name</th> </tr> <tr> <td>Alfreds Futterkiste</td> <td>Maria Anders</td> </tr> <tr> <td>Centro comercial Moctezuma</td> <td>Francisco Chang</td> </tr> </table> </body> </html>
Because we may need to pass data from model from controller so we have already added Employee model in partial view, so you can implement and pass different model data while exporting. So you can copy the model class from below
public class Employee { public string Name { get; set; } }
This is just a sample class to explain how it can be done , you can change it according to your requirements. After we have done adding model and partial view we have to install some iTextsharp packages, Please install
ITextSharp v5.5.13.3
itextsharp.xmlworker v5.5.13.3
You can see the packages and versions in below image
After, adding the packages now we have to add a new interface class name IViewRenderService and add this
using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; namespace ViewPdfExport.Models { public interface IViewRenderService { Task<string> RenderToStringAsync(string viewName, object model); } }
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.ViewEngines; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Routing; using System; using System.IO; using System.Linq; using System.Threading.Tasks; using ViewPdfExport.Models; namespace ViewPdfExport.Models { public class ViewRenderService : IViewRenderService { private readonly IRazorViewEngine _razorViewEngine; private readonly ITempDataProvider _tempDataProvider; private readonly IServiceProvider _serviceProvider; public ViewRenderService(IRazorViewEngine razorViewEngine, ITempDataProvider tempDataProvider, IServiceProvider serviceProvider) { _razorViewEngine = razorViewEngine; _tempDataProvider = tempDataProvider; _serviceProvider = serviceProvider; } private IView FindView(ActionContext actionContext, string partialName) { var getPartialResult = _razorViewEngine.GetView(null, partialName, false); if (getPartialResult.Success) { return getPartialResult.View; } var findPartialResult = _razorViewEngine.FindView(actionContext, partialName, false); if (findPartialResult.Success) { return findPartialResult.View; } var searchedLocations = getPartialResult.SearchedLocations.Concat(findPartialResult.SearchedLocations); var errorMessage = string.Join( Environment.NewLine, new[] { $"Unable to find partial '{partialName}'. The following locations were searched:" }.Concat(searchedLocations)); ; throw new InvalidOperationException(errorMessage); } private ActionContext GetActionContext() { var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider }; return new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); } public async Task<string> RenderToStringAsync(string viewName, object model) { var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider }; var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); using (var sw = new StringWriter()) { var viewResult = _razorViewEngine.FindView(actionContext, viewName, false); if (viewResult.View == null) { throw new ArgumentNullException($"{viewName} does not match any available view"); } var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { Model = model }; var viewContext = new ViewContext( actionContext, viewResult.View, viewDictionary, new TempDataDictionary(actionContext.HttpContext, _tempDataProvider), sw, new HtmlHelperOptions() ); await viewResult.View.RenderAsync(viewContext); return sw.ToString(); } } } }
using Microsoft.AspNetCore.Mvc; using System.Diagnostics; using ViewPdfExport.Models; using iTextSharp.tool.xml.pipeline.html; using iTextSharp.tool.xml.pipeline.css; using iTextSharp.tool.xml; using iTextSharp.tool.xml.parser; using iTextSharp.tool.xml.html; using iTextSharp.tool.xml.pipeline.end; using iTextSharp.text.pdf; using iTextSharp.text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using System.IO; using System; using ViewToPdfExport.Models; namespace ViewPdfExport.Controllers { public class HomeController : Controller { private readonly ILogger<HomeController> _logger; private IViewRenderService _viewRender; public HomeController(ILogger<HomeController> logger, IViewRenderService viewRender) { _logger = logger; _viewRender = viewRender; } public async Task<IActionResult> Index() { await Export(); return View(); } private async Task<string> Export() { System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); var model = new Employee { Name = "Test" }; var filename = "PdfExport" + DateTime.Now.ToString("ddMMyyyyhhmmss"); string html = await _viewRender.RenderToStringAsync("_pdfDemo", model); Document document = new Document(); XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS); var path = Directory.GetCurrentDirectory() + "/wwwroot/" + filename + ".pdf"; PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(path, FileMode.Create)); foreach (var file in Directory.GetFiles(Directory.GetCurrentDirectory() + "/" + "wwwroot/fonts")) { FontFactory.FontImp.Register(file); } document.Open(); using (var strReader = new StringReader(html)) { //Set factories HtmlPipelineContext htmlContext = new HtmlPipelineContext(null); htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory()); //Set css ICSSResolver cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false); cssResolver.AddCssFile(Directory.GetCurrentDirectory() + "/wwwroot/css/site.css", true); //Export IPipeline pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, writer))); var worker = new XMLWorker(pipeline, true); var xmlParse = new XMLParser(true, worker); xmlParse.Parse(strReader); xmlParse.Flush(); } document.Close(); return path; } } }So, here Export method is the one we have for exporting the view to pdf, in that you can see view name passed which you want to export
private async Task<string> Export() { System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); var model = new Employee { Name = "Test" }; var filename = "PdfExport" + DateTime.Now.ToString("ddMMyyyyhhmmss"); string html = await _viewRender.RenderToStringAsync("_pdfDemo", model); //Change the view name and model from here Document document = new Document(); XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS); var path = Directory.GetCurrentDirectory() + "/wwwroot/" + filename + ".pdf"; //This is the exported file anme PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(path, FileMode.Create)); foreach (var file in Directory.GetFiles(Directory.GetCurrentDirectory() + "/" + "wwwroot/fonts")) //This is for custom fonts if you have any { FontFactory.FontImp.Register(file); } document.Open(); using (var strReader = new StringReader(html)) { //Set factories HtmlPipelineContext htmlContext = new HtmlPipelineContext(null); htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory()); //Set css ICSSResolver cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false); cssResolver.AddCssFile(Directory.GetCurrentDirectory() + "/wwwroot/css/site.css", true); //For adding custom css //Export IPipeline pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, writer))); var worker = new XMLWorker(pipeline, true); var xmlParse = new XMLParser(true, worker); xmlParse.Parse(strReader); xmlParse.Flush(); } document.Close(); return path; }
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddScoped<IViewRenderService, ViewRenderService>(); /*Add This ViewRenderService*/ }
Now, we are ready to run the application. Run your application and check the exported pdf file, like we have in the image
This is the pdf file which is generated inside wwwroot in you project, open the file
So, this is how to export view as pdf in Asp.Net Core using ITextSharp. You can also download the attached source code and let us know if you face any issue.