此片博文是在你有一定水晶报表基础的前提下参阅的;如果对于水晶报表的基础知识比较薄弱建议先去了解下水晶报表;

  因为项目需要,研究了下水晶报表。说实在,这个组件很强大,但是用起来也很麻烦。刚开始使用遇到了老多问题。然后上了搜索引擎搜索。但是我发现,有一个很痛疼的问题。那就是现在搜索引擎搜索到的东西都是COPY的。大家到处复制别人的答案,却连测试都不测试就贴上了,然后一搜索出来的都是千篇一律的东西。要找到正确的解决方案真的是一件很痛苦的事。我不知道你们有没有这样的经理。反正我经常是这样。所以也萌生了自己写帖子的想法。把自己遇到的问题的解决方案写出来。但是因为水平有限,所以可能也会存在很多问题。希望大家多多谅解。多多提出;

  好了 进入今天的主题。所谓通用报表,我们来模拟一个需求:现在需要做个报表。这个报表要实现的功能是。配置一个配置文件,配置好要显示的数据表,和数据字段,配置好每个字段在报表中的显示宽度,配置好报表数据要按那个字段的什么排序方式排序;这样,我就只需要一个报表就能显示不同的表的数据,并且可以根据字段数据的长度设置报表中列的宽度;其实这里的通用也是有点牵强的。为什么牵强看下面的解决方案就知道了。

  解决方案:通用报表是一个很强大的组件。所以其实很多东西都是我们还为挖掘的。那么通用报表怎么实现呢。我的想法是。先在报表上放一堆公式字段,或者文本对象。然后通过代码,设置每个公式字段(报表的列)的宽度和左边偏移量;而要按照配置文件的需求则可以获取配置文件的条件,然后组合成为sql语句。获取数据填充到一个dataset中。在将这个dataset作为报表的数据源;就可以实现了;

  第一步:

  假设我的报表最多有10列;那么我需要创建一个DataSet.xsd文件。然后创建一张表;

  问题:为什么一定要创建这个文件,代码中创建一个DataSet可不可以?

  水晶报表在初始化的时候,需要关联已个数据源,这个数据源哪怕没有数据也没关系,关联数据源有两种方式。一是直接和数据库的表关联,二就是像我们这样创建一个DataSet.xsd文件,然后与这个DataSet.xsd文件关联;

  如果没有用任何一种关联的话,会提示:

  该报表不包含表。

  说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。   

  异常详细信息: CrystalDecisions.CrystalReports.Engine.DataSourceException: 该报表不包含表。

  所以如果不创建创建DataSet文件,而是代码中创建一个DataSet,那么就没有关联数据源,会报如上错误;

  接着讲:新增项创建一个DataSet.xsd后,右键新增一张表:然后在表上右键新增列,完事后如下

  asp.net实现通用水晶报表

  然后与报表关联:

asp.net实现通用水晶报表

第二步:创建水晶报表;然后右键公式字段,新增公式字段。然后把公式字段放到报表上,最后结果如下。

asp.net实现通用水晶报表

然后右键每个公式字段,选择设置对象个数,修改里面的对象名称,这里的对象名称是代码要使用的。建议设置成如:colu1,colu2....colu10  这样在代码中可以用循环来找到每个公式字段!

这里的公式字段我是为每个设置类单线边框,样式可能不是很好看。你也可以自己画线。这个下面的字报表会讲到;

 

第三步:创建页面,然后在页面上拉个水晶报表的控件

asp.net实现通用水晶报表

创建完后 有人可能不想要左边的这个组树。水晶报表的版本不一样。可能设置也不一样。我这个是10的。设置方式是将下面的属性改为none;

asp.net实现通用水晶报表

asp.net实现通用水晶报表

水晶报表的工具栏很多也是可以去掉的,然后在右上角会有个微标,点击会跳到该组件的官网,可以通过设置属性:

asp.net实现通用水晶报表

  接着是创建配置文件

  

<?xml version="1.0" encoding="utf-8" ?>
<ConfigManage>
<Config ID="1">
  <TableName Title="系统日志报表">SYS_Log</TableName>
  <OrderBy Order="desc">logid</OrderBy>
  <Fields>
    <Field ChinesName="编号" IsShow="true" Width="1800">logid</Field>
    <Field ChinesName="日志类别" IsShow="true" Width="1800">logtype</Field>
    <Field ChinesName="用户编号" IsShow="true" Width="1800">userid</Field>
    <Field ChinesName="日志内容" IsShow="true" Width="1800">logcontent</Field>
    <Field ChinesName="操作用户名" IsShow="true" Width="1800">username</Field>
    <Field ChinesName="操作用户名" IsShow="true" Width="1800">username</Field>
  </Fields>
