Click here to Skip to main content
15,860,972 members
Articles / Web Development / ASP.NET
Article

Printing a GridView with Paging

Rate me:
Please Sign up or sign in to vote.
4.74/5 (29 votes)
18 Oct 2007CPOL2 min read 168.7K   6.4K   86   16
This is a WebControl that provides an easy way to prepare an ASP.NET GridView to be paged and printed in the browser.
Image 1

Introduction

This is a WebControl that provides an easy way to prepare an ASP.NET GridView to be paged and printed in the browser.

How It Works

This control inherits from the regular GridView, so no original feature will be lost.
We implement the paging by overriding the method that renders the gridview row when we detect that it should be the last row in the current page. This is done by using the method SetRenderMethodDelegate of the row.

C#
void ReportGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == System.Web.UI.WebControls.DataControlRowType.DataRow)
    {
        _currentPageRow++;
        if (_currentPageRow == this._printPageSize)
        {
            _currentPageRow = 0;
            e.Row.SetRenderMethodDelegate(PageBreakRender);
        }
    }
}

Now, the last row of each page will use our PageBreakRender method to render itself. So, in the PageBreakRender method we have to manually render the contents of the row, that's where we are going to close the table, insert a page break and open the table again in the next page.
Here's the PageBreakRender method:

C#
protected void PageBreakRender(HtmlTextWriter output, Control container)
{
    HtmlTextWriter cellsWriter = new HtmlTextWriter(new StringWriter());
    foreach (Control c in container.Controls)
    {
        TableCell cell = (TableCell)c;
        cell.RenderControl(cellsWriter);
    }

    output.Write("<tr>");
    output.Write(cellsWriter.InnerWriter.ToString());
    output.Write("</tr></table>");
    output.Write(GetPageFooterHtml());

    //If it is the last row, don't show the next header
    if (_currentPrintPage ==  PrintPageCount && Rows.Count % 
        (_currentPrintPage) == 0)
        return;

    output.Write("<div style=\"page-break-after:always;\"></div>");
    output.Write(GetHeaderHtml());
    _currentPrintPage++;
}

Note that there is a call to a method named GetHeaderHtml. This method returns the header of the GridView, so it can be rendered again in the new page.

This is the main idea behind the control. I also added the capability to render a custom page header and page footer defined in templates. Enabling the use of templates is very straight forward and you should find plenty of resources about it on the internet. You can also take a closer look at the source code to see how it works.

How To Use It

This control will work just like a regular GridView, but to enable paging we should look at a couple of properties:

  • AllowPrintPaging – Enables the paging (bool)
  • PrintPageSize - The number of rows that will fit in one single page (int)

The control's opening tag should be something like this:

ASP.NET
<wc:ReportGridView runat="server" BorderWidth="1" 
    ID="gvSample" PrintPageSize="23" AllowPrintPaging="true" 
    AutoGenerateColumns="false">

That's it. Adding these two properties will make ASP.NET output several GridViews, one for each page.

You can still insert custom content between each GridView, before and after the page break. This can be accomplished by defining a PageHeaderTemplate and a PageFooterTemplate.

Here is the GridView used in our sample page:

ASP.NET
<wc:ReportGridView runat="server" BorderWidth="1" 
    ID="gvSample" AutoGenerateColumns="false" PrintPageSize="23" 
    AllowPrintPaging="true"
            Width="600px">
        <Columns>
            <asp:BoundField DataField="Name" HeaderText="Customer Name" />
            <asp:BoundField DataField="PhoneNumber" 
                HeaderText="Customer Phone" 
                ItemStyle-HorizontalAlign="center" />
        </Columns>
        <PageHeaderTemplate>
            <br />
            PAGE HEADER TEMPLATE HERE
            <br />
        </PageHeaderTemplate>
        <PageFooterTemplate>
            <br />

            <hr />
            Page <%# gvSample.CurrentPrintPage.ToString() %> / 
                    <%# gvSample.PrintPageCount %>

        </PageFooterTemplate>
    </wc:ReportGridView>

Notice that there are a couple more properties that we can use in the templates:

  • CurrentPrintPage – Return the current page that is being rendered
  • PrintPageCount – The total number of pages

It can be used to display the page number at the footer or at the header of the page, as we can see in the sample picture above.

Known Issues

When using Firefox, the BorderWith property must be set explicitly. Otherwise the border of the GridView won't be displayed.

Conclusion

In this article, we saw how we can extend the GridView control to add custom rendering logic and provide a useful feature such as preparing it for printing in the browser.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Intelligent Coder
Canada Canada
I've been developing .NET enterprise applications since 2000.

I am originally from Rio de Janeiro and I am currently working at http://www.intelligentcoder.com in Ontario.

I also have my own startup where we offer client intake forms.

Comments and Discussions

 
QuestionFirst Page without Header Pin
Vicente Galindo5-Apr-16 14:37
Vicente Galindo5-Apr-16 14:37 
QuestionControls in PageHeaderTemplate Pin
Member 844343029-Oct-14 5:10
Member 844343029-Oct-14 5:10 
Questionhow to bind controls taken in pageheadertemplate from database Pin
bhoyarpriti5-Mar-13 23:08
bhoyarpriti5-Mar-13 23:08 
BugPageFooterTemplate is duplicated Pin
esraa farag22-Nov-11 23:43
esraa farag22-Nov-11 23:43 
GeneralMy vote of 5 Pin
sravani.v10-Nov-11 1:20
sravani.v10-Nov-11 1:20 
QuestionAwesome Job Dear Pin
Milton_win3-Jul-11 20:22
Milton_win3-Jul-11 20:22 
GeneralMake it into a DLL Pin
vrhari6-Sep-10 1:11
vrhari6-Sep-10 1:11 
GeneralPrinting a GridView with Paging Pin
krunal198626-Jul-10 23:53
krunal198626-Jul-10 23:53 
GeneralRe: Printing a GridView with Paging Pin
siskum3-Nov-11 13:51
siskum3-Nov-11 13:51 
Generalprinting a gridview with paging Pin
annamthana24-Jul-09 19:19
annamthana24-Jul-09 19:19 
QuestionHow about when there are odd number of records in the gridview? Pin
shravaniraj9-Jul-09 3:50
shravaniraj9-Jul-09 3:50 
QuestionPrinting a GridView with Paging Pin
annamthana28-Jun-09 21:51
annamthana28-Jun-09 21:51 
Hi Cassio Mosqueira

Thanks for this great article its very much used for me.

my question is how can i place the datalist in the Page Header Template

I try some way, but i dont get any solution can you guid me..?


regards

Thanasekaran.P
Generalimports shared.webcontrols is not valid as indentifier Pin
Member 389525213-Apr-09 13:49
Member 389525213-Apr-09 13:49 
GeneralHeaderstyle - alignment Pin
katem631-Jul-08 1:10
katem631-Jul-08 1:10 
GeneralRe: Headerstyle - alignment Pin
Cassio Mosqueira31-Jul-08 3:10
Cassio Mosqueira31-Jul-08 3:10 
GeneralOne small fix Pin
ingridt19-Nov-07 11:44
ingridt19-Nov-07 11:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.