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:
$.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.
[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.
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.