实现 DataGrid 在打印时,每页都可显示 表头


MS 的DataGrid 在数据呈现上非常好用,可在WEB打印时,无法在分页时每页都能显示表头,造成诸多不便。
经过一段时间的研究和资料搜索,找到一种解决办法:

要使打印时,每页都可显示表头,需要将 table 改造成 thead ,tbody,tfoot 分组。
现改造如下:

在WEB 应用程序项目中添加 WEB自定义控件,
代码如下:
其中的 namespace 名改为你当前项目的 namespace

namespace  FullDataGridControl
{
    
using System;
    
using System.Data;
    
using System.Drawing;
    
using System.Web;
    
using System.Web.UI.WebControls;
    
using System.Web.UI.HtmlControls;
    
using System.IO;
    
using System.Web.UI;

    
/// <summary>
    
///        FullDataGrid 的摘要说明。
    
/// </summary>

    public class FullDataGrid : System.Web.UI.WebControls.DataGrid
    
{
        
protected override void Render(System.Web.UI.HtmlTextWriter writer)
        
{
            writer.Write(
this.ParsMarkupWithPrintStyle(ParseMarkup()));
        }

        
/// <summary>
        
/// 去除 table 的 border 和  rules
        
/// </summary>
        
/// <param name="oldMarkup"></param>
        
/// <returns></returns>

        private string ParsMarkupWithPrintStyle(string markup)
        
{            

            markup 
= markup.Replace("<td","<td  style=\"BORDER-RIGHT:black 1px  solid;BORDER-TOP:black 1px  solid;BORDER-LEFT:black 1px  solid;BORDER-BOTTOM:black 1px  solid\"");
            
            markup 
= markup.Replace("rules=\"all\"","");
            markup 
= markup.Replace("border=\"1\"","border=\"0\"");

            
return markup;
        }

        
/// <summary>
        
/// 插入 thead,tbody 元素
        
/// </summary>
        
/// <returns></returns>

        private string ParseMarkup()
        
{
            StringWriter writer 
= new StringWriter();
            HtmlTextWriter buffer  
= new HtmlTextWriter(writer);
            
base.Render(buffer);
            
            
string markup = writer.ToString() ;
            
            
// <THEAD> 标签的位置 插在第一个 > 之后,即 <table> 之后
            int theadStarPos = markup.IndexOf(">")+">".Length;            
                        
            markup 
= markup.Insert(theadStarPos,"<thead style=\"DISPLAY:table-header-group;\">");
            
            
// </THEAD><TBODY> 标签的位置, 插在第一个 </tr> 之后
            int theadEndPos = markup.IndexOf("</tr>")+"</tr>".Length;    
            
            markup 
= markup.Insert(theadEndPos,"</thead><tbody>");
            
            
// </TBODY> 插在原先的 </TABLE> 之前
            int tbodyEndPos = markup.IndexOf("</table>");                
            
            markup 
= markup.Insert(tbodyEndPos,"</tbody><TFOOT style=\"DISPLAY: table-footer-group; FONT-WEIGHT: bold\">"+
                            
"<tr><TD style=\"BORDER-TOP:black 1px  solid\""+
                            
" ></TD></TR></TFOOT>");
            
return markup;
        }

    }

}

 
简单改造完毕。

为何要去掉 原来系统自动生成的 rules="all" 而且将 border=1 改为0 呢?
rules="all" 表示全部显示线框(上下左右)
如果不去掉,在打印第一页之后的页面时,表头的顶部线条会消失,效果自然不理想。
所以干脆去掉原先表格的线条,自己添加每个 td 的 border . 也就是这行:

markup  =  markup.Replace( " <td " , " <td  style=\ " BORDER - RIGHT:black 1px  solid;BORDER - TOP:black 1px  solid;BORDER - LEFT:black 1px  solid;BORDER - BOTTOM:black 1px  solid\ "" );
            




现做测试:

添加一个 WEBFORM,名为 FullDataGridTest.aspx
HTML 页代码如下:

<% @ Register TagPrefix="FullDataGridControl" Assembly="FullDataGridControl" Namespace="FullDataGridControl" %>
<% @ Page language="c#" Codebehind="FullDataGridTest.aspx.cs" AutoEventWireup="false" Inherits="FullDataGridControl.FullDataGridTest"  %>
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"  >
< HTML >
    
< HEAD >
        
< title > FullDataGridTest </ title >
        
< meta  content ="Microsoft Visual Studio .NET 7.1"  name ="GENERATOR" >
        
< meta  content ="C#"  name ="CODE_LANGUAGE" >
        
< meta  content ="JavaScript"  name ="vs_defaultClientScript" >
        
< meta  content ="http://schemas.microsoft.com/intellisense/ie5"  name ="vs_targetSchema" >
        
< style  media ="print" >
        .noprint
{display:none;}
        }
        .nextpage 
{
    PAGE-BREAK-AFTER
: always
}

        
</ style >
    
</ HEAD >
    
< body  MS_POSITIONING ="GridLayout" >
        
< form  id ="Form1"  method ="post"  runat ="server" >
            
< FullDataGridControl:FullDataGrid  id ="FullDataGrid1"  runat ="Server" >
            
</ FullDataGridControl:FullDataGrid >
            
</ form >
    
</ body >
</ HTML >

HTML代码很简单,只是要注意下 style media="print" ,该样式只在打印时有用。
noprint 即不打印输出, nextpage 为分页点

后台 cs  代码如下:
using  System;
using  System.Collections;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Web;
using  System.Web.SessionState;
using  System.Web.UI;
using  System.Web.UI.WebControls;
using  System.Web.UI.HtmlControls;

namespace  FullDataGridControl
{
    
/// <summary>
    
/// FullDataGridTest 的摘要说明。
    
/// </summary>

    public class FullDataGridTest : System.Web.UI.Page
    
{
        
protected FullDataGrid FullDataGrid1;

        
private void Page_Load(object sender, System.EventArgs e)
        
{
            
string[] strArr = new string[80];
            
for(int i=0;i<strArr.Length;i++)
            
{
                strArr[i] 
= "a";
                
            }


            FullDataGrid1.DataSource 
= strArr;
            FullDataGrid1.DataBind();
            
            
for(int i=30;i<FullDataGrid1.Items.Count;i+=30)
            
{
                FullDataGrid1.Items[i].CssClass 
= "nextpage";
            }

        }


        
#region Web 窗体设计器生成的代码
        
override protected void OnInit(EventArgs e)
        
{
            
//
            
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
            
//
            InitializeComponent();
            
base.OnInit(e);
        }

        
        
/// <summary>
        
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
        
/// 此方法的内容。
        
/// </summary>

        private void InitializeComponent()
        
{    
            
this.Load += new System.EventHandler(this.Page_Load);
        }

        
#endregion

    }

}

 

你可能感兴趣的:(datagrid)