In this article I will explain with an example, how to print ASP.Net GridView control with page breaks and repeat header on each page using C# and VB.Net.
This article will illustrate how to print GridView with Current Page and all Pages in ASP.Net.
When the Print Button is clicked, the GridView will be rendered as an HTML string which will be later sent to Printer using JavaScript in ASP.Net.
 
 
Database
Here I am making use of Microsoft’s Northwind Database. You can download it from here.
 
 
HTML Markup
The following HTML Markup consists of an ASP.Net GridView control with three BoundField columns and two Buttons.
Paging has been enabled for the GridView control.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" AllowPaging="true" PageSize="10" OnPageIndexChanging="OnPageIndexChanging">
    <Columns>
        <asp:BoundField DataField="ContactName" HeaderText="Contact Name" ItemStyle-Width="150px"/>
        <asp:BoundField DataField="City" HeaderText="City" ItemStyle-Width="100px"/>
        <asp:BoundField DataField="Country" HeaderText="Country" ItemStyle-Width="100px"/>
    </Columns>
</asp:GridView>
<hr/>
<asp:Button ID="btnPrintCurrent" runat="server" Text="Print Current Page" OnClick="PrintGridView" CommandArgument="Current"/>
<asp:Button ID="btnPrintAll" runat="server" Text="Print All Pages" OnClick="PrintGridView" CommandArgument="All"/>
 
 
CSS Styles for GridView
The following are the CSS styles used for the GridView control.
<style id="gridStyles" runat="server" type="text/css">
    body
    {
        font-family: Arial;
        font-size: 10pt;
    }
    table
    {
        border: 1px solid #ccc;
        border-collapse: collapse;
    }
    table th
    {
        color: #0090CB;
        font-weight: bold;
    }
    table th, table td
    {
        padding: 5px;
        border: 1px solid #ccc;
    }
    table, table table td
    {
        border: 0px solid #ccc;
    }
    thead
    {
        display: table-header-group;
    }
    tfoot
    {
        display: table-footer-group;
    }
</style>
 
 
Namespaces
You will need to import the following namespaces.
C#
using System.IO;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
 
VB.Net
Imports System.IO
Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration
 
 
Populating the GridView control
Inside the Page Load event, the GridView is populated with records from the Customers Table of the Northwind Database.
C#
protected void Page_Load(object sender, EventArgs e)
{
    if (!this.IsPostBack)
    {
        this.BindGrid();
    }
}
 
private void BindGrid()
{
    string conString = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
    using (SqlConnection con = new SqlConnection(conString))
    {
        using (SqlDataAdapter sda = new SqlDataAdapter("SELECT * FROM Customers", con))
        {
            using (DataTable dt = new DataTable())
            {
                sda.Fill(dt);
                GridView1.DataSource = dt;
                GridView1.DataBind();
            }
        }
    }
}
 
VB.Net
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
    If Not IsPostBack Then
        Me.BindGrid()
    End If
End Sub
 
Private Sub BindGrid()
    Dim conString As String = ConfigurationManager.ConnectionStrings("conString").ConnectionString
    Using con As New SqlConnection(conString)
        Using sda As New SqlDataAdapter("SELECT * FROM Customers", con)
            Using dt As New DataTable()
                sda.Fill(dt)
                GridView1.DataSource = dt
                GridView1.DataBind()
            End Using
        End Using
    End Using
End Sub
 
 
Implement Paging in GridView
The OnPageIndexChanging event handles the Pagination in the GridView.
Inside the OnPageIndexChanging event handler, the GridView’s PageIndex property is updated and the GridView is again populated from Database by making call to the BindGrid method.
C#
protected void OnPageIndexChanging(object sender, GridViewPageEventArgs e)
{
    GridView1.PageIndex = e.NewPageIndex;
    this.BindGrid();
}
 
VB.Net
Protected Sub OnPageIndexChanging(sender As Object, e As GridViewPageEventArgs)
    GridView1.PageIndex = e.NewPageIndex
    Me.BindGrid()
End Sub
 
 
Printing GridView with page breaks and repeat header on each page in ASP.Net
There are two Buttons for printing the GridView control and both when clicked invoke the PrintGridView event handler.
1. PrintCurrent Button – The current page of the GridView will be printed.
2. PrintAll Button – All the pages of the GridView will be printed and the Header row will be repeated on each page.
Inside the PrintGridView event handler, first the Pager is hidden as it is not required.
Then if the PrintAll Button is clicked, then the paging feature is disabled for the GridView and the GridView is again populated with data.
The UseAccessibleHeader property and the TableSection property are set for the GridView so that the HTML Table is rendered with THEAD and TBODY tags.
Note: THEAD and TBODY tags are required for repeating the Header Row on each page as well as for adding Page Breaks.
 
