Render and Save PDF file from HTML in MVC 5 Application

In my application I had rendered JSON data with AngularJS and I had to send it to a controller in my MVC application to render PDF file and to allow a user to save it. So, the task was dynamically to submit the request, render a file and allow user to save it.
As soon as I generated the data to send in AngularJS, I wanted to use POST request. But in AngularJS I didn't find how to do it without Ajax, that's why I found a workaround. I don't even know, may be it's not a workaround but the solution. I still use it in my projects. I send Ajax POST request to a method which renders my content, and it returns me a JSON with my parameters.
For submitting data, add this code to JS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$.ajax({ type: 'POST', url: '/ImportExport/ExportPDF', data: { 'data': qsend }, success: function (res) { window.location = '/ImportExport/DownloadPDF?fileGuid=' + res.FileGuid + '&filename=' + res.FileName; $('.result').html(res); } , failure: function(errMsg) { alert(errMsg); } }); |
To render PDF files I prefer OpenHtmlToPdf package. You can add it to your project from Nuget, in Package Manager Console enter this command:
Install-Package OpenHtmlToPdf -Version 1.12.0
Add "using OpenHtmlToPdf;" to controller code.
In your controller you have to create two methods. One of the methods renders the file and saves it to a temporary data storage, the second one gets rendered data from temp storage and returns it in the appropriate MIME type or format.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[HttpGet] public virtual ActionResult DownloadPDF(string fileGuid, string fileName) { if (TempData[fileGuid] != null) { byte[] data = TempData[fileGuid] as byte[]; return File(data, "application/pdf", fileName); } else { // Problem - Log the error, generate a blank file, // redirect to another controller action - whatever fits with your application return new EmptyResult(); } } |
The second method in controller must render PDF file content and to store it in TempData.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public ActionResult ExportPDF(string data) { //This handle (guid) will be used to connect with the TempData[] string handle = Guid.NewGuid().ToString(); List<BossEmployee> be = JsonConvert.DeserializeObject<List<BossEmployee>>(data); string htmlText = String.Format(@" <h1>Export to pdf</h1><p>Here is the text to be exported to PDF</p>"); } string html = htmlText; using (MemoryStream memoryStream = new MemoryStream()) { var pdf = Pdf .From(html) .WithGlobalSetting("orientation", "Landscape") .WithObjectSetting("web.defaultEncoding", "utf-8") .Content(); TempData[handle] = pdf; } // Return both as a filename so and the handle return new JsonResult() { Data = new { FileGuid = handle, FileName = "TestReportOutput.pdf" } }; } |
If a user clicks on a button "Make PDF" or something like this, PDF file will be downloaded to his or her computer.