.NET 2005 中动态水晶报表的实现
简介
本程序演示如何动态地从数据库读入数据,并应用到水晶报表中。通过使用本程序,我们可以在应用程序的运行时刻定制水晶报表,限定只有那些被指定的字段(特定表的列)才显示在报表中。
背景
这一问题起因于一些 SLIIT 的学生询问我该如何使用 C# 2.0 动态地产生水晶报表。为了解决这个问题,我试着搜索了很多论坛和网站,但是很不幸,我没能找到任何的解决办法。在一些论坛中有人说,在 .NET 2005 中不可能创建动态的水晶报表。后来,我找到了解决办法。
代码使用
1.创建一个 C# 项目(本例中项目名称为app5),或添加窗体到已有项目中。 现在,你可以添加与表的字段相对应的复选框到窗体中,这些字段将被显示在水晶报表和水晶报表查看器(CrystalReportViewer)控件中。
在本例中,我已经使用 Access 创建了一个名为 db1.mdb 的数据库,以及一个名为 Customer 的表。 在 Customer 表中包含如下 5 个字段:Code、 FirstName、LastName、Address、Phone
2. 在解决方案资源管理器中使用“添加—新建项”功能,添加一个数据集(.xsd 文件, 本例中数据集名称为DataSet1) 到项目中,然后添加一个数据表(DataTable,本例中数据表名称为Customer) 到数据集中。
添加列到数据表(DataTable) 中,并命名为 Column1, Column2 … 等等。列的数目取决于将有多少列被显示在水晶报表中。
3.添加一个水晶报表到项目中(译者注:在解决方案资源管理器中使用“添加—新建项”功能添加),使用报表向导,先选择水晶报表的数据源(本例为“项目数据 — ADO.NET 数据集 — app5.DataSet1”),并选定要在水晶报表中显示的表(本例为 Customer);单击[下一步]按钮。
接下来在向导中选择要在报表中显示的字段,如下图所示。在单击向导的[完成]按钮后,报表就会自动生成。在报表的Section2(页眉带区)中,删除下列文本对象(即报表列的名称或标题):Column1, Column2...Column5
4. 现在在字段资源管理器中添加如下参数字段(parameter fields): col1, col2… col5 (参数字段的数目应该等于显示在水晶报表中的列的数目),并把它们放置到Section2 (页眉带区)中,与对应的报表列对齐
5. 添加下列方法到窗体中,以便于根据用户选定的报表列,创建 SQL SELECT 查询,并赋值到水晶报表的参数字段。
// ///
/// 本方法用于:
/// 1. 根据用户选定的字段名,创建 SELECT 查询
/// 2. 与水晶报表中的参数字段相对应,创建参数并赋值给它们
/// 说明: 根据用户的选择,这些参数用于显示水晶报表中的列名称(标题)
///
///
private string CreateSelectQueryAndParameters()
{
ReportDocument reportDocument;
ParameterFields paramFields;
ParameterField paramField;
ParameterDiscreteValue paramDiscreteValue;
reportDocument = new ReportDocument();
paramFields = new ParameterFields();
string query = "SELECT ";
int columnNo = 0;
if (chbCode.Checked)
{
columnNo++;
query = query.Insert(query.Length, "Code as Column" + columnNo.ToString());
paramField = new ParameterField();
paramField.Name = "col" + columnNo.ToString();
paramDiscreteValue = new ParameterDiscreteValue();
paramDiscreteValue.Value = "Customer Code";
paramField.CurrentValues.Add(paramDiscreteValue);
//把 paramField 添加到 paramFields 中
paramFields.Add(paramField);
}
if (chbFirstName.Checked)
{
columnNo++;
if (query.Contains("Column"))
{
query = query.Insert(query.Length, ", ");
}
query = query.Insert(query.Length, "FirstName as Column" + columnNo.ToString());
paramField = new ParameterField();
paramField.Name = "col" + columnNo.ToString();
paramDiscreteValue = new ParameterDiscreteValue();
paramDiscreteValue.Value = "First Name";
paramField.CurrentValues.Add(paramDiscreteValue);
//把 paramField 添加到 paramFields
paramFields.Add(paramField);
}
if (chbLastName.Checked)
{
columnNo++; //确定列的数目
if (query.Contains("Column"))
{
query = query.Insert(query.Length, ", ");
}
query = query.Insert(query.Length, "LastName as Column" + columnNo.ToString());
paramField = new ParameterField();
paramField.Name = "col" + columnNo.ToString();
paramDiscreteValue = new ParameterDiscreteValue();
paramDiscreteValue.Value = "Last Name";
paramField.CurrentValues.Add(paramDiscreteValue);
//把 paramField 添加到 paramFields
paramFields.Add(paramField);
}
if (chbAddress.Checked)
{
columnNo++;
if (query.Contains("Column"))
{
query = query.Insert(query.Length, ", ");
}
query = query.Insert(query.Length, "Address as Column" + columnNo.ToString());
paramField = new ParameterField();
paramField.Name = "col" + columnNo.ToString();
paramDiscreteValue = new ParameterDiscreteValue();
paramDiscreteValue.Value = "Address";
paramField.CurrentValues.Add(paramDiscreteValue);
//把 paramField 添加到 paramFields
paramFields.Add(paramField);
}
if (chbPhone.Checked)
{
columnNo++;
if (query.Contains("Column"))
{
query = query.Insert(query.Length, ", ");
}
query = query.Insert(query.Length, "Phone as Column" + columnNo.ToString());
paramField = new ParameterField();
paramField.Name = "col" + columnNo.ToString();
paramDiscreteValue = new ParameterDiscreteValue();
paramDiscreteValue.Value = "Phone";
paramField.CurrentValues.Add(paramDiscreteValue);
//把 paramField 添加到 paramFields
paramFields.Add(paramField);
}
//如果还有其他参数,为它们赋空值(empty value)
for (int i = columnNo; i < 5; i++)
{
columnNo++;
paramField = new ParameterField();
paramField.Name = "col" + columnNo.ToString();
paramDiscreteValue = new ParameterDiscreteValue();
paramDiscreteValue.Value = "";
paramField.CurrentValues.Add(paramDiscreteValue);
//把 paramField 添加到 paramFields
paramFields.Add(paramField);
}
crystalReportViewer1.ParameterFieldInfo = paramFields;
query += " FROM Customer" ;
return query;
}
//
6. 添加下列方法到预览报表按钮的 click 事件代码中,以便于在用户按下此按钮时显示报表
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.ReportSource;
using CrystalDecisions.Shared;
using CrystalDecisions.Windows.Forms;
namespace app5
{
public partial class Form1 : Form
{
CrystalReport1 objRpt;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
objRpt = new CrystalReport1();
string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\db1.mdb";
//取 Select 查询字符串,并添加参数到水晶报表
string query = CreateSelectQueryAndParameters();
//如果没有选定项,则退出
if (!query.Contains("Column"))
{
MessageBox.Show("No selection to display!");
return;
}
try
{
OleDbConnection Conn = new OleDbConnection(connString);
OleDbDataAdapter adepter = new OleDbDataAdapter(query, connString);
DataSet1 Ds = new DataSet1();
adepter.Fill(Ds, "Customer");
objRpt.SetDataSource(Ds);
crystalReportViewer1.ReportSource = objRpt;
}
catch (OleDbException oleEx)
{
MessageBox.Show(oleEx.Message);
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message);
}
}
本文转自 qianshao 51CTO博客,原文链接:http://blog.51cto.com/qianshao/203440,如需转载请自行联系原作者