I would like to call an action on a controller. Have the controller get the data from the model. The view then runs and generates a PDF. The only example I have found is in an article by Lou http://whereslou.com/2009/04/12/returning-pdfs-from-an-aspnet-mvc-action. His code is very elegant. The view is using ITextSharp to generate the PDF. The only downside is his example uses the Spark View Engine. Is there a way to do a similar thing with the standard Microsoft view engine?
-
8Using the Spark view engine is a downside? I'm wounded. :) – loudej May 28 '09 at 18:03
-
Check this out, RazorPDF: http://www.nyveldt.com/blog/post/Introducing-RazorPDF – Rosdi Kasim May 20 '13 at 09:10
-
I have struggled with this. Spark with iText was easy to use, but the PDF formatting was limited. I would love to see your sample where you are using a template PDF file, changing content and then writing to a stream. – user275308 Feb 17 '10 at 14:28
-
For posterity's sake we are now using Rotativa now, which wraps wkhtmltopdf – Eric Brown - Cal Jul 29 '15 at 16:54
8 Answers
I use iTextSharp to generate dynamic PDF's in MVC. All you need to do is put your PDF into a Stream object and then your ActionResult return a FileStreamResult. I also set the content-disposition so the user can download it.
public FileStreamResult PDFGenerator() { Stream fileStream = GeneratePDF(); HttpContext.Response.AddHeader("content-disposition", "attachment; filename=form.pdf"); return new FileStreamResult(fileStream, "application/pdf"); }
I also have code that enables me to take a template PDF, write text and images to it etc (if you wanted to do that).
- Note: you must set the Stream position to 0.
private Stream GeneratePDF() { //create your pdf and put it into the stream... pdf variable below //comes from a class I use to write content to PDF files MemoryStream ms = new MemoryStream(); byte[] byteInfo = pdf.Output(); ms.Write(byteInfo, 0, byteInfo.Length); ms.Position = 0; return ms; }

- 15,150
- 15
- 61
- 83
-
5I would love to see example of what that "pdf class" in the example looks like or get some hints on how to implement it? – jesperlind Aug 06 '09 at 23:37
-
1The only thing I would add to this is that this Action cannot be called from a partial postback (ajax) but rather use a Html.ActionLink or the like. – zonkflut Feb 24 '10 at 04:27
-
2Code Project article with sample code: http://www.codeproject.com/Articles/66948/Rendering-PDF-views-in-ASP-MVC-using-iTextSharp.aspx – Jakub Konecki Jun 18 '11 at 11:46
-
3Adding Content-Disposition header does not work in FireFox due to this [issue with duplicate Content-Disposition](https://bugzilla.mozilla.org/show_bug.cgi?id=681140). The right solution is to set FileDownloadName property of FireStreamResult object. – alpav Nov 25 '11 at 20:29
-
@David , in my project i have roles based authorization to actions, but when i use pdf it's only print the login screen – SAR Dec 12 '16 at 11:44
our final answer to this problem was to use Rotativa.
It wraps up the WKhtmltopdf.exe like some of the other solutions, but it's by far the easiest to use that I have found
I went and up voted all the other answers that also solve the problem well, but this is what we used to solve the problem posed in the question above. It is different from the other answers.
Here is a Rotativa Tutorial.
after you install it, this is all your need
public ActionResult PrintInvoice(int invoiceId)
{
return new ActionAsPdf(
"Invoice",
new { invoiceId= invoiceId })
{ FileName = "Invoice.pdf" };
}
Very Very simple.

- 6,011
- 8
- 50
- 76

- 14,135
- 12
- 58
- 97
-
3Why the downvote, I am confused. This is how we solve the problem now, so I updated the question to keep it current. I don't understand. How can I do better if I don't understand why I got the down vote? – Eric Brown - Cal Nov 05 '14 at 22:18
-
3Again a down vote without a comment... this is the answer we used to solve the issue. I made extra effort to come back and update the question with the more current answer. I'm confused how that rates a down vote, unless you just don't like rotativa. – Eric Brown - Cal Nov 18 '14 at 17:55
-
Brown Beautiful answer with absolutely no code, that's what we need in 21st century. +1 for both comments and answer..thanks heaps – Learner Jan 20 '16 at 06:02
-
It simply doesn't work. When I use ViewAsPdf it gives me an error: "The directory name is invalid" – Robert Benyi May 31 '16 at 08:05
-
Ask yourself a question, in that block of code, what has a directory name in it implicitly? The file name... So make sure you are pathing to where the .pdf is correctly. – Eric Brown - Cal Jun 22 '16 at 16:02
-
@EricBrown-Cal Here i found one problem, there is user roles which,action is belong to, now when i use to click the actionPDF which should print pdf it's printing login screen, if i set to Allow Anonymous the authoriz it will print actual data but i dont want it, is it possible to print with permissions, thank you – SAR Dec 12 '16 at 06:29
-
Yes, you need to correctly set up your roles access for your controller.. http://stackoverflow.com/questions/9601420/asp-net-mvc-role-based-access-to-controller – Eric Brown - Cal Jan 03 '17 at 17:44
-
I use rotativa, but I want to display another language not to display English, so how can we add another language. When I add the Gujarati language into PDF then it shows in a black box. How can i solve it? thanks in advance. – Brijesh Mavani Jan 16 '19 at 07:37
Creating layout in html and printing afterwards into pdf is the fastest way.
Html into pdf conversion is provided by phantomjs, wkhtmltopdf or jsreport
jsreport provides direct integration with asp.net mvc views, where you can just mark controller action with attribute and it will print pdf instead of html for you.
More on this blog post
Disclaimer: I am the author of jsreport

- 3,069
- 1
- 22
- 35
-
1If you are using MVC, Rotativa is a really nice wrapper for wkhtmltopdf... super easy to use, we've converted to it to solve this problem now... There was an issue with images, but there is a workaround on SO – Eric Brown - Cal Apr 16 '14 at 16:21
-
Yes, Rorativa is a nice wrapper. jsreport is rather a reporting server that handles images or keeps reports history for you. – Jan Blaha Apr 20 '14 at 19:49
This is an old question but one that's still relevant and I thought I'd just share what I've implemented which works well.
Install NuGet package TuesPechkin - a fork in the Pechkin library based on WkHtmlToPdf that uses a Webkit engine to convert HTML pages to PDF.
Write a little helper to read a view and convert it to an HTML string (mvcContext is this.HttpContext). The replace is optional of course!:
public static string RenderViewToString(HttpContextBase mvcContext, string area, string controllerName, string viewName, object model) { var context = System.Web.HttpContext.Current; var contextBase = mvcContext; var routeData = new RouteData(); if (area == null) area = ""; routeData.DataTokens.Add("area", area); routeData.Values.Add("controller", controllerName); var controllerContext = new ControllerContext(contextBase, routeData, new EmptyController()); var razorViewEngine = new RazorViewEngine(); var razorViewResult = razorViewEngine.FindView(controllerContext, viewName, "", false); var writer = new StringWriter(); var viewContext = new ViewContext(controllerContext, razorViewResult.View, new ViewDataDictionary(model), new TempDataDictionary(), writer); razorViewResult.View.Render(viewContext, writer); string hostAddress = context.Request.Url.Scheme + "://" + context.Request.Url.Authority; return writer.ToString() .Replace("src=\"/", "src=\"" + hostAddress + "/") .Replace("<link href=\"/", "<link href=\"" + hostAddress + "/"); } class EmptyController : ControllerBase { protected override void ExecuteCore() { } }
The hard work of the above were from here: http://wouterdekort.blogspot.co.uk/2012/10/rendering-aspnet-mvc-view-to-string-in.html?showComment=1414603363455#c7863520150405064571
Create an MVC Action to generate the document
public ActionResult DownloadPDF(long CentreID) { var model = GetModel() IPechkin converter = Factory.Create(); byte[] result = converter.Convert(Helpers.PDF.RenderViewToString(this.HttpContext, "area", "controller", "action", model); MemoryStream outputStream = new MemoryStream(); outputStream.Write(result, 0, result.Length); outputStream.Position = 0; return File(outputStream, "application/pdf", "filename.pdf"); }

- 1,354
- 1
- 13
- 22
-
For those who follow this tutorial and has error on `IPechkin` and `Factory` things it is because it does deprecated already. Please read how to install and implement on the repo itself at https://github.com/tuespetre/TuesPechkin. – chaintng Aug 18 '15 at 04:59
-
And also, after you download `TuesPechkin` from nuget, don't forget to download `TuesPechkin.Wkhtmltox.Win32` or `TuesPechkin.Wkhtmltox.Win64` as it is not include when download. – chaintng Aug 18 '15 at 05:00
-
This should be one of the top answers. Was exactly what i was looking for and it is open source. – Alao Nov 11 '15 at 18:32
I also came across this http://www.codeproject.com/Articles/260470/PDF-reporting-using-ASP-NET-MVC3. It's easy and swift, and fits well with MVC.
However, the only downside so far is that it's not quite flexible you want to have a decent layout, for example, you don't have much control with table, and cell borders through html. It sort of supports force new page, but you will have to apply a patch to iTextsharp.

- 575
- 9
- 16
I just used wkhtmltopdf, to create the layout in html and afterwards, i convert it to pdf.
Easy, customizable, awesome as hell :)

- 3,435
- 4
- 40
- 66
Very Late Reply, but I found that the following URL helped me get my results quickly :
(Ensure that you reference to the iTextSharp DLL by making use of the Nuget Packages)
EDIT This is the code I used to make the table look a little different(This is landscape as well:
public string GetCssForPdf()
{
string css = "";
css = "th, td" +
"{" +
"font-family:Arial; font-size:10px" +
"}";
return css;
}
[HttpPost]
[ValidateInput(false)]
public FileResult Export(string GridHtml)
{
string webgridstyle = GetCssForPdf();
string exportData = String.Format("<html><body>{0}{1}</body></html>", "<style>" + webgridstyle + "</style>", GridHtml);
var bytes = System.Text.Encoding.UTF8.GetBytes(exportData);
using (var input = new MemoryStream(bytes))
{
var output = new MemoryStream();
var document = new iTextSharp.text.Document(PageSize.A4, 50, 50, 50, 50);
var writer = PdfWriter.GetInstance(document, output);
document.SetPageSize(iTextSharp.text.PageSize.A4.Rotate());
Font headerFont = FontFactory.GetFont("Verdana", 10);
Font rowfont = FontFactory.GetFont("Verdana", 10);
writer.CloseStream = false;
document.Open();
var xmlWorker = iTextSharp.tool.xml.XMLWorkerHelper.GetInstance();
xmlWorker.ParseXHtml(writer, document, input, System.Text.Encoding.UTF8);
document.Close();
output.Position = 0;
return File(output, "application/pdf", "Pipeline_Report.pdf");
//return new FileStreamResult(output, "application/pdf");
}
}
Hope this helps someone else as well.

- 1,801
- 1
- 19
- 51
A small example using rotativa package in asp.net mvc
We will create a function to populate the data. We will insert data for 7 days (Feb 1 2018 - Feb 7 2018) showing the first punch and the last punch for particular day with remarks.
public ReportViewModel PopulateData()
{
var attendances = new List<Attendance>
{
new Attendance{ClassName = "present",Day = new DateTime(2018, 02, 01).ToString("ddd"),Date = new DateTime(2018, 02, 01).ToString("d"),FirstPunch = "09:01:00",LastPunch = "06:00:01",Remarks = ""},
new Attendance{ClassName = "absent",Day = new DateTime(2018, 02, 02).ToString("ddd"),Date = new DateTime(2018, 02, 02).ToString("d"),FirstPunch = "",LastPunch = "",Remarks = "Absent"},
new Attendance{ClassName = "holiday",Day = new DateTime(2018, 02, 03).ToString("ddd"),Date = new DateTime(2018, 02, 03).ToString("d"),FirstPunch = "",LastPunch = "",Remarks = "Democracy Day"},
new Attendance{ClassName = "present",Day = new DateTime(2018, 02, 04).ToString("ddd"),Date = new DateTime(2018, 02, 04).ToString("d"),FirstPunch = "09:05:00",LastPunch = "06:30:01",Remarks = ""},
new Attendance{ClassName = "present",Day = new DateTime(2018, 02, 05).ToString("ddd"),Date = new DateTime(2018, 02, 05).ToString("d"),FirstPunch = "09:01:00",LastPunch = "06:00:01",Remarks = ""},
new Attendance{ClassName = "leave",Day = new DateTime(2018, 02, 06).ToString("ddd"),Date = new DateTime(2018, 02, 06).ToString("d"),FirstPunch = "",LastPunch = "",Remarks = "Sick Leave"},
new Attendance{ClassName = "present",Day = new DateTime(2018, 02, 07).ToString("ddd"),Date = new DateTime(2018, 02, 07).ToString("d"),FirstPunch = "08:35:00",LastPunch = "06:15:01",Remarks = ""}
};
return new ReportViewModel
{
UserInformation = new UserInformation
{
FullName = "Ritesh Man Chitrakar",
Department = "Information Science"
},
StartDate = new DateTime(2018, 02, 01),
EndDate = new DateTime(2018, 02, 07),
AttendanceData = attendances
};
}
We will then create a function to DownloadPdf. To download the pdf we will need to create 2 function. 1. to download pdf 2. to view pdf
public ActionResult DownloadPdf()
{
var filename = "attendance.pdf";
/*get the current login cookie*/
var cookies = Request.Cookies.AllKeys.ToDictionary(k => k, k => Request.Cookies[k]?.Value);
return new ActionAsPdf("PdfView", new
{
startDate = Convert.ToDateTime(Request["StartDate"]),
endDate = Convert.ToDateTime(Request["EndDate"])
})
{
FileName = filename,
/*pass the retrieved cookie inside the cookie option*/
RotativaOptions = {Cookies = cookies}
};
}
public ActionResult PdfView()
{
var reportAttendanceData = PopulateData();
return View(reportAttendanceData);
}
You can view the detail explanation on this link . Visit here .
Curtesoy : thelearninguy.com

- 207
- 2
- 5