In this article I will explain with an example, how to export GridView with Images from SQL Server database to Word, Excel and PDF formats in ASP.Net using C# and VB.Net.
Exporting GridView to Word and Excel can be easily achieved using ASP.Net without any third party tools, but for exporting to PDF iTextSharp library will be used.
This article will illustrate how to export GridView with Images from SQL Server database to Word, Excel and PDF file along with formatting i.e. Styles and Colors in ASP.Net.
 
 
Download iTextSharp and XmlWorkerHelper Libraries
You can download the latest iTextSharp and XmlWorkerHelper libraries from the following links.
Note: You will need to add the reference of iTextSharp and XmlWorkerHelper libraries in your project.
 
 
Database
This article makes use of a table named tblFiles whose schema is defined as follows.
Export GridView with Images from database to Word Excel and PDF Formats
 
I have already inserted few records in the table.
Export GridView with Images from database to Word Excel and PDF Formats
 
Note: You can download the database table SQL by clicking the download link below.
          Download SQL file
 
 
HTML Markup
The following HTML Markup consists of:
GridView:–
Columns
GridView consists of a TemplateField column and a BoundField column.
TemplateField – The TemplateField column consist of an ItemTemplate with an Image control for displaying image files from the SQL Server database.
Properties
DataKeyNames – For storing the Unique key values such as Primary Key, ID fields, etc.
Note: For more details on DataKeys, please refer my article DataKeyNames in GridView example in ASP.Net.
 
Events
The GridView consists of the following event handlers i.e. OnRowDataBound.
Buttons – For performing different exporting operation.
The Buttons have been assigned with OnClick event handlers which will perform the operation for exporting GridView to Word, Excel and PDF files.
<asp:GridView runat="server" ID="gvFiles" AutoGenerateColumns="false" OnRowDataBound="OnRowDataBound" DataKeyNames="Id"
    HeaderStyle-BackColor="#3AC0F2" HeaderStyle-ForeColor="White" Font-Names="Arial" Font-Size="10"
    RowStyle-BackColor="#A1DCF2" AlternatingRowStyle-BackColor="White" AlternatingRowStyle-ForeColor="#000">
    <Columns>
        <asp:BoundField DataField="Name" HeaderText="File Name" />
        <asp:TemplateField ItemStyle-Height="150" ItemStyle-Width="100">
            <ItemTemplate>
                <asp:Image ID="Image1" runat="server" Height="100" Width="100" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>
<br />
<asp:Button ID="btnWord" runat="server" Text="Export To Word" OnClick="ExportToWord" Width="120" />
<asp:Button ID="btnExcel" runat="server" Text="Export To Excel" OnClick="ExportToExcel" Width="120" />
<br />
<br />
<asp:Button ID="btnPDF" runat="server" Text="Export To PDF" OnClick="ExportToPDF" Width="120" />
 
 
Namespaces
You will need to import the following namespaces.
C#
using System.IO;
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
using System.Drawing;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.tool.xml;
 
VB.Net
Imports System.IO
Imports System.Data
Imports System.Configuration
Imports System.Data.SqlClient
Imports System.Drawing
Imports iTextSharp.text
Imports iTextSharp.text.pdf
Imports iTextSharp.tool.xml
 
 
Binding the GridView
Inside the Page Load event handler, the records from the SQL Server database table are fetched and are used to populate the GridView.
C#
protected void Page_Load(object sender, EventArgs e)
{
    if (!this.IsPostBack)
    {
        this.BindGrid();
    }
}
 
private void BindGrid()
{
    string query = "SELECT * FROM tblFiles";
    string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    using (SqlConnection con = new SqlConnection(constr))
    {
        using (SqlDataAdapter sda = new SqlDataAdapter(query, con))
        {
            using (DataTable dt = new DataTable())
            {
                sda.Fill(dt);
                gvFiles.DataSource = dt;
                gvFiles.DataBind();
            }
        }
    }
}
 
VB.Net
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    If Not Me.IsPostBack Then
        Me.BindGrid()
    End If
End Sub
 
