Wednesday 9 March 2011

Printing Multi Page GridView with Preview - 1



This post concentrates on how to print the GridView contents using Javascript when it has multiple pages exists. There are lots of ways to achieve previewing all pages of GridView in to a popup window and user can print from a print button, each can be used for different scenarios. So this post and subsequence post concentrate on each ways.

Here I am connecting to the Northwind database for this example.

The following implementation shows the first method to preview all the records in the GridView using Javascript.

In aspx script.
<div>
    <asp:GridView ID="grdViewProducts" runat="server" 
        AllowPaging="True" AutoGenerateColumns="False" TabIndex="1"
        DataKeyNames="ProductID" Width="100%" CssClass="GridViewStyle"
        ShowFooter="false" CellPadding="4" ForeColor="#333333" GridLines="None" 
        OnPageIndexChanging="grdViewProducts_PageIndexChanging">
        <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
        <Columns>
            <asp:BoundField DataField="ProductID" HeaderText="Product ID" />
            <asp:BoundField DataField="ProductName" HeaderText="Product Name" />
            <asp:BoundField DataField="CompanyName" HeaderText="Supplier" />
            <asp:BoundField DataField="CategoryName" HeaderText="Category" />
            <asp:BoundField DataField="QuantityPerUnit" 
                                    HeaderText="Quantity Per Unit" />
            <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" />
        </Columns>
        <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
        <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
        <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
        <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
        <EditRowStyle BackColor="#999999" />
        <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
    </asp:GridView>
    <input type="button" value="Print" onclick="PrintGridView()" />
    <asp:HiddenField ID="hndGridViewPrintContent" runat="server" />
    
    <asp:Button Text="For Checking Postback" runat="server" ID="Button1" />
    <asp:DropDownList runat="server" ID="DDLPostBack" AutoPostBack="true"
        onselectedindexchanged="DDLPostBack_SelectedIndexChanged">
        <asp:ListItem Text="List 1" Value="List 1"></asp:ListItem>
        <asp:ListItem Text="List 2" Value="List 2"></asp:ListItem>
    </asp:DropDownList>
</div>
Remember, this javascript may thro’ an error (You can only have one <title> element within the <head> element.) if you keep it in the Page header. Because it contains <title> in the Javascript script. So you can place it inside of the body itself or remove any one <title> from the Javascript or Page.
function PrintGridView() {
     var printWindow = window.open("", "mywindow", "location=0,status=0,scrollbars=1,resizable=1");
     var strContent = "<html><body>";
     strContent = strContent + "<title>Print Preview</title>";
     strContent = strContent + "<link href=\"App_Themes/Default/Default.css\" type=\"text/css\" rel=\"stylesheet\" />";
     strContent = strContent + "</head><body>";
     strContent = strContent + "<div id='buttons' style='width:100%;text-align:right;'>";
     strContent = strContent + "<input type='button' id='btnPrint' value='Print' style='width:100px' onclick='window.print()' />";
     strContent = strContent + "<input type='button' id='btnCancel' value='Cancel' style='width:100px' onclick='window.close()' />";
     strContent = strContent + "</div>";
     strContent = strContent + "<div style='width:100%;'>";
     strContent = strContent + document.getElementById('<%= hndGridViewPrintContent.ClientID %>').value;
     strContent = strContent + "</div>";
     strContent = strContent + "</body>";
     printWindow.document.write(strContent);
     printWindow.document.close();
     printWindow.focus();
 }
.GridViewStyle
{
    font-family:Calibri;
    font-size:12px;
}
protected void Page_PreRender(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        grdViewProducts.AllowPaging = false;
        BindGrid();
        System.IO.StringWriter stringwriter = new System.IO.StringWriter();
        System.Web.UI.HtmlTextWriter htmlwriter = new System.Web.UI.HtmlTextWriter(stringwriter);
        grdViewProducts.RenderControl(htmlwriter);
        hndGridViewPrintContent.Value = stringwriter.ToString();

        grdViewProducts.AllowPaging = true;
        BindGrid();
    }
}
private void BindGrid()
{
    using (SqlConnection connection =
        new SqlConnection(ConfigurationManager.ConnectionStrings
                            ["SQLConnection"].ConnectionString))
    {

        SqlCommand command = new SqlCommand(
               "SELECT ProductID, ProductName, CompanyName, CategoryName, " +
               "QuantityPerUnit, UnitPrice FROM Products " +
               "JOIN Suppliers ON Products.SupplierID = Suppliers.SupplierID " +
               "JOIN Categories ON Products.CategoryID = Categories.CategoryID " +
               "Order by ProductID", connection);

        connection.Open();
        SqlDataReader dr = command.ExecuteReader(CommandBehavior.CloseConnection);

        IList<ProductView> productViewList = new List<ProductView>();
        while (dr.Read())
        {
            ProductView productView = new ProductView();
            productView.ProductID = dr["ProductID"].ToString();
            productView.ProductName = dr["ProductName"].ToString();
            productView.CompanyName = dr["CompanyName"].ToString();
            productView.CategoryName = dr["CategoryName"].ToString();
            productView.QuantityPerUnit = dr["QuantityPerUnit"].ToString();
            productView.UnitPrice = Convert.ToDouble(dr["UnitPrice"].ToString());
            productViewList.Add(productView);
        }
        grdViewProducts.DataSource = productViewList;
        grdViewProducts.DataBind();
    }
}
protected void grdViewProducts_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    grdViewProducts.PageIndex = e.NewPageIndex;
    BindGrid();
}
/// <summary>
/// This event is used to remove the error occuring while exporting to export
/// The Error is : Control 'ControlID' of type 'GridView' must be placed inside a form tag with runat=server.
/// </summary>
/// <param name="control"></param>
public override void VerifyRenderingInServerForm(Control control)
{
    return;
}
protected void DDLPostBack_SelectedIndexChanged(object sender, EventArgs e)
{

}
public class ProductView
{
    public string ProductID { get; set; }
    public string ProductName { get; set; }
    public string CompanyName { get; set; }
    public string CategoryName { get; set; }
    public string QuantityPerUnit { get; set; }
    public double UnitPrice { get; set; }
}
The idea behind is, we are declaring a hidden control in the page. When the page gets loaded at the first time, bind all the records to the GridView (with AllowPaging = false), get the HTML code and assigning to the hidden control. So the hidden control always has the inner HTML of the GridView.

I have added some other controls like Button, DropDown box for verifying page result when post back happening. So make sure you declared false for ValidateRequest. in Page declaration

The output of the implementation would be :
GridView with Multi Pagging

Print Preview window with all records

download the source code here


0 Responses to “Printing Multi Page GridView with Preview - 1”

Post a Comment