What is iTextSharp ?
- iTextSharp is a free C# PDF library that is ported from the Java-PDF library iText
- iText was launched in 2000 and is a popular Open Source Java library
- iTextSharp has been under development since 2008
What does iTextSharp do ?
- Generate documents and Reports based on data from an XML file or a database
- Create maps and books, exploiting numerous interactive features available in PDF
- Add bookmarks, page numbers, watermarks, and other features to existing PDF documents
- Split or concatenate pages from existing PDF files
- Fill out interactive forms
- Serve dynamically generated or manipulated PDF documents to a web browser
How to Create a Report ?
Step 1 : Open Visual Studio 2010
Step 2 : File ==> New Project as MvcPDFReport
Step 3 : Select "Internet Application" Project Template
After above Steps :
Step 4 : After that File ==> Add ==> New Project
Step 5 : Visual C# ==> Class Library as iTextSharpReportGenerator
After All above Steps :
How to Create iTextSharp Report API ?
Step 1 : Download iTextSharp DLL
Step 2 : Extract above Zip File is as below
Below Steps for "iTextSharpReportGenerator" Class Library Project
Step 1 : Add References for the itextsharp.dll , System.Web and System.Web.Mvc
Step 2 : Add ==> New Class as PdfViewController
PdfViewController.cs
using System.Web.Mvc;
namespace iTextSharpReportGenerator
{
/// <summary>
/// Extends the controller with functionality for rendering
PDF views
/// </summary>
public class PdfViewController
: Controller
{
private
readonly HtmlViewRenderer
_htmlViewRenderer;
private
readonly StandardPdfRenderer
_standardPdfRenderer;
public
PdfViewController()
{
this._htmlViewRenderer
= new HtmlViewRenderer();
this._standardPdfRenderer
= new StandardPdfRenderer();
}
protected
ActionResult ViewPdf(string pageTitle,string viewName,object model)
{
// Render
the view html to a string
var
htmlText = this._htmlViewRenderer.RenderViewToString(this,viewName,model);
// Let
the html be rendered into a PDF document through iTextSharp
byte[]
buffer = _standardPdfRenderer.Render(htmlText, pageTitle);
// Return
the PDF as a binary stream to the client
return
new BinaryContentResult(buffer,
"application/pdf");
}
}
}
Step 3 : Add ==> New Class as BinaryContentResult
BinaryContentResult.cs
using System.IO;
using System.Web;
using System.Web.Mvc;
namespace iTextSharpReportGenerator
{
/// <summary>
/// An ActionResult used to send binary data to the browser
/// </summary>
public class BinaryContentResult
: ActionResult
{
private
readonly string
_contentType;
private
readonly byte[]
_contentBytes;
public
BinaryContentResult(byte[] contentBytes, string contentType)
{
this._contentBytes
= contentBytes;
this._contentType
= contentType;
}
public override void
ExecuteResult(ControllerContext context)
{
var
response = context.HttpContext.Response;
response.Clear();
response.Cache.SetCacheability(HttpCacheability.Public);
response.ContentType = this._contentType;
using
(var stream = new
MemoryStream(this._contentBytes))
{
stream.WriteTo(response.OutputStream);
stream.Flush();
}
}
}
}
using System.IO;
using iTextSharp.text;
using iTextSharp.text.html.simpleparser;
using iTextSharp.text.pdf;
namespace iTextSharpReportGenerator
{
/// <summary>
/// This class is responsible for rendering a html text string
to a PDF
/// document using the html renderer of iTextSharp
/// </summary>
public class StandardPdfRenderer
{
private
const int
HorizontalMargin = 40;
private
const int
VerticalMargin = 40;
public byte[] Render(string
htmlText, string pageTitle)
{
byte[]
renderedBuffer;
using
(var outputMemoryStream = new MemoryStream())
{
using
(var pdfDocument = new
Document(PageSize.A4,
HorizontalMargin, HorizontalMargin, VerticalMargin, VerticalMargin))
{
PdfWriter
pdfWriter = PdfWriter.GetInstance(pdfDocument,
outputMemoryStream);
pdfWriter.CloseStream = false;
pdfWriter.PageEvent = new PrintHeaderFooter
{ Title = pageTitle };
pdfDocument.Open();
using
(var htmlViewReader = new
StringReader(htmlText))
{
using (var htmlWorker = new HTMLWorker(pdfDocument))
{
htmlWorker.Parse(htmlViewReader);
}
}
}
renderedBuffer = new byte[outputMemoryStream.Position];
outputMemoryStream.Position =
0;
outputMemoryStream.Read(renderedBuffer, 0, renderedBuffer.Length);
}
return
renderedBuffer;
}
}
}
using System;
using System.IO;
using System.Web.Mvc;
namespace iTextSharpReportGenerator
{
/// <summary>
/// Defines the FakeView type
/// </summary>
public class FakeView : IView
{
public void Render(ViewContext
viewContext, TextWriter writer)
{
throw
new NotImplementedException();
}
}
}
Step 6 : Add ==> New Class as PrintHeaderFooter
PrintHeaderFooter.cs
Step 7 : Add ==> New Class as HtmlViewRenderer
PrintHeaderFooter.cs
using System;
using System.Globalization;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace iTextSharpReportGenerator
{
/// <summary>
/// This class represents the standard header and footer for a
PDF print
/// application by Extending the PdfPageEventHelper (iTextSharp Class)
/// </summary>
public class PrintHeaderFooter
: PdfPageEventHelper
{
private
PdfContentByte _pdfContent;
private
PdfTemplate _pageNumberTemplate;
private
BaseFont _baseFont;
private
DateTime _printTime;
public string Title { get; set; }
public override void
OnOpenDocument(PdfWriter writer, Document document)
{
_printTime = DateTime.Now;
_baseFont = BaseFont.CreateFont(BaseFont.HELVETICA,
BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
_pdfContent = writer.DirectContent;
_pageNumberTemplate =
_pdfContent.CreateTemplate(50, 50);
}
public override void
OnStartPage(PdfWriter writer, Document document)
{
base.OnStartPage(writer,
document);
Rectangle
pageSize = document.PageSize;
if
(Title != string.Empty)
{
_pdfContent.BeginText();
_pdfContent.SetFontAndSize(_baseFont, 11);
_pdfContent.SetRGBColorFill(0,
0, 0);
_pdfContent.SetTextMatrix(pageSize.GetLeft(40),
pageSize.GetTop(40));
_pdfContent.ShowText(Title);
_pdfContent.EndText();
}
}
public override void
OnEndPage(PdfWriter writer, Document document)
{
base.OnEndPage(writer,
document);
int
pageN = writer.PageNumber;
string
text = pageN + " - ";
float
len = _baseFont.GetWidthPoint(text, 8);
Rectangle
pageSize = document.PageSize;
_pdfContent = writer.DirectContent;
_pdfContent.SetRGBColorFill(100,
100, 100);
_pdfContent.BeginText();
_pdfContent.SetFontAndSize(_baseFont, 8);
_pdfContent.SetTextMatrix(pageSize.Width / 2, pageSize.GetBottom(30));
_pdfContent.ShowText(text);
_pdfContent.EndText();
_pdfContent.AddTemplate(_pageNumberTemplate, (pageSize.Width / 2) + len,
pageSize.GetBottom(30));
_pdfContent.BeginText();
_pdfContent.SetFontAndSize(_baseFont,
8);
_pdfContent.ShowTextAligned(PdfContentByte.ALIGN_RIGHT, _printTime.ToString(CultureInfo.InvariantCulture),
pageSize.GetRight(40), pageSize.GetBottom(30), 0);
_pdfContent.EndText();
}
public override void OnCloseDocument(PdfWriter
writer, Document document)
{
base.OnCloseDocument(writer,
document);
_pageNumberTemplate.BeginText();
_pageNumberTemplate.SetFontAndSize(_baseFont, 8);
_pageNumberTemplate.SetTextMatrix(0, 0);
_pageNumberTemplate.ShowText(string.Empty + (writer.PageNumber - 1));
_pageNumberTemplate.EndText();
}
}
}
Step 7 : Add ==> New Class as HtmlViewRenderer
HtmlViewRenderer.cs
using System.IO;
using System.Text;
using System.Web;
using System.Web.Mvc.Html;
namespace iTextSharpReportGenerator
{
/// <summary>
/// This class is responsible for rendering a HTML view into a
string
/// </summary>
public class HtmlViewRenderer
{
public string RenderViewToString(Controller
controller, string viewName, object viewData)
{
var
renderedView = new StringBuilder();
using
(var responseWriter = new
StringWriter(renderedView))
{
var
fakeResponse = new HttpResponse(responseWriter);
var
fakeContext = new HttpContext(HttpContext.Current.Request, fakeResponse);
var
fakeControllerContext = new ControllerContext(new
HttpContextWrapper(fakeContext),
controller.ControllerContext.RouteData,
controller.ControllerContext.Controller);
var
oldContext = HttpContext.Current;
HttpContext.Current
= fakeContext;
using
(var viewPage = new
ViewPage())
{
var
html = new HtmlHelper(CreateViewContext(responseWriter,
fakeControllerContext), viewPage);
html.RenderPartial(viewName, viewData);
HttpContext.Current
= oldContext;
}
}
return
renderedView.ToString();
}
private
static ViewContext
CreateViewContext(TextWriter responseWriter,
ControllerContext fakeControllerContext)
{
return
new ViewContext(fakeControllerContext,
new FakeView(),
new ViewDataDictionary(),
new TempDataDictionary(),
responseWriter);
}
}
}
After above Steps Class Library Project is as below
Class Diagram for above Report API
How to use Above Report API in MVC 3 Project (i.e. MvcPDFReport)?
Step 1 : Add ==> New Class as Provider inside the Model Folder
Provider.cs
namespace MvcPDFReport.Models
{
/// <summary>
/// Provider model
/// </summary>
public class Provider
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get;
set; }
public string Place { get; set; }
}
}
Step 2 : Add ==> New Class as ProviderList inside the Model Folder
ProviderList.cs
using System.Collections.Generic;
namespace MvcPDFReport.Models
{
/// <summary>
/// ProviderList model which extends Provider collection
/// </summary>
public class ProviderList
: List<Provider>
{
public string ImageUrl { get;
set; }
}
}
HomeController.cs
using System.Web.Mvc;
using MvcPDFReport.Models;
using iTextSharpReportGenerator;
namespace MvcPDFReport.Controllers
{
/// <summary>
/// Extends the PdfViewController with functionality for
rendering PDF views
/// </summary>
public class HomeController
: PdfViewController
{
public ActionResult PrintProviders()
{
var
providerList = CreateCustomerList();
FillImageUrl(providerList, "iTextSharp.png");
return
this.ViewPdf("Software
Providers Report", "PdfReport",
providerList);
}
#region Private
Methods
private
void FillImageUrl(ProviderList
providerList, string imageName)
{
if
(Request.Url == null) return;
var
url = string.Format("{0}://{1}{2}",
Request.Url.Scheme, Request.Url.Authority, Url.Content("~"));
providerList.ImageUrl = url + "Content/" + imageName;
}
private
ProviderList CreateCustomerList()
{
return
new ProviderList()
{
new
Provider {Id=1,Name="Inexis Consulting",Address="Colombo 4",Place="Sri Lanka"},
new
Provider {Id=2,Name="Microsoft",Address ="Washington",Place="USA"},
new
Provider {Id=3,Name="IBM",Address="Armonk, New York",Place="USA"
},
new
Provider {Id=4,Name="HP",Address="California",Place="USA"},
new
Provider {Id=5,Name="Novell",Address="Provo,Utah",Place="USA"},
new
Provider {Id=6,Name="Google",Address="California",Place="USA"},
new
Provider {Id=7,Name="Oracle",Address="Redwood City",Place="USA"},
new
Provider {Id=8,Name="Apple",Address="California",Place="USA"},
new
Provider {Id=9,Name="SAP",Address="Walldorf",Place="Germany"},
};
}
#endregion
}
}
@using
MvcPDFReport.Models
@model ProviderList
<br />
<img src="@Model.ImageUrl" width="64" height="64" />
<br />
<table cellpadding="3" cellspacing="3">
<tr border="1" bgcolor="#777777" color="#ffffff">
<td width="20%" align="center">
Provider Name
</td>
<td width="50%" align="center">
Provider Address
</td>
<td width="30%" align="center">
Provider Place
</td>
</tr>
@{
var
oddColor = "#FACC6D";
var
evenColor = "#99CC33";
var odd
= oddColor;
}
@foreach (var p in Model)
{
<tr border="1" bgcolor="@odd">
<td>@p.Name
</td>
<td>@p.Address
</td>
<td>@p.Place
</td>
</tr>
odd = odd == oddColor ? evenColor :
oddColor;
}
</table>
Step 5 : Add Hyper Link for the Index View
Index.cshtml
@{
ViewBag.Title = "Home
Page";
}
<h2>Press the link to print a
Software Provider List to PDF</h2>
@Html.ActionLink("Print Software Providers", "PrintProviders", null, new { target = "_blank" })
Screen 1 :
Screen 2 :
On Firefox - Top of the Report
Do You Need a Book ?
Do You Need to Download this Sample Project ?
Conclusion
- You can see that it's very easy to create MVC Reports by using iTextSharp
- It's having lot of inbuilt features to make your job very easy
- Such as iTextsharp supports colors out of the box as you can see on above report
- It is possible to add images to the report by using an <img src="" /> tag
I hope this helps to You.Comments and feedback greatly appreciated.
If you feel it was a good article,Give me a +1.Thank You.
Happy Coding.
You Might Also Like
How to Improve ASP.Net MVC 3 View Performance ?
Well explained...
ReplyDeleteGood article to work with PDF
DeleteHi Priyanka,Anjan,
DeleteGlad to hear that it helped!
Keep in Touch.
@Sampath : Its really very nice......
ReplyDeleteThanx keep it up
Hi Jogendra,
DeleteThanks, I’m glad you enjoyed it!
Keep in Touch.
Thanks sampath for sharing it with me, Nice explanation, From my side i don't think any improvements needed. well done. I personally use iText Sharp for grid reporting.
ReplyDeleteThanks again and please keep sharing nice articles like this.
-Razin Memon-
Hi Razin,
DeleteYou're warmly welcome.
Keep in Touch.
Thanks for sharing, this seems to be very interesting...
ReplyDelete-Safeer Hussain-
Hi Safeer,
DeleteThanks,I’m glad you found it useful!
Keep in Touch.
Geat article!
ReplyDeleteHi Zhao,
DeleteYou're warmly welcome.
Keep in Touch.
great descriptive article.. keep it up ...
ReplyDeleteHi Shalin,
DeleteThanks, I’m glad you enjoyed it!
Keep in Touch.
Well done!
ReplyDeleteThe only comment: use NuGet for installing the library. Launch Package Management Console in Visual Studio and type command: PM>Install-Package iTextSharp
This command will install the library and all dependencies.
-Gediminas Bukauskas-
Hi Gediminas,
DeleteThanks for your feedback and additional information.
But the only problem NuGet having is it's having older version than current.As a example Nuget is having iTextSharp V 5.3.3 But the latest from sourcefrog is 5.4.1.As such.
Hi Sampath,
ReplyDeleteGreat Article...
Can we create complex reports like bar charts,line charts etc.
Hi Theja,
DeleteThanks for your feedback.
About Your Question:
Yes.You can.
On my future blog post I will explain how to do that.Just for the time being you can check below mentioned link for more details(this is a java post.But easily you can convert it to C#) .
http://jtoee.blogspot.com/2008/04/writing-pdf-charts-with-itext-in-less.html
Great work as usual man :) keep it up
ReplyDeleteHi Dinindu,
DeleteYou're warmly welcome.
Keep in Touch.
Sorry but i got trouble with the Picture ( dont know what to put it at the beginning).
ReplyDeleteand second, if i display a List province by Entity framework, so how can i deal with the class ProvinceList
it mean where is the 1st place to but the Image in, it keep alert that cant not find picture.
Deleteand about entity framwork, it mean such at ( db is variable of entity)
db.Province.tolist()
so how can i change it to type ProvinceList.
thanks
Hi Nguyen,
DeleteFirst of all download the above source code and then play with that source code.I have mentioned the place where image should reside on above article. Plz check that the "After above Steps MVC project is as below" section's image for additional details.
With EF If you need to get the List of objects you have to use ToList(); method.So If you need more help plz let me know.
yo, thanks. i have successful in create pdf file.
DeleteBut one more trouble is the font in display pdf, u know anyway to inport font like Arial or timenew roman, something like that..
in the table, i mean, the page layout for pdf
DeleteHi Nguyen,
DeleteMy Pleasure :)
You can change the font details as you wish by using below code snippet that is on above article.
Check the Step 6 with below code snippet:
public override void OnOpenDocument(PdfWriter writer, Document document)
{
_baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
}
hi Sampath Lokuge
Deletei did as u told but it only change the title. The content in font
PdfReport.cshtml didnot work. i use font Arial @ standardpdf class cs to add new paragrap> > on pdf ok
but @ pdfreport.cshtml, it cant not display the right font. i dont know if i lack any library.
and 1 more thing, is it possible if i want to display a name of user who r loggin in? i try use viewbag at controller PrintPDF and a viewbag in html page but there is an error happen.
THank ^^
@Nguyen Duy.
DeleteI know how to display unicode in itextsharp but i can not change the font. Do u have any solution?
To display unicode, u can put following code into StandardPdfRenderer below htmlWorker.Parse(htmlViewReader);
var styleSheet = new iTextSharp.text.html.simpleparser.StyleSheet();
styleSheet.LoadTagStyle(HtmlTags.BODY, HtmlTags.FACE, "Arial Unicode MS");
styleSheet.LoadTagStyle(HtmlTags.BODY, HtmlTags.ENCODING, BaseFont.IDENTITY_H);
htmlWorker.SetStyleSheet(styleSheet);
I do like your tutorial. Everything is fine. But when i try to attach PDF file to email. I can't do it. Do you have any answer? Thanks!
ReplyDeleteHi Wai,
DeleteThanks for your feedback. :)
How did you try to add it ? Can I have more info about it ?
It's not free. Read the licensing if you create a commercial app.
ReplyDeleteHi,
DeleteIf you download it from the SourceForge (http://sourceforge.net/projects/itextsharp/) then it's free.It's having Affero GNU Public License (AGPL - http://www.gnu.org/licenses/agpl-3.0.html).I hope this will help to you. :)
i read this article , but my problem is still not resolve . my problem is how to use class in table rather incline class for getting attractive ui in pdf .
ReplyDelete