Private Sub BindGrid()
    Dim query As String = "SELECT * FROM tblFiles"
    Dim constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
    Using con As SqlConnection = New SqlConnection(constr)
        Using sda As SqlDataAdapter = New SqlDataAdapter(query, con)
            Dim dt As DataTable = New DataTable()
            sda.Fill(dt)
            gvFiles.DataSource = dt
            gvFiles.DataBind()
        End Using
    End Using
End Sub
 
 
OnRowDataBound event
Inside the OnRowDataBound event of the GridView, the Absolute URL to the application is built by concatenation of the URL segments.
Note: In order to export to Word, Excel or PDF, it is important to generate the complete URL of the handler like this http://localhost:25260/Handler.ashx?id=1.
           Such URLs are known as Absolute Path and Word, Excel and PDF files will use this path to download the Image files within the application.
 
Then, using the Row Index, the DataKeys array is accessed and the ID of the Image is fetched. This ID value will be passed to the Generic Handler, which in turn will return the Image from the SQL Server Database.
Note: For more details on DataKeys, please refer my article DataKeyNames in GridView example in ASP.Net.
 
Finally, the Absolute URL of the Generic Handler along with the ID of the Image is set in the Image control.
C#
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        //Fetch the Current URL.
        Uri uri = Request.Url;
 
        //Generate Absolute Path for the Images folder.
        string applicationUrl = string.Format("{0}://{1}{2}", uri.Scheme, uri.Authority, uri.AbsolutePath);
        applicationUrl = applicationUrl.Replace(Request.Url.Segments[Request.Url.Segments.Length - 1], "");
 
        //Fetch the Image ID from the DataKeyNames property.
        int id = Convert.ToInt32(gvFiles.DataKeys[e.Row.RowIndex].Values[0]);
 
        //Generate and set the Handler Absolute URL in the Image control.
        string imageUrl = string.Format("{0}Handler.ashx?id={1}", applicationUrl, id);
        (e.Row.FindControl("Image1") as System.Web.UI.WebControls.Image).ImageUrl = imageUrl;
    }
}
 
VB.Net
Protected Sub OnRowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
    If e.Row.RowType = DataControlRowType.DataRow Then
        'Fetch the Current URL.
        Dim uri As Uri = Request.Url
 
        'Generate Absolute Path for the Images folder.
        Dim applicationUrl As String = String.Format("{0}://{1}{2}", uri.Scheme, uri.Authority, uri.AbsolutePath)
        applicationUrl = applicationUrl.Replace(Request.Url.Segments(Request.Url.Segments.Length - 1), "")
 
        'Fetch the Image ID from the DataKeyNames property.
        Dim id As Integer = Convert.ToInt32(gvFiles.DataKeys(e.Row.RowIndex).Values(0))
 
        'Generate and set the Handler Absolute URL in the Image control.
        Dim imageUrl As String = String.Format("{0}Handler.ashx?id={1}", applicationUrl, id)
        TryCast(e.Row.FindControl("Image1"), System.Web.UI.WebControls.Image).ImageUrl = imageUrl
    End If
End Sub
 
 
The Generic Handler
The following Generic Handler accepts the ID of the Image file through the QueryString parameter and fetches the Binary Data of the Image file from the SQL Server database using its ID.
Finally, the Binary Data is converted into a Byte Array and returned through the response.
C#
<%@ WebHandler Language="C#" Class="Handler" %>
 
using System;
using System.Web;
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
 
public class Handler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        int id = 0;
        int.TryParse(context.Request.QueryString["id"], out id);
        if (id > 0)
        {
            string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
            using (SqlConnection con = new SqlConnection(constr))
            {
                string query = "SELECT Data, ContentType FROM tblFiles WHERE Id =" + id;
                using (SqlDataAdapter sda = new SqlDataAdapter(query, con))
                {
                    using (DataTable dt = new DataTable())
                    {
                        sda.Fill(dt);
                        byte[] bytes = (byte[])dt.Rows[0]["Data"];
                        context.Response.ContentType = dt.Rows[0]["ContentType"].ToString();
                        context.Response.BinaryWrite(bytes);
                        context.Response.End();
                    }
                }
            }
        }
    }
 
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}
 
VB.Net
<%@ WebHandler Language="VB" Class="Handler" %>
 
