总想写点积极的东西。工作,程序,c#,水晶报表……
这段日子一直在弄水晶报表,虽然做的都是很简单的东西,但是经过我已经不记得的次数的调试和测试,看着它们在项目里运行正常,高兴是不由自主的!现在把我做水晶报表的一点点入门知识和大家分享。
winform(windows应用程序设计的页面)和webform(asp.net web应用程序设计的页面)都可以调用已经设计好的水晶报表。
水晶报表的执行模式有两种:pull模式和push模式。pull模式简单点讲就是水晶报表直接从数据库里取数据;push模式则是通过建立dataset架构,并自己编写代码取数据填充记录dataset,然后将其添加到报表。
我在项目中做的就是winform调用水晶报表。做的过程中最好按顺序一个一个来,这样不仅节省时间又不容易出错。(这是我做了几十张报表<虽然项目中只需要用七张>总结出来的经验)
步骤如下:
1. 新建一个窗体Form1.cs
(1)在解决方案资源管理器中,右击项目名,“添加”-“添加windows窗体”。
(2)添加报表浏览器。在“工具箱”的“windows窗体”里找到一个叫CrystalReportViewer的控件,将其添加到窗体上,用它来显示我们的报表。 提示:为方便这个报表查看器的大小随窗体的大小变化而变化,最好改变它的dock属性(如fill)。
(3)编写连接数据库和绑定报表的代码。这个在我们讨论完下面的两个步骤后再写出来。
2. 新建一个数据集Dataset1.xsd
(1)在解决方案资源管理器中,右击项目名,“添加”-“添加新项”-“数据集”。
(2)添加架构。出现的空页面上有一句“若要开始,请将对象从[u]服务器资源管理器[/u]或[u]工具箱[/u]拖动到设计器表面,或在此右击。”
第一种情况:
若你需要的是数据库里一个CustomerTable的全部字段,那么直接将该CustomerTable从服务器资源管理器中选中直接拖到页面上就行了,页面上用表显示该CustomerTable的所有字段及其类型。要知道,在这个设计器里,我们建立的只是一个架构,它并不包含实际记录。给空架子放上内容,这个事情要在需要调用报表的Form1里去做。
第二种情况:
可是,在我们设计水晶报表的过程中,我们会经常碰到在报表中显示多个表的字段,那怎么在这个Dataset1.xsd里建立一个这样包含多个数据库表字段的table架构呢?我查了很多相关资料,看过最省心的方法是建立一个视图,然后把这个视图作为报表的数据源,可是这个办法在我要做的项目里是行不通的,不仅因为它不能随着我要查询内容的变化而变化试图,更因为它不是最简单的方法!
我的办法是直接右击,查看这个Dataset1.xsd文件的xml源,在里面编写element,把需要的字段名及其类型写上去就行。当然,你完全可以把这两个表全拖进来,然后剪切粘贴它们的字段组成一个表就搞定了。在做完这些事情后,我发现,不用进来xml源在可视的界面上也可以进行剪切粘贴的工作!记得把数据表名改成你自己取的。而填充这个table架构的内容要容易多了,在form里写连接数据库取内容的代码时,把sql查询语句写对就ok了!
保存!
3. 新建一个水晶报表CrystalReport1.rpt
(1)在解决方案资源管理器中,右击项目名,“添加”-“添加新项”-“CrystalReport”。
(2)设计报表。我是利用“报表专家”做的“标准报表”。字段的添加都是自动的,很方便,但是缺陷就是你每次要换个数据源或新增组时,这个样式就全都得初始化,以往调的大小,画的线条全都没有了。所以在做这个步骤的时候一定要考虑清楚了,然后再去优化你的界面。不管怎么样,界面到最后做优化应该是比较好的选择。
首先,由于上述第2个步骤已经在项目里建立了一个数据集,我们可以在“标准报表专家”里“项目数据”-“ADO.NET数据集”中看到我们的Dataset1下面有一个CustomerTable,双击它将其添加到右边的“报表中的表”。
下一步去添加“字段”,在这里,我们可以选择要在报表上显示的字段,将它们添加到右边的“要显示的字段”。设置到这里,一张简单的报表就出来了,如果想要报表拥有更多更好的功能,可以下一步继续设置。
下一步到“组”,这一项是可选设置。如果我们希望将所有的信息按CustomerTable中的CustomerCode字段分组,从而可以根据记录的值对它们排序,那么我们把CustomerCode添加到右边的“分组依据”。
下一步到“总计”,可选设置。如果我们希望报表上显示客户的统计总数,我们就可以选择CustomerCode到右边的“汇总字段”,选择汇总类型为“计数”。这样,在报表的页脚(也就是报表的最后一页最后一条记录的下方)会显示该总数。
下一步到“最前n个”,可选设置。这个设置可以基于前面所选汇总字段的值加以排序。
下一步到“图表”,可选设置。项目不需要,所以我没做这个功能。不过在偏重统计的财务报表制作中,这个是很实用的。你只需要选择要显示的字段统计数据,在“文本”里输入相对应的标题、脚注等,报表专家就自动生成一张非常漂亮的表了!
下一步到“选择”,可选设置。如果我们想对字段显示的数据进行筛选,在这里设置条件(等于、不等于、类似……)即可。
下一步到“样式”,可选设置。在这里可以设置我们想要的报表样式,比如表。不过我建议如果要做的是表,最好自己在工具箱里点“线条对象”,自己画!要漂亮很多哦!
保存!
* 注意:如果你想在设计水晶报表的时候改变数据库连接,那么回到第二个步骤改变Dataset1.xsd里的表后,如果在报表“添加或删除数据库”的“数据库专家”里找不到改变后的表,就重启你的解决方案,这样在水晶报表里就能刷新再显示新的数据库连接了。
4. 编写代码
(1)第一种情况:
上面所有的步骤做完了,我们到现在还是看不到显示有数据的报表。这时,我们回到第1个步骤的Form1. 之前我已经说过了,在Dataset1.xsd 里的CustomerTable是没有记录只有框架的表,我们需要在这里来写代码填充它。
在Form1的load事件里写如下代码:
try
{
string strconn= "Data Source=CHENSHAN;Initial Catalog=master;User Id=sa;Password=";
SqlConnection myconn = new SqlConnection(strconn);
string sql = "select * from CUSTOMERTABLE";//注意,这里查询出来的字段名一定要和DataSet1.xsd文件里的CUSTOMERTABLE一样
myconn.Open(); //连接数据库
SqlDataAdapter myDa = new SqlDataAdapter(sql,myconn);
DataSet myds = new DataSet(); //建立数据集
myDa.Fill(myds,"CUSTOMERTABLE"); //填充数据集
CrystalReport1 cr = new CrystalReport1 (); //实例化报表
cr.SetDataSource(myds.Tables["CUSTOMERTABLE"]); //为报表的数据表填充记录
this.crystalReportViewer1.ReportSource = cr; //为报表查询器设置报表源
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString()); //有错误时,弹出报错对话框
}
(2)第二种情况:
在另一个窗体中弹出报表窗体,并希望报表内容随该窗体里datatable的内容变化而变化。
如:在查询窗体里有一个customerDataSet,希望报表窗体的报表内容随查询窗体里显示在datagrid里的内容而动态变化,可以用构照函数传进CustomerTable参数,代码如下:
(A) 报表窗体Form1的代码
public Form1(DataTable CustomerTable)
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
//
// 报表查看器显示指定Table的内容
//
CrystalReport1 customerReport = new CrystalReport1();
customerReport.SetDataSource(customerTable);
CustomerCrystalReportViewer.ReportSource = customerReport;
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
(B) 查询窗体的代码
public QuaryForm()
{
DataSet coustomerDataSet ;
……//查询界面里的数据集填充
//
/// 显示报表
//
DataTable CustomerTable = coustomerDataSet.Tables["CustomerTable"].Clone(); //复制架构,但是没有实际记录
for(int i = 0; i < coustomerDataSet.Tables["CustomerTable"].DefaultView.Count; i++)
{
//将动态视图里的记录填充进customerTable
customerTable.ImportRow( coustomerDataSet.Tables["CustomerTable"].DefaultView[i].Row);
}
if (customerTable.Rows.Count > 0) //当customertable不为空时,显示报表窗体Form1
{
//将查询窗体里的customerTable作为报表窗体构造函数的参数传进去
Form1 customerReportForm = new Form1( customerTable);
customerReportForm.Show();
}
}
调试好后,就运行吧!希望能稳定的运行!
哇,花了我一个下午总结写篇啊……
如有疑问,可给我留言,大家一起交流,一起进步。