先上图,最终效果如下:
可以连续打印。
具体功能就是大报表里面再套一个子报表。
考察了几个报表控件,在b/s下面ActiveReport还是比较好用的,简单,实用
具体步骤如下:
1、安装ActiveReports for .NET 3.0 Setup.exe,到官网自己下。
2、用自己的金钱、魅力、或者智慧注册之~~~~~不注册也可以用,不过报表上会有红色字体提示。
3、在项目中新建报表文件
4、在新建的报表文件上右键选择“视图设计器”,直接双击的话就会用vs代码编辑器打开,这里b/s和c/s是不一样的。c/s里面双击就是视图设计器了。
5、和设计网页一样,在页面上布置各种控件
画完的页面如下:
在左上角的地方有个按钮, ,这里面可以更改报表的信息,如纸张大小、纸张方向等,我选的就是A4纸、横向
这里不多说了,注意设定好页面里面每个地方的绑定字段,另外在右侧有一个子报表SubReport,在这里
这个放后面说~~~
点上面的数据库图标可以直接连接数据库进行测试,这个自己试验就ok,实际应用时都是用代码控制,这里控制太不灵活。另外需要说明的一点是,可以在这里把测试数据提取出来,方便选择每个地方的字段~~~不多说了,看图
6、下面开始做现实报表的网页
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ZhunKaoZheng.aspx.cs" Inherits="ExamSys.Report.ZhunKaoZheng" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
<meta name="GENERATOR" content="Microsoft Visual Studio 7.0">
<meta name="CODE_LANGUAGE" content="C#">
<meta name="vs_defaultClientScript" content="VBScript">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
<link rel="stylesheet" type="text/css" href="default.css">
</head>
<body>
<form id="ActiveXExport" method="post" runat="server">
</form>
<div id="pagebody">
<object id="arv" codebase="arview2.cab#version=-1,-1,-1,-1" height="800" width="100%" classid="clsid:8569D715-FF88-44BA-8D1D-AD3E59543DDE" viewastext>
<param name="_ExtentX" value="26141">
<param name="_ExtentY" value="11959">
</object>
<script language="vbscript">
<!--
sub arv_ControlLoaded()
arv.DataPath = "ZhunKaoZheng.aspx?ReturnReport=1"
end sub
-->
</script>
</div>
</body>
</html>
|
需要注意的是我这个控件是引用在form外面的,在里面不好使哦!!!
还有这个
arv.DataPath = "ZhunKaoZheng.aspx?ReturnReport=1"
是必须加的,记得ZhunKaoZheng.aspx就是本页面的地址,具体为什么加我也不知道,谁知道为啥记得告诉我哦。
后台代码如下:
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;
using System.IO;
using DataDynamics.ActiveReports;
using ExamSys.DBUtility;
using System.Data.SqlClient;
using System.Data;
namespace ExamSys.Report
{
public partial class ZhunKaoZheng : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string strSql="";
if (Session["personid"].ToString() != "" && Session["personid"] != null)
{
strSql = @"SELECT T_PERSON.ID, T_PERSON.NAME, T_PERSON.PHOTO,
T_PERSON.BH_SHENFENZHENG, T_PERSON.BAOMING_NO, T_PERSON.DEP,
ExamUser.examID, T_PERSON.DEP_BIANHAO,
T_INFO.NAME AS DEP_NAME, ExamList.elClass
FROM ExamList INNER JOIN
ExamUser ON ExamList.elID = ExamUser.elID INNER JOIN
T_PERSON ON ExamUser.personID = T_PERSON.ID INNER JOIN
T_INFO ON T_PERSON.DEP_BIANHAO = T_INFO.ID
WHERE (T_PERSON.ID = '" + Session["personid"].ToString() + @"')";
}
else
{
strSql = @"SELECT T_PERSON.ID, T_PERSON.NAME, T_PERSON.PHOTO,
T_PERSON.BH_SHENFENZHENG, T_PERSON.BAOMING_NO, T_PERSON.DEP,
ExamUser.examID, T_PERSON.DEP_BIANHAO,
T_INFO.NAME AS DEP_NAME, ExamList.elClass
FROM ExamList INNER JOIN
ExamUser ON ExamList.elID = ExamUser.elID INNER JOIN
T_PERSON ON ExamUser.personID = T_PERSON.ID INNER JOIN
T_INFO ON T_PERSON.DEP_BIANHAO = T_INFO.ID
WHERE (T_PERSON.DEP_BIANHAO = '" + Session["dep"].ToString() + @"') AND (ExamUser.elID IN (SELECT ELID FROM EXAMLIST AS EXAMLIST_1 WHERE (ELCLASS = '" + Session["bigtitle"].ToString() + "')))";
}
strSql = strSql.Replace("\r", " ").Replace("\n", " ");
DataSet myDS = SQLHelper.GetDataSet(strSql);
DataTable myDT = GetDistinctTable(myDS.Tables[0], "id");
string sReturnReport = this.Page.Request.QueryString["ReturnReport"];
if ((sReturnReport != null) && (sReturnReport.Trim().Length != 0))
{
this.Page.Response.Buffer = true;
ActiveReport3 rpt = null;
try
{
//这两句话是重点
rpt = new rptZhunKaoZheng();
rpt.DataSource = myDT;
rpt.DataMember = myDT.TableName;
rpt.Run(false);
}
catch (DataDynamics.ActiveReports.ReportException eRunReport)
{
this.Trace.Warn("Report failed to run:\n" + eRunReport.ToString());
}
MemoryStream outStream = new MemoryStream();
rpt.Document.Save(outStream, DataDynamics.ActiveReports.Document.RdfFormat.AR20);
outStream.Seek(0, SeekOrigin.Begin);
byte[] bytes = new byte[outStream.Length];
outStream.Read(bytes, 0, (int)outStream.Length);
this.Page.Response.ClearContent();
this.Page.Response.ClearHeaders();
this.Page.Response.BinaryWrite(bytes);
this.Page.Response.End();
}
}
/// <summary>
/// 获取对固定列不重复的新DataTable
/// </summary>
/// <param name="dt">含有重复数据的DataTable</param>
/// <param name="colName">需要验证重复的列名</param>
/// <returns>新的DataTable,colName列不重复,表格式保持不变</returns>
private DataTable GetDistinctTable(DataTable dt, string colName)
{
DataView dv = dt.DefaultView;
DataTable dtCardNo = dv.ToTable(true, colName);
DataTable Pointdt = new DataTable();
Pointdt = dv.ToTable();
Pointdt.Clear();
for (int i = 0; i < dtCardNo.Rows.Count; i++ )
{
string ss=dtCardNo.Rows[i][0].ToString();
DataRow dr = dt.Select(colName +"="+ ss)[0];
Pointdt.Rows.Add(dr.ItemArray);
}
return Pointdt;
}
}
}
|
为了确保能看的清楚,无关的代码我也不删除了。里面最重要的是
rpt = new rptZhunKaoZheng();
rpt.DataSource = myDT;
rpt.DataMember = myDT.TableName;
rpt.Run(false);
7、这样主报表就现实成功了,下面开始子报表的制作~~
8、同样的方法建立子报表模板
注意里面的标题栏为groupHeader,子报表的标题一定要选这个,不然不能在主报表里面现实,可以右键选择添加、删除标题栏
在里面设定好需要显示的字段就O了
9、更改主报表
1)选择主报表的detail模块,添加Format事件,这里面主要设置子报表的DataSource和DataMember
private void detail_Format(object sender, EventArgs e)
{
//string strSql1 = "SELECT EXAMLIST.ELNAME, SiteInfo.siName, T_PSSBSchema.seatnum, ExamOrder.eoBegin, ExamOrder.eoEnd FROM T_PSSBSchema INNER JOIN SiteInfo ON T_PSSBSchema.siID = SiteInfo.siID INNER JOIN ExamOrder ON SiteInfo.siID = ExamOrder.siID INNER JOIN EXAMLIST ON T_PSSBSchema.elID = EXAMLIST.ELID AND ExamOrder.elID = EXAMLIST.ELID WHERE (T_PSSBSchema.examID = '" + this.label9.Text + "')";
string strSql = @"SELECT ExamList.elName, SiteInfo.siName, ExamUser.seatnum, ExamOrder.eoBegin,
ExamOrder.eoEnd
FROM ExamUser INNER JOIN
SiteInfo ON ExamUser.siID = SiteInfo.siID INNER JOIN
ExamOrder ON SiteInfo.siID = ExamOrder.siID INNER JOIN
ExamList ON ExamUser.elID = ExamList.elID AND
ExamOrder.elID = ExamList.elID
WHERE (ExamUser.examID = '" + this.label9.Text + "')";
strSql = strSql.Replace("\r", " ").Replace("\n", " ");
DataTable myDT = SQLHelper.GetDataSet(strSql).Tables[0];
Time2CharConvert(myDT, "eoBegin", "f");
Time2CharConvert(myDT, "eoEnd", "t");
this.srptKaoChang.Report.DataSource = myDT;
this.srptKaoChang.Report.DataMember = myDT.TableName;
//((DataDynamics.ActiveReports.DataSources.SqlDBDataSource)this.srptKaoChang.Report.DataSource).ConnectionString = "data source=127.0.0.1;initial catalog=kuaiji;password=sa;persist security info=True;user id=sa";
//((DataDynamics.ActiveReports.DataSources.SqlDBDataSource)this.srptKaoChang.Report.DataSource).SQL = "SELECT EXAMLIST.ELNAME, SiteInfo.siName, T_PSSBSchema.seatnum, ExamOrder.eoBegin, ExamOrder.eoEnd FROM T_PSSBSchema INNER JOIN SiteInfo ON T_PSSBSchema.siID = SiteInfo.siID INNER JOIN ExamOrder ON SiteInfo.siID = ExamOrder.siID INNER JOIN EXAMLIST ON T_PSSBSchema.elID = EXAMLIST.ELID AND ExamOrder.elID = EXAMLIST.ELID WHERE (T_PSSBSchema.examID = '" + this.label9.Text + "')";
}
|
10、选择报表主体,添加ReportStart和ReportEnd事件。
rptKaoChang _rptKaoChang = null;
private void rptZhunKaoZheng_ReportStart(object sender, EventArgs e)
{
//Check to see if the holder subreport object is assigned, if not create it
//Creating the subreport here will only create one instance to use
if (_rptKaoChang == null)
{
_rptKaoChang = new rptKaoChang();
this.srptKaoChang.Report = _rptKaoChang;
this.srptKaoChang.Report.DataSource = new DataDynamics.ActiveReports.DataSources.SqlDBDataSource();
}
}
private void rptZhunKaoZheng_ReportEnd(object sender, EventArgs e)
{
//clean up existing subreport document object
_rptKaoChang.Document.Dispose();
//clean up existing subreport object
_rptKaoChang.Dispose();
//Reset subreport to null, so if this report is called again it will reinit inside the section format event
_rptKaoChang = null;
}
|
在此进行子报表的初始化和关闭。
11、结束战斗,测试OK~~~