Imports System
Imports System.Web
Imports System.Data
Imports System.Configuration
Imports System.Data.SqlClient
 
Public Class Handler : Implements IHttpHandler
 
    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        Dim id As Integer = 0
        Integer.TryParse(context.Request.QueryString("id"), id)
        If id > 0 Then
            Dim constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
            Using con As SqlConnection = New SqlConnection(constr)
                Dim query As String = "SELECT Data, ContentType FROM tblFiles WHERE Id =" & id
                Using sda As SqlDataAdapter = New SqlDataAdapter(query, con)
                    Using dt As DataTable = New DataTable()
                        sda.Fill(dt)
                        Dim bytes As Byte() = CType(dt.Rows(0)("Data"), Byte())
                        context.Response.ContentType = dt.Rows(0)("ContentType").ToString()
                        context.Response.BinaryWrite(bytes)
                        context.Response.End()
                    End Using
                End Using
            End Using
        End If
    End Sub
 
    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property
End Class
 
 
Exporting GridView with Images to Word document with Formatting
When the Export Button is clicked,the Response class properties are set.
1. Content-Disposition – It is a response header indicating, the download file is an attachment and allows setting the file name.
Note: For more details on Content-Disposition header, please refer What is Content Disposition Header in ASP.Net.
 
2. ContentType – It informs the Browser about the file type. In this case it is Word.
 
Next, the StringWriter and HtmlTextWriter class objects are created and the Paging is disabled for the GridView by setting the AllowPaging property to false and the GridView is again populated with records i.e. Images fetched from the database by making call to the BindGrid method.
Then, a FOR EACH loop is executed over the GridView rows and the style and formatting are applied to the Header Row and Alternating Row of the GridView control.
 Finally, StringWriter object is written to the Response which initiates the File download operation.
C#
protected void ExportToWord(object sender, EventArgs e)
{
    Response.Clear();
    Response.Buffer = true;
    Response.AddHeader("content-disposition", "attachment;filename=GridViewExport.doc");
    Response.Charset = "";
    Response.ContentType = "application/vnd.ms-word";
    using (StringWriter sw = new StringWriter())
    {
        HtmlTextWriter hw = new HtmlTextWriter(sw);
 
        //To Export all pages.
        gvFiles.AllowPaging = false;
        this.BindGrid();
 
        gvFiles.HeaderRow.BackColor = Color.White;
        foreach (TableCell cell in gvFiles.HeaderRow.Cells)
        {
            cell.BackColor = gvFiles.HeaderStyle.BackColor;
        }
        foreach (GridViewRow row in gvFiles.Rows)
        {
            row.BackColor = Color.White;
            foreach (TableCell cell in row.Cells)
            {
                if (row.RowIndex % 2 == 0)
                {
                    cell.BackColor = gvFiles.AlternatingRowStyle.BackColor;
                }
                else
                {
                    cell.BackColor = gvFiles.RowStyle.BackColor;
                }
            }
        }
 
        gvFiles.RenderControl(hw);
 
        Response.Output.Write(sw.ToString());
        Response.Flush();
        Response.End();
    }
}
 
VB.Net
Protected Sub ExportToWord(ByVal sender As Object, ByVal e As EventArgs)
    Response.Clear()
    Response.Buffer = True
    Response.AddHeader("content-disposition", "attachment;filename=GridViewExport.doc")
    Response.Charset = ""
    Response.ContentType = "application/vnd.ms-word"
    Using sw As StringWriter = New StringWriter()
        Dim hw As HtmlTextWriter = New HtmlTextWriter(sw)
 
        'To Export all pages.
        gvFiles.AllowPaging = False
        Me.BindGrid()
 
        gvFiles.HeaderRow.BackColor = Color.White
        For Each cell As TableCell In gvFiles.HeaderRow.Cells
            cell.BackColor = gvFiles.HeaderStyle.BackColor
        Next
        For Each row As GridViewRowIn gvFiles.Rows
            row.BackColor = Color.White
            For Each cell As TableCell In row.Cells
                If row.RowIndex Mod 2 = 0 Then
                    cell.BackColor = gvFiles.AlternatingRowStyle.BackColor
                Else
                    cell.BackColor = gvFiles.RowStyle.BackColor
                End If
            Next
        Next
 
        gvFiles.RenderControl(hw)
 
        Response.Output.Write(sw.ToString())
        Response.Flush()
        Response.End()
    End Using