</Config>
</ConfigManage>

 

 

 

  然后就是为报表设置数据源和控制列宽的代码了。 

/// <summary>
        /// 获取配置文件的配置信息配置报表
        /// </summary>
        public void GetData()
        {
    
            string Path = "";
            string reportPath = "";
            string tablename = "";//表名称
            string OrderKey = "";//排序的字段
            string Order = "";//按什么排序
            string title = "";//报表标题
            bool Separate = true;//显示页是分页还是连接
            string serch = "";//筛选条件
            Path = Server.MapPath("Config/ReportConfig.xml");
            reportPath = Server.MapPath("CrystalReport3.rpt");

            #region 获取配置文件的信息
            XmlDocument document = new XmlDocument();
            document.Load(Path);
            XmlNodeList NodeList = document.GetElementsByTagName("TableName");
            if (NodeList != null && NodeList.Count > 0)
            {
                tablename = NodeList[0].InnerText;
                title = NodeList[0].Attributes["Title"].Value;
            }
            else
            {
                return;
            }
            NodeList = document.GetElementsByTagName("OrderBy");
            if (NodeList != null && NodeList.Count > 0)
            {
                OrderKey = NodeList[0].InnerText;
                Order = NodeList[0].Attributes["Order"].Value;
            }
            else
            {
                return;
            }
            NodeList = document.GetElementsByTagName("Field");
            string fields = "";
            if (NodeList != null && NodeList.Count > 0)
            {
                foreach (XmlNode node in NodeList)
                {
                    if (node.InnerText != "")
                    {                       
                        fields += node.InnerText + ",";
                    }
                }
            }
            else
            {
                return;
            }
            #endregion
            if (fields.Length > 0)
            {
                fields = fields.Substring(0, fields.Length - 1);
                string sql = "select " + fields + " from " + tablename + " " + serch + " order by " + OrderKey + " " + Order;
                DataSet ds = new Maticsoft.BLL.CommonClass().Query(sql);


                if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                {
                    ReportDocument myReport = new ReportDocument();
                    myReport.Load(reportPath);
                    DataTable dtx1 = new clsDyCrystalReportCore().dtx(ds.Tables[0]);
                    int left = 100;
                    #region 设置每列显示的数据和宽度
                    for (int i = 0; i < NodeList.Count; i++)
                    {
                        //设置公式字段对应的数据库字段
                        myReport.DataDefinition.FormulaFields["colu" + (i + 1).ToString()].Text = "{CryReport.colu" + (i + 1) + "}";
                        //设置公式字段的文本
                        myReport.DataDefinition.FormulaFields["mt" + (i + 1).ToString()].Text = "\"" + NodeList[i].Attributes["ChinesName"].Value + "\"";
                        //设置宽度和左边偏移量
                        FieldObject fo;
                        fo = (FieldObject)myReport.ReportDefinition.ReportObjects["colu" + (i + 1)];
                        //fo.Height = 567 * 3;                 
                        int width = int.Parse(NodeList[i].Attributes["Width"].Value);
                        fo.Width = width;
                        fo.Left = left;
                        fo.Top = 30;
                        fo = (FieldObject)myReport.ReportDefinition.ReportObjects["mt" + (i + 1)];
                        //fo.Height = 567 * 3;
                        fo.Width = width;
                        fo.Left = left;
                        fo.Top = 760;
                        left += width+100;
                        
                    }
                    #endregion
                    HideColu(NodeList.Count, myReport);
                    myReport.DataDefinition.FormulaFields["title"].Text = "\"" + title + "\"";
                    //myReport.Database.Tables[0].ApplyLogOnInfo(GetConnectionInfo());//设置报表数据库连接信息
                    myReport.SetDataSource(dtx1);
                    CrystalReportViewer1.SeparatePages = Separate;
                    CrystalReportViewer1.ReportSource = myReport;
                    CrystalReportViewer1.DataBind();
                    CrystalReportViewer1.RefreshReport();
                }
            }

        }                
View Code

相关文章:

  • 2022-01-26
  • 2022-01-10
  • 2021-09-11
  • 2021-09-14
  • 2021-07-10
  • 2021-08-04
猜你喜欢
  • 2022-12-23
  • 2021-06-04
  • 2022-12-23
  • 2022-12-23
  • 2021-06-10
相关资源
相似解决方案