Then using a LOOP, after every 10th record (which is the PageSize of the GridView page), a Page Break CSS style is set for GridView. Thus when printed, after every 10th record the next set of 10 records will be printed on a new Page.
Finally, the GridView is rendered into HTML using StringWriter and HtmlTextWriter classes and the GridView HTML along with the CSS styles are passed to the PrintGrid JavaScript function using the ClientScript.RegisterStartupScript method.
C#
protected void PrintGridView(object sender, EventArgs e)
{
    //Disable Paging if all Pages need to be Printed.
    if ((sender as Button).CommandArgument == "All")
    {
        //Disable Paging.
        GridView1.AllowPaging = false;
 
        //Re-bind the GridView.
        this.BindGrid();
 
        //For Printing Header on each Page.
        GridView1.UseAccessibleHeader = true;
        GridView1.HeaderRow.TableSection = TableRowSection.TableHeader;
        GridView1.FooterRow.TableSection = TableRowSection.TableFooter;
        GridView1.Attributes["style"] = "border-collapse:separate";
        foreach (GridViewRow row in GridView1.Rows)
        {
            if ((row.RowIndex + 1) % GridView1.PageSize == 0 && row.RowIndex != 0)
            {
                row.Attributes["style"] = "page-break-after:always;";
            }
        }
    }
    else
    {
        //Hide the Pager.
        GridView1.PagerSettings.Visible = false;
        this.BindGrid();
    }
 
    using (StringWriter sw = new StringWriter())
    {
        //Render GridView to HTML.
        HtmlTextWriter hw = new HtmlTextWriter(sw);
        GridView1.RenderControl(hw);
 
       //Enable Paging.
        GridView1.AllowPaging = true;
        this.BindGrid();
 
        //Remove single quotes to avoid JavaScript error.
        string gridHTML = sw.ToString().Replace(Environment.NewLine, "");
        string gridCSS = gridStyles.InnerText.Replace("\"", "'").Replace(Environment.NewLine, "");
 
 
        //Print the GridView.
        string script = "window.onload = function() { PrintGrid('" + gridHTML + "', '" + gridCSS + "'); }";
        ClientScript.RegisterStartupScript(this.GetType(), "GridPrint", script, true);
    }
}
 
public override void VerifyRenderingInServerForm(Control control)
{
    /*Verifies that the control is rendered */
}
 
VB.Net
Protected Sub PrintGridView(ByVal sender As Object, ByVal e As EventArgs)
    'Disable Paging if all Pages need to be Printed.
    If (CType(sender, Button).CommandArgument = "All") Then
 
        'Disable Paging.
        GridView1.AllowPaging = False
 
        'Re-bind the GridView.
        Me.BindGrid()
 
        'For Printing Header on each Page.
        GridView1.UseAccessibleHeader = True
        GridView1.HeaderRow.TableSection = TableRowSection.TableHeader
        GridView1.FooterRow.TableSection = TableRowSection.TableFooter
        GridView1.Attributes("style") = "border-collapse:separate"
        For Each row As GridViewRow In GridView1.Rows
            If (row.RowIndex + 1) Mod GridView1.PageSize = 0 AndAlso row.RowIndex <> 0 Then
                row.Attributes("style") = "page-break-after:always;"
            End If
        Next
    Else
        'Hide the Pager.
        GridView1.PagerSettings.Visible = False
        Me.BindGrid()
    End If
 
    Using sw As StringWriter = New StringWriter
 
        'Render GridView to HTML.
        Dim hw As HtmlTextWriter = New HtmlTextWriter(sw)
        GridView1.RenderControl(hw)
 
       'Enable Paging.
        GridView1.AllowPaging = true
        Me.BindGrid()
 
        'Remove single quotes to avoid JavaScript error.
        Dim gridHTML As String = sw.ToString.Replace(Environment.NewLine, "")
        Dim gridCSS As String = gridStyles.InnerText.Replace("""", "'").Replace(Environment.NewLine, "")
 
        ' Print the GridView.
        Dim script As String = "window.onload = function() { PrintGrid('" & gridHTML & "', '" & gridCSS & "'); }"
        ClientScript.RegisterStartupScript(Me.GetType(), "GridPrint", script, True)
    End Using
End Sub
 
Public Overrides Sub VerifyRenderingInServerForm(control As Control)
    ' Verifies that the control is rendered
End Sub
 
 
JavaScript function for printing the GridView control
Inside the PrintGrid JavaScript function, the rendered HTML and the CSS styles of the GridView are received and are written to a JavaScript Popup Window.
Finally, the Popup Window is opened and the JavaScript Print command is executed.
<script type="text/javascript">
    function PrintGrid(html, css) {
        var printWin = window.open('', '', 'left=0,top=0,width=400,height=300,scrollbars=1');
        printWin.document.write('<style type = "text/css">' + css + '</style>');
        printWin.document.write(html);
        printWin.document.close();
        printWin.focus();
        printWin.print();
        printWin.close();
    };
</script>
 
 
Errors
In case you get the following error on running the code.
RegisterForEventValidation can only be called during Render();
 
Please set the EnableEventValidation property to False in the @Page directive.
 
 
Screenshots
GridView
Print ASP.Net GridView with page breaks and repeat header on each page
 
Printed GridView Page
Print ASP.Net GridView with page breaks and repeat header on each page
 
 
Demo
 
 
Downloads