这两天学习如何生成动态水晶报表,看了网上的一些资料,觉得讲得都不是很详细。今天晚上做一个小的实例,算是对这两天学习的总结吧。
先让我们来看一下现实现的步骤:
一、新建一个项目:
二、向项目中添加 Crystal 报表和 DataSet 数据集,报表使用专家向导,在 DataSet 数据集中添加一个表,为表添加八列,都使用默认名。
三、为CrystalReport1 设置数据库字段与参数字段。
四:实现代码:
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.ReportSource;
using CrystalDecisions.Shared;
using CrystalDecisions.Windows.Forms;
/**/ /**/ /**/ /// <summary>
/// 动态生成水晶报表
///
/// 王稳嵩
///
/// 2007-10-23
/// </summary>
namespace WindowsApplication4
... ... {
public partial class Form1 : Form
......{
CrystalReport1 CrystalReport11;
ParameterFields paramFields; //定义一个参数字段集对象
ParameterField paramField; //定义一个参数字段列表对象
ParameterDiscreteValue paramDiscreteValue; //定义离散值参数对象
DataSet1 ds1;
SqlConnection conn = new SqlConnection("server=(local);Integrated Security = SSPI; database = Northwind");
public Form1()
......{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
......{
this.cmbSqlstring.Items.Add("select orderid,customerid from orders");
this.cmbSqlstring.Items.Add("select * from Orders");
this.cmbSqlstring.Items.Add("select * from Products");
this.cmbSqlstring.Items.Add("等等");
}
private void butQuery_Click(object sender, EventArgs e)
......{
if (this.cmbSqlstring.Text != "")
......{
if (this.cmbSqlstring.Text == "等等")
......{
MessageBox.Show("兄弟您可真幽默,没有这样的sql语句吧");
return;
}
this.dataGridView1.Columns.Clear();
try
......{
SqlDataAdapter da = new SqlDataAdapter(this.cmbSqlstring.Text.Trim(), conn);
ds1 = new DataSet1();
da.Fill(ds1, "DataTable1");
for (int i = 1; i < 9; i++)
......{
ds1.Tables[0].Columns.Remove("Column" + i.ToString()); //删除 DataSet1 数据集中的 预定义表 DataTable1 中预定义的8列 columns1 ……;
}
this.dataGridView1.DataSource = ds1.Tables[0];
}
catch (SqlException sqlEX)
......{
MessageBox.Show(sqlEX.Message);
}
catch (Exception Ex)
......{
MessageBox.Show(Ex.Message);
}
}
else
......{
MessageBox.Show("sql语句不能为空");
}
}
private void butPrint_Click(object sender, EventArgs e)
......{
try
......{
if (this.dataGridView1.DataSource != null)
......{
paramFields = new ParameterFields();
if (this.ds1.Tables[0].Columns.Count >= 8)
......{
//查询结果中表的列数大于等于八列时
for (int i = 1; i < 9; i++)
......{
paramField = new ParameterField();
paramField.Name = "col" + i.ToString(); //设置对象参数字段对象名
paramDiscreteValue = new ParameterDiscreteValue();
paramDiscreteValue.Value = ds1.Tables[0].Columns[i - 1].ColumnName; //设置对象paramDiscreteValue 的值,报表预览中指定的列名
ds1.Tables[0].Columns[i - 1].ColumnName = "Column" + i.ToString(); //修改 ds1 中 DataTable1 中的列名
paramField.CurrentValues.Add(paramDiscreteValue); //添加paramDiscreteValue到paramfield实例中
paramFields.Add(paramField); //添加到参数字段集中
}
}
else
......{
//查询结果中表的列数小于八时
for (int i = 1; i < this.ds1.Tables[0].Columns.Count + 1; i++)
......{
paramField = new ParameterField();
paramField.Name = "col" + i.ToString();
paramDiscreteValue = new ParameterDiscreteValue();
paramDiscreteValue.Value = ds1.Tables[0].Columns[i - 1].ColumnName;
ds1.Tables[0].Columns[i - 1].ColumnName = "Column" + i.ToString();
paramField.CurrentValues.Add(paramDiscreteValue);
paramFields.Add(paramField);
}
// 为因查询表列数小于八,以CrystalReport1中设定的八个参数字段不能完匹配,所以要为没有匹配的参数字段赋空值
for (int i = this.ds1.Tables[0].Columns.Count + 1; i < 9; i++)
......{
paramField = new ParameterField();
paramField.Name = "col" + i.ToString();
paramDiscreteValue = new ParameterDiscreteValue();
paramDiscreteValue.Value = "";
paramField.CurrentValues.Add(paramDiscreteValue);
paramFields.Add(paramField);
}
}
CrystalReport11 = new CrystalReport1();
CrystalReport11.SetDataSource(ds1); //为CrystalReport11 设置数据源
crystalReportViewer1.ParameterFieldInfo = paramFields; //获取或设置参数字段集合。
crystalReportViewer1.ReportSource = CrystalReport11;
}
else
......{
MessageBox.Show("还没查询出数据");
}
}
catch (Exception Ex)
......{
MessageBox.Show(Ex.Message);
}
}
}
}
五:效果
总结:
首先建立一个数据集模板,然后建立一个水晶报表,将数据集模板与水晶报表的数据库字段建立连接,再为水晶报表设计打印模式,利用参数字段改变打打印时的列名,最后为水晶报表填充数据源。要注意的是当我们为数据集定义了一个模板之后,在使用数据适配器填充数据的时,不为数据集新增了一个表,所以在填充数据的时候一定要指定要填充的模板表名,而且要删除原来的定义的模板列。
本例中最重要的是用到了:
ParameterFields //包含报表中的每个参数字段的 ParameterField 对象。
ParameterField //提供属性,以便检索和设置参数字段的选项和值。
ParameterDiscreteValue //提供属性,以便检索和设置离散值参数。
利用这三个类为先前设置的报表模板中改变参数字段的属性。比如可以预先设计不同列数量的水晶报表模板,这样可以在打印不同列数时列宽合适分配。还有因为我也是刚刚学习水晶报表,所以还不是很理解VS.net 2005 提供的报表模型,所以希望还能和大家一起学习。
程序下载 http://download.csdn.net/source/269184
参考资料 http://www.msproject.cn/article/DynamicCrystalReport.aspx
感谢: manjula.prasanna.