End Sub
 
 
Exporting GridView with Images to Excel with Formatting
When the Export Button is clicked,the Response class properties are set.
1. Content-Disposition – It is a response header indicating, the download file is an attachment and allows setting the file name.
Note: For more details on Content-Disposition header, please refer What is Content Disposition Header in ASP.Net.
 
2. ContentType – It informs the Browser about the file type. In this case it is Excel File.
 
Next, the StringWriter and HtmlTextWriter class objects are created and the Paging is disabled for the GridView by setting the AllowPaging property to false and the GridView is again populated with records i.e. Images fetched from the database by making call to the BindGrid method.
Then, a FOR EACH loop is executed over the GridView rows and the style and formatting are applied to the Header Row and Alternating Row of the GridView control.
Note: The colors are applied to individual cell of each Row and not to the whole Row as if this is not done then the color will spread on all cells of the Excel sheet.
 
After that, CSS class named textmode is applied to each cell of the GridView. This class makes sure that all the contents are rendered in Text format (mso number format).
Note: The mso number format style prevents large numbers from getting converted to exponential values.
 
Finally, StringWriter object is written to the Response which initiates the File download operation.
C#
protected void ExportToExcel(object sender, EventArgs e)
{
    Response.Clear();
    Response.Buffer = true;
    Response.AddHeader("content-disposition", "attachment;filename=GridViewExport.xls");
    Response.Charset = "";
    Response.ContentType = "application/vnd.ms-excel";
    using (StringWriter sw = new StringWriter())
    {
        HtmlTextWriter hw = new HtmlTextWriter(sw);
 
        //To Export all pages.
        gvFiles.AllowPaging = false;
        this.BindGrid();
 
        gvFiles.HeaderRow.BackColor = Color.White;
        foreach (TableCell cell in gvFiles.HeaderRow.Cells)
        {
            cell.BackColor = gvFiles.HeaderStyle.BackColor;
        }
        foreach (GridViewRow row in gvFiles.Rows)
        {
            row.BackColor = Color.White;
            foreach (TableCell cell in row.Cells)
            {
                if (row.RowIndex % 2 == 0)
                {
                    cell.BackColor = gvFiles.AlternatingRowStyle.BackColor;
                }
                else
                {
                    cell.BackColor = gvFiles.RowStyle.BackColor;
                }
                cell.CssClass = "textmode";
            }
        }
 
        gvFiles.RenderControl(hw);
 
        //Style to format numbers to string.
        string style = @"<style> .textmode { mso-number-format:\@; } </style>";
        Response.Write(style);
        Response.Output.Write(sw.ToString());
        Response.Flush();
        Response.End();
    }
}
 
VB.Net
Protected Sub ExportToExcel(ByVal sender As Object, ByVal e As EventArgs)
   Response.Clear()
    Response.Buffer = True
    Response.AddHeader("content-disposition", "attachment;filename=GridViewExport.xls")
    Response.Charset = ""
    Response.ContentType = "application/vnd.ms-excel"
    Using sw As StringWriter = New StringWriter()
        Dim hw As HtmlTextWriter = New HtmlTextWriter(sw)
 
        'To Export all pages.
        gvFiles.AllowPaging = False
        Me.BindGrid()
 
        gvFiles.HeaderRow.BackColor = Color.White
        For Each cell As TableCell In gvFiles.HeaderRow.Cells
            cell.BackColor = gvFiles.HeaderStyle.BackColor
        Next
        For Each row As GridViewRow In gvFiles.Rows
            row.BackColor = Color.White
            For Each cell As TableCell In row.Cells
                If row.RowIndex Mod 2 = 0 Then
                    cell.BackColor = gvFiles.AlternatingRowStyle.BackColor
                Else
                    cell.BackColor = gvFiles.RowStyle.BackColor
                End If
                cell.CssClass = "textmode"
            Next
        Next
 
        gvFiles.RenderControl(hw)
 
        'Style to format numbers to string.
        Dim style As String = "<style> .textmode { mso-number-format:\@; } </style>"
        Response.Write(style)
        Response.Output.Write(sw.ToString())
        Response.Flush()
        Response.End()
    End Using
