引用:海风吹的专栏
Code
在做报表项目时,有时不仅要满足用户的需求,而且要求软件要有一定的适应性,这就往往就要求报表要动态地生成.
最近在做一个项目时,就碰到这样子的问题.系统要在不现的地区使用,不同的地区下属单位是不一样的,而报表中有列就是显示下属单位的某一属性的.因而报表中的这一项不公名称不能确定,数目也不能定.所以它要求在生成过程中动态地改变报表中的格式.
这个项目是用.NET的C#开发的,报表用微软的RDLC模板报表.
RDLC 是用XML文档定义报表格式,这样就很容易想到通过更改XML文档元素内容来实现这一需求.
报表中实现了多列表头以及向报表中动态添加列增加参数据等内容.
使用方法:
private void ProressAllXiangZhen()
{
string sql = null;
string filename = Application.StartupPath + "\\ChecksMonthAll.rdlc";//报表定义文件地址
ReportXml Rex = new ReportXml(destname);//创建XML操作对象
XiangZhenEx xz = new XiangZhenEx();//强类型数据集
xz = (new XiangZhenBL()).GetAllXiangZhen();
//根据数据表值,修改报表格式
foreach (DataRow row in xz._XiangZhen.Rows)//每镇增加两列当月所得及年累计值
{
string code = row["code"].ToString();
string name = row["name"].ToString();
//系统提示
UpStatus(string.Format("设置乡镇{0}报表格式", name));
//增加参数
Rex.AddParamter("Params" + code, "String", name);
//增加字段
Rex.AddDataSetColumn("Month_" + code + "Region", "System.Decimal");
Rex.AddTableColumn("2.5cm");
Rex.AddDataSetColumn("Year_" + code + "Region", "System.Decimal");
Rex.AddTableColumn("2.5cm");
//增加表头第一行,跨列居中
Rex.AddTableHaderFirstRowCell("Heade" + code + "01", String.Format("=Parameters!{0}.Value", "Params" + code));
//增加表头第二行,加两列与上对齐
Rex.AddTableHaderSecondRowCell("Heade" + code + "0101", "当月");
Rex.AddTableHaderSecondRowCell("Heade" + code + "0102", "全年");
//增加详细数据行列
Rex.AddDetailsCell("Detail" + code + "01", String.Format("=Fields!{0}.Value", "Month_" + code + "Region"));
Rex.AddDetailsCell("Detail" + code + "02", String.Format("=Fields!{0}.Value", "Year_" + code + "Region"));
sql += "," + String.Format("dbo.Get_Month_Region('{0}',{1},{2},shui_code,{3}) as \"{4}\"", code, m_year, m_month, m_item2, "Month_" + code + "Region");
sql += "," + String.Format("dbo.Get_Year_Region('{0}',{1},{2},shui_code,{3}) as \"{4}\"", code, m_year, m_month, m_item2, "Year_" + code + "Region");
if (row["name"].ToString() == "市直" || row["name"].ToString() == "县直") AddXiangZhenHeJi(Rex, xz._XiangZhen.Rows);
}
UpStatus("调整报表宽度");
Int32 width = (xz._XiangZhen.Rows.Count+1) * 5;
Rex.EditPageHeaderTb28Width(width);
Rex.EditPageHeaderTb29Left(width);
Rex.EditPageFooterLineWidth("line1", width);
Rex.EditPageFooterLineWidth("line2", width);
sql = string.Format("select acctname,sum(money)money,bili,sum(country_get)country_get,"
+ "sum(province_get)province_get,sum(region_get)region_get,"
+ "shui_code " + sql + " from v_report_month_allzhen where "
+ "year={0} and month={1} and item IN({2})"
+ " group by shui_code,bili,acctname", m_year, m_month, m_item);
System.Diagnostics.Debug.WriteLine(sql);
UpStatus(string.Format("正在取此数据,大概需要2-3分钟"));
ReportBl BL = new ReportBl();
DataSet re = BL.GetMonthReport(sql);
UpStatus("已经取得数据,正在加载报表数据");
this.reportViewer.ProcessingMode = ProcessingMode.Local;
this.reportViewer.LocalReport.DataSources.Clear();
Microsoft.Reporting.WinForms.ReportDataSource RD = new Microsoft.Reporting.WinForms.ReportDataSource("ReportDT_v_report_month", re.Tables[0]);
this.reportViewer.LocalReport.DataSources.Add(RD);
ReportParameter[] cc = new ReportParameter[xz._XiangZhen.Rows.Count + 4];
for (int i = 0; i < xz._XiangZhen.Rows.Count; i++)//每镇增加两列当月所得及年累计值
{
DataRow row = xz._XiangZhen.Rows[i];
string code = row["code"].ToString();
string name = row["name"].ToString();
cc[i] = new ReportParameter("Params" + code, name);
}
UpStatus("设置报表参数");
this.reportViewer.LocalReport.ReportPath = destname;
cc[xz._XiangZhen.Rows.Count] = new ReportParameter("dwmc", "全县");
cc[xz._XiangZhen.Rows.Count + 1] = new ReportParameter("date", string.Format("{0}年{1}月", m_year, m_month));
cc[xz._XiangZhen.Rows.Count + 2] = new ReportParameter("shou_item", m_item.Replace('\'', ' ').Replace(',', '、'));
cc[xz._XiangZhen.Rows.Count + 3] = new ReportParameter("Params100", "乡镇小计");
this.reportViewer.LocalReport.SetParameters(cc);
UpStatus("就绪");
this.reportViewer.RefreshReport();
}
类代码示例(报表操作类ReportXML源码):
public ReportXml(string filename)
{
this.filename = filename;
doc = new XmlDocument();
doc.Load(filename);
root = doc.DocumentElement;
xnm=new XmlNamespaceManager(doc.NameTable);
xnm.AddNamespace("rd", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner");
xnm.AddNamespace("default", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
xnm.PushScope();
xpathdoc = new XPathDocument(filename);
xnv = xpathdoc.CreateNavigator();
}
private XmlNode CreateNode( string nodename, string innertext)
{
XmlNode node = null;
node = doc.CreateNode(XmlNodeType.Element, nodename, "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
node.InnerText = innertext;
return node;
}
private XmlNode CreateNode(string nodename)
{
XmlNode node = null;
node = doc.CreateNode(XmlNodeType.Element, nodename, "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
return node;
}
public void AddParamter(string name, string type, string prompt)
{
XmlNode node = null;
XmlNode refCd = root.SelectSingleNode("//default:ReportParameters", xnm);
XmlElement docFrag = doc.CreateElement("ReportParameter", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
docFrag.SetAttribute("Name",name);
node = doc.CreateNode(XmlNodeType.Element, "DataType", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
node.InnerText = type;
docFrag.AppendChild(node);
node = doc.CreateNode(XmlNodeType.Element, "Nullable", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
node.InnerText = "true";
docFrag.AppendChild(node);
node = doc.CreateNode(XmlNodeType.Element, "Prompt", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
node.InnerText = prompt;
docFrag.AppendChild(node);
refCd.InsertAfter(docFrag, refCd.LastChild);
doc.Save(filename);
}
(未完)
实现的效果图(1):
在做报表项目时,有时不仅要满足用户的需求,而且要求软件要有一定的适应性,这就往往就要求报表要动态地生成.
最近在做一个项目时,就碰到这样子的问题.系统要在不现的地区使用,不同的地区下属单位是不一样的,而报表中有列就是显示下属单位的某一属性的.因而报表中的这一项不公名称不能确定,数目也不能定.所以它要求在生成过程中动态地改变报表中的格式.
这个项目是用.NET的C#开发的,报表用微软的RDLC模板报表.
RDLC 是用XML文档定义报表格式,这样就很容易想到通过更改XML文档元素内容来实现这一需求.
报表中实现了多列表头以及向报表中动态添加列增加参数据等内容.
使用方法:
private void ProressAllXiangZhen()
{
string sql = null;
string filename = Application.StartupPath + "\\ChecksMonthAll.rdlc";//报表定义文件地址
ReportXml Rex = new ReportXml(destname);//创建XML操作对象
XiangZhenEx xz = new XiangZhenEx();//强类型数据集
xz = (new XiangZhenBL()).GetAllXiangZhen();
//根据数据表值,修改报表格式
foreach (DataRow row in xz._XiangZhen.Rows)//每镇增加两列当月所得及年累计值
{
string code = row["code"].ToString();
string name = row["name"].ToString();
//系统提示
UpStatus(string.Format("设置乡镇{0}报表格式", name));
//增加参数
Rex.AddParamter("Params" + code, "String", name);
//增加字段
Rex.AddDataSetColumn("Month_" + code + "Region", "System.Decimal");
Rex.AddTableColumn("2.5cm");
Rex.AddDataSetColumn("Year_" + code + "Region", "System.Decimal");
Rex.AddTableColumn("2.5cm");
//增加表头第一行,跨列居中
Rex.AddTableHaderFirstRowCell("Heade" + code + "01", String.Format("=Parameters!{0}.Value", "Params" + code));
//增加表头第二行,加两列与上对齐
Rex.AddTableHaderSecondRowCell("Heade" + code + "0101", "当月");
Rex.AddTableHaderSecondRowCell("Heade" + code + "0102", "全年");
//增加详细数据行列
Rex.AddDetailsCell("Detail" + code + "01", String.Format("=Fields!{0}.Value", "Month_" + code + "Region"));
Rex.AddDetailsCell("Detail" + code + "02", String.Format("=Fields!{0}.Value", "Year_" + code + "Region"));
sql += "," + String.Format("dbo.Get_Month_Region('{0}',{1},{2},shui_code,{3}) as \"{4}\"", code, m_year, m_month, m_item2, "Month_" + code + "Region");
sql += "," + String.Format("dbo.Get_Year_Region('{0}',{1},{2},shui_code,{3}) as \"{4}\"", code, m_year, m_month, m_item2, "Year_" + code + "Region");
if (row["name"].ToString() == "市直" || row["name"].ToString() == "县直") AddXiangZhenHeJi(Rex, xz._XiangZhen.Rows);
}
UpStatus("调整报表宽度");
Int32 width = (xz._XiangZhen.Rows.Count+1) * 5;
Rex.EditPageHeaderTb28Width(width);
Rex.EditPageHeaderTb29Left(width);
Rex.EditPageFooterLineWidth("line1", width);
Rex.EditPageFooterLineWidth("line2", width);
sql = string.Format("select acctname,sum(money)money,bili,sum(country_get)country_get,"
+ "sum(province_get)province_get,sum(region_get)region_get,"
+ "shui_code " + sql + " from v_report_month_allzhen where "
+ "year={0} and month={1} and item IN({2})"
+ " group by shui_code,bili,acctname", m_year, m_month, m_item);
System.Diagnostics.Debug.WriteLine(sql);
UpStatus(string.Format("正在取此数据,大概需要2-3分钟"));
ReportBl BL = new ReportBl();
DataSet re = BL.GetMonthReport(sql);
UpStatus("已经取得数据,正在加载报表数据");
this.reportViewer.ProcessingMode = ProcessingMode.Local;
this.reportViewer.LocalReport.DataSources.Clear();
Microsoft.Reporting.WinForms.ReportDataSource RD = new Microsoft.Reporting.WinForms.ReportDataSource("ReportDT_v_report_month", re.Tables[0]);
this.reportViewer.LocalReport.DataSources.Add(RD);
ReportParameter[] cc = new ReportParameter[xz._XiangZhen.Rows.Count + 4];
for (int i = 0; i < xz._XiangZhen.Rows.Count; i++)//每镇增加两列当月所得及年累计值
{
DataRow row = xz._XiangZhen.Rows[i];
string code = row["code"].ToString();
string name = row["name"].ToString();
cc[i] = new ReportParameter("Params" + code, name);
}
UpStatus("设置报表参数");
this.reportViewer.LocalReport.ReportPath = destname;
cc[xz._XiangZhen.Rows.Count] = new ReportParameter("dwmc", "全县");
cc[xz._XiangZhen.Rows.Count + 1] = new ReportParameter("date", string.Format("{0}年{1}月", m_year, m_month));
cc[xz._XiangZhen.Rows.Count + 2] = new ReportParameter("shou_item", m_item.Replace('\'', ' ').Replace(',', '、'));
cc[xz._XiangZhen.Rows.Count + 3] = new ReportParameter("Params100", "乡镇小计");
this.reportViewer.LocalReport.SetParameters(cc);
UpStatus("就绪");
this.reportViewer.RefreshReport();
}
类代码示例(报表操作类ReportXML源码):
public ReportXml(string filename)
{
this.filename = filename;
doc = new XmlDocument();
doc.Load(filename);
root = doc.DocumentElement;
xnm=new XmlNamespaceManager(doc.NameTable);
xnm.AddNamespace("rd", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner");
xnm.AddNamespace("default", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
xnm.PushScope();
xpathdoc = new XPathDocument(filename);
xnv = xpathdoc.CreateNavigator();
}
private XmlNode CreateNode( string nodename, string innertext)
{
XmlNode node = null;
node = doc.CreateNode(XmlNodeType.Element, nodename, "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
node.InnerText = innertext;
return node;
}
private XmlNode CreateNode(string nodename)
{
XmlNode node = null;
node = doc.CreateNode(XmlNodeType.Element, nodename, "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
return node;
}
public void AddParamter(string name, string type, string prompt)
{
XmlNode node = null;
XmlNode refCd = root.SelectSingleNode("//default:ReportParameters", xnm);
XmlElement docFrag = doc.CreateElement("ReportParameter", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
docFrag.SetAttribute("Name",name);
node = doc.CreateNode(XmlNodeType.Element, "DataType", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
node.InnerText = type;
docFrag.AppendChild(node);
node = doc.CreateNode(XmlNodeType.Element, "Nullable", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
node.InnerText = "true";
docFrag.AppendChild(node);
node = doc.CreateNode(XmlNodeType.Element, "Prompt", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
node.InnerText = prompt;
docFrag.AppendChild(node);
refCd.InsertAfter(docFrag, refCd.LastChild);
doc.Save(filename);
}
(未完)
实现的效果图(1):
实现的效果图(1):