In this article I will explain with an example, how to print GridView with page breaks and repeat header on each page using C# and VB.Net.
This article will also illustrate how to print single page and all pages GridView 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:
GridView – For displaying data.
Columns
GridView consists of three BoundField columns.
 
Properties
PageSize – For permitting maximum number of rows to be displayed per page.
AllowPaging – For enabling paging in the GridView control.
 
Events
GridView has been assigned with the following event handler i.e. OnPageIndexChanging
Button – One for printing current page and another one for printing all pages.
 
Properties
The Buttons have been assigned with an OnClick event handler.
 
Events
The Buttons have been assigned with the CommandArgument property.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" AllowPaging="true" OnPageIndexChanging="OnPageIndexChanging" PageSize="10">
    <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 classes 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 { background-color: #F7F7F7; color: #333; font-weight: bold; }
    table th, table td { padding: 5px; border: 1px solid #ccc; }
    table, table table td { border: 0px solid #ccc; }
</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 handler, 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 constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    using (SqlConnection con = new SqlConnection(constr))
    {
        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 constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
    Using con As New SqlConnection(constr)
        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
Inside the OnPageIndexChanging event handler, the PageIndex property of the GridView is updated with the new Page Number which was clicked.
Finally, the GridView is populated using the BindGrid method which in-turn displays the new GridView page.
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 using JavaScript in ASP.Net
There are two Buttons for printing the GridView control if any of them is clicked, it will 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, a check is performed which Button is clicked so that the value of CommandArgument property of the clicked button can be fetched.
If the PrintAll Button is clicked, then the paging feature is disabled for the GridView and the BindGrid method is called.
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.
 
After that, a FOR EACH loop is executed over the GridView rows, 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 class objects 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>
 
 
Possible Error
The following error occurs, when you try to render a control to Response i.e. exporting GridView to Excel, Word, PDF or CSV formats.
RegisterForEventValidation can only be called during Render();
 
 
Solution
The solution for this problem is explanation in this article, RegisterForEventValidation can only be called during Render().
 
 
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