End Sub
 
 
Exporting GridView with Images to PDF with Formatting
When the Export Button is clicked,the Response class properties are set.
1. Content-Disposition – It is a response header indicating, the download file is an attachment and allows setting the file name.
Note: For more details on Content-Disposition header, please refer What is Content Disposition Header in ASP.Net.
 
2. ContentType – It informs the Browser about the file type. In this case it is PDF.
 
The Paging is disabled for the GridView by setting the AllowPaging property to false and the GridView is again populated with records i.e. Images fetched from the database by making call to the BindGrid method.
Next, the GridView is rendered into an HTML string using HtmlTextWriter and then, the generated HTML is added to the iTextSharp PDF document using Document class.
After that, the PDF document is opened and the GridView data is written using ParseXHtml method of XmlWorkerHelper class.
Finally, StringWriter object is written to the Response which initiates the File download operation.
C#
protected void ExportToPDF(object sender, EventArgs e)
{
    Response.Clear();
    Response.Buffer = true;
    Response.AddHeader("content-disposition", "attachment;filename=GridViewExport.pdf");
    Response.Charset = "";
    Response.ContentType = "application/pdf";
 
    //To Export all pages.
    gvFiles.AllowPaging = false;
    this.BindGrid();
 
    using (StringWriter sw = new StringWriter())
    {
        using (HtmlTextWriter hw = new HtmlTextWriter(sw))
        {
            gvFiles.RenderControl(hw);
            using (StringReader sr = new StringReader(sw.ToString()))
            {
                using (Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f))
                {
                    using (PdfWriter writer = PdfWriter.GetInstance(pdfDoc, Response.OutputStream))
                    {
                        pdfDoc.Open();
                        XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, sr);
                        pdfDoc.Close();
                        Response.Cache.SetCacheability(HttpCacheability.NoCache);
                        Response.Write(pdfDoc);
                        Response.End();
                    }
                }
            }
        }
    }
}
 
VB.Net
Protected Sub ExportToPDF(ByVal sender As Object, ByVal e As EventArgs)
    Response.Clear()
    Response.Buffer = True
    Response.AddHeader("content-disposition", "attachment;filename=GridViewExport.pdf")
    Response.Charset = ""
    Response.ContentType = "application/pdf"
 
    'To Export all pages.
    gvFiles.AllowPaging = False
    Me.BindGrid()
 
    Using sw As StringWriter = New StringWriter()
        Using hw As HtmlTextWriter = New HtmlTextWriter(sw)
            gvFiles.RenderControl(hw)
            Using sr As StringReader = New StringReader(sw.ToString())
                Using pdfDoc As Document = New Document(PageSize.A4, 10.0F, 10.0F, 10.0F, 0.0F)
                    Using writer As PdfWriter = PdfWriter.GetInstance(pdfDoc, Response.OutputStream)
                        pdfDoc.Open()
                        XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, sr)
                        pdfDoc.Close()
                        Response.Cache.SetCacheability(HttpCacheability.NoCache)
                        Response.Write(pdfDoc)
                        Response.End()
                    End Using
                End Using
            End Using
        End Using
    End Using
End Sub
 
 
Error
The following error occurs when you run the application first time and click on export you might receive the following error.
Server Error in '/ASP.Net' Application.

Control 'GridView1' of type 'GridView' must be placed inside a form tag with runat=server.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Web.HttpException: Control 'GridView1' of type 'GridView' must be placed inside a form tag with runat=server.
 
 
Solution
The solution to the above exception is to override VerifyRenderingInServerForm event handler.
 
 
Screenshots
Exporting GridView
Export GridView with Images from database to Word Excel and PDF Formats
 
Exported Word Document
Export GridView with Images from database to Word Excel and PDF Formats
 
Exported Excel file
Export GridView with Images from database to Word Excel and PDF Formats
 
Exported PDF file
Export GridView with Images from database to Word Excel and PDF Formats
 
 
Demo
 
 
Downloads