Thursday, January 29, 2015

Export System.Data.DataTable to PDF using AT.PDFReportCreator

I was engaged in a big web-application which has lots of inquiry pages. As we all know, each inquiry page has filtering options and a grid which displays the data. With each inquiry page we need to show export buttons, in PDF and Excel. Exporting data in excel was simple, we just need to create a sheet and put all the data in there. But export of PDF was difficult, client was asking to have a good formatted PDF file, with company logo, total number of pages, heading and with inquiry parameters.

Features:

  • Provide your own Logo and Watermark files, yes AT logo and watermark is NOT hard-coded you can change it :-)
  • Page X of Y in the footer
  • Date and Time of printing in the footer
  • Custome Report Heading
  • Provide Page Layout, for example custom page width, height, margins and orientation
  • Define which columns should be included in PDF from DataTable, in-case if you don't want all columns to be printed
  • Define widths for each column
  • Provide Parameters which will be displayed in the report header

iTextSharp is a very powerful library for creating PDF files in .net Applications. So I decided to create a generic API using iTextSharp library, which can be used to create PDF for every inquiry screen. We just need to pass the Data to the utility and it will create the PDF File. Usually I don't have time, so I did a quick work and created a DLL, which can be used with .net Applications, like ASP.net or Desktop. Also I tried my best to keep the usage as simple as possible.

Below is the Export PDF code written for a ASP.net Web Application using my wrapper library around iTextSharp.

protected void btnCreatePDF_Click(object sender, EventArgs e)
{
    try
    {
        using (System.Data.DataTable dt = this.GetData())
        {
            var reportParam = new AT.PDFReportCreator.PDFReportParam()
            {
                ReportData = dt
            };

            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.Buffer = true;
            HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=Customers.pdf");
            HttpContext.Current.Response.Charset = "";
            HttpContext.Current.Response.ContentType = "application/pdf";

            AT.PDFReportCreator.PDFReportCreator.CreatePDF(HttpContext.Current.Response.OutputStream, reportParam);

            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();
        }
    }
    catch (Exception ex)
    {
        Trace.Write("Export PDF", ex.Message, ex);
    }
}

Due to time limit, I only came up with DataTable export, while we have other possibilities as well, such as,

  • Export ASP.net GridView Control to PDF
  • Export Entity Framework's List of Entity to PDF
  • Export Desktop Application's DataGridView Control to PDF
For above scenarios we can convert them into DataTable, for example iterate each GridView control row and add the content in DataTable and then pass that DataTable to Export utility.

Downloads:
PDFExportTest.zip Download this file, it contains a Web Application project which shows the export option. Also contains the AT.PDFReportCreator.dll and iTextSharp.dll files. If you want to quickly start testing and don't want to go in complex details, then just download this zip file, extract the DLLs and use in your project.
AT.PDFReportCreator.zip Source code of export API, which is actually a wrapper around iTextSharp

Sunday, July 6, 2014

ASP.net ReadOnly TextBox get value on PostBack

Level: Intermediate

Knowledge Required:
  • ASP.net
  • Custom Controls

In ASP.net we have a problem, that if we set a TextBox control ReadOnly, then the value changed through JavaScript cannot be received back to Server on PostBack.

If we search on Google, we will find that a good solutions is to add readonly attribute on the Page_Load. For example,

protected void Page_Load(object sender, EventArgs e)
{
     TextBox1.Attributes.Add("readonly", "readonly");
}

So putting this code for every control and on every page is obviously a bit annoying. So a better way is to create your own TextBox control which implements this behaviour. But since we already have a good TextBox control available so we can just extend it

    public class ExtendedTextBox : System.Web.UI.WebControls.TextBox
    {
        public override bool ReadOnly
        {
            get
            {
                // We will always return ReadOnly false because internally control
                // is checking this property and it will start the same behaviour
                // if we return true, i.e. value will NOT be received on PostBack 
                return false;
            }
            set
            {
                // Here I have implemented a logic, if we you mark the control as
                // readonly then we will render it as background-color = light gray
                if (value)
                {
                    this.Attributes.Add("readonly", "readonly");
                    this.BackColor = System.Drawing.Color.WhiteSmoke;
                }
                else
                {
                    this.Attributes.Remove("readonly");
                    this.BackColor = System.Drawing.Color.White;
                }
            }
        }
    }

The point is, actually we do NOT set the ReadOnly property of control to true, just add the readonly attribute, so that ASP.net control will consider itself as normally rendered control, and will return the value correctly.

After this we can easily use this control on any web page, but before this we have to add the control reference in our web.config file as,

  <system.web>
    <pages>
      <controls>
        <add assembly="YourWebApplicationAssemblyName" namespace="NameSpaceWhereYouHaveThisExtendedClass" tagPrefix="asp"/>
      </controls>
    </pages>
  </system.web>

Monday, February 10, 2014

Changing SQL Server New Stored Procedure Template

You can change the default SQL Server's Stored Procedure Template by editing the following files. This will change the template which appears when you right click on Store Procedure folder (in object explorer) and select "New Stored Procedure..." Command

SQL Server 2008 R2
C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\SqlWorkbenchProjectItems\Sql\Stored Procedure\Create Stored Procedure (New Menu).sql

SQL Server 2012
C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\SqlWorkbenchProjectItems\Sql\Stored Procedure\Create Stored Procedure (New Menu).sql

Note that these files may only be editable by Administrators only, so you may need to open your editor in Administrator mode.

Monday, July 16, 2012

LightSwitch: How to get Total Number of Records in all pages in a Multi-Page DataGrid

Level: Intermediate

Knowledge Required:
  • LightSwitch
  • Search Screen
  • DataGrid
  • Creating a new property and placing it on Screen

This post explains how to get the total number of records in all the pages of Multi-Page DataGrid.