Reporting Services 简介 (三) 数据区域 (Data Region)

by Lujun 22. July 2009 15:14

报表中有一个概念叫数据区域 (Data Region), 数据区域包括一系列报表控件: 表(table), 矩阵(Matrix),列表(list) 和图表(chart).这些数据区域主要用来绑定数据集, 来显示来自数据集的多行数据。

table 控件.table 控件由许多部分组成, 包括:表头(table header),组头(group header), 详细信息(table detail), 组尾(group footer), 表尾(table footer)等。如图所示:

Table 控件是我们呈现报表的主要方式, 在这里我需要指出的是, 对于任何数据区域控件, 在他的位置是受到一定限制的, 如不能出现在详细信息,页眉和页脚中。同时, 值得注意的是, 当数据区域控件放在Table控件或Matrix空间的表头/表尾或组头/组尾时, 导出的Excel 将" 忽略表/矩阵单元内的数据区域。"

从工具箱中拖出一个Table 控件, 我们首先就是要对表属性进行设置。

将表绑定到数据集, 所有的数据区域控件都需要绑定到数据集才能呈现数据。 其他设置在制作报表的时候就可以很快掌握。

默认情况下, Table控件是没有组的, 可以通过插入组对数据进行分组。如图所示:

Table控件是由许多个Table Cell组成, 而没个Table Cell就是一个Text Box 控件, Text Box控件属于非数据区域控件,不需要绑定数据集。

Matrix 控件

Matrix 控件最主要是呈现交叉表数据(cross table)。由Corner, Dynamic Row Group Header, Dynamic Columns Group Header, Static Group Headers 和 Details Cells 组成, 如图所示:

List 控件

如果报表中不需要像表格这么整齐排列的数据区域, 我们就可以选择List 控件, 在List 控件中数据布局十分灵活, 无论是数据区域控件还是非数据区域空间都可以放置在其中。 如果需要将分组显示的组头信息与详细信息对齐显示,就可以在List控件中放置Table 控件,如图所示:

Chart 控件

Chart 控件主要是通过绑定数据集, 用chart图表的形式呈现数据,入图所示:

我们可以选择各种各样的图表呈现方式, 例如:柱形图, 条形图, 面积图,折线图,饼图等。但是这个控件功能还是太简单了, 不能满足客户许多复杂的需求。 通常, 在报表中加图表我们是通过第三方控件(TeeChart)生成图表图片, 然后再将图片加载到报表中以实现特殊的功能。.Net 3.5以后,我想这个第三方控件已经不需要了, 因为微软已经发布了.NET 3.5框架下的图表控件,如图所示:

ABM, SHO项目中大量使用了图表控件。 以后如果升级到.Net3.5, 强烈推荐微软的图表控件, 开发十分方便, 而且与ajax技术结合, 会带来友好用户体验。

Tags:

报表开发

使用Linq to XML来将hardcode在reporting services报表里的label文字变成从数据库取值

by Huangyao 17. July 2009 16:36

最近在做一个任务item, 要求检查reporting services(2003/2005)格式的报表里hard code的label,并把它们变成从数据库的表里拿出来用, 当时要求是先一个报表, 我想,如果有好多报表,纯用手工来做,不累死才怪,学过一下.net3.5里的linq to XML的特性,好,就用这个来实现。

首先得有一个思路, 大家都知道micorsoft的reporting services无论2003或2005的rdl文件实际上就是一个XML文件,里边的节点格式大致相同, label在xml里都是<textbox>…</textbox>

思路:

1.       找出所有textbox

2.       找出这些textbox的内容里有hardcode中文或英文(用各自的正则表达式来匹配, 本例子只找英文的)

3.       自动根据需要生成不重复的label id给这个hardcode的label, 根据资源表结果生成insert语句

4. 将report的xml内容里hard code的地方,替换成刚加入的label id

5. 原本还可以在DataSets节点下找到取label的存储过程,为它加上新加的field, 不过算了,还不如直接打开报表,刷新一下数据源.

 

代码如下:
view plaincopy to clipboardprint?
private void button1_Click(object sender, EventArgs e)  
{  
    //  
    XNamespace ns = "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition";  
    if (File.Exists("output2.txt"))  
    {  
        File.Delete("output2.txt");  
    }  
 
    using (FileStream fs = File.Open("output2.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))  
    {  
        XNamespace ns2 = "urn:schemas-microsoft-com:office:spreadsheet";  
        XNamespace nsSS = "urn:schemas-microsoft-com:office:spreadsheet";  
 
        //File file in dir.GetFiles("*.rdl")  
        string fileName = Application.StartupPath + @"\StaffInjuryReport.rdl";  
        XElement eleReport = XElement.Load(fileName);  
 
        //Regex reg = new Regex(@"[<]Value[>][^=]*[<]/Value[>]");  
        Regex reg = new Regex(@"[<]Value[>][^=]*[<]/Value[>]");  
          
        IEnumerable<XElement> tbList =  
                       from itemField in eleReport.Descendants(ns + "Textbox")  
                       //where reg.IsMatch( itemField.Elements(ns + "Value").First().Value) == true  
                       select itemField;  
 
        string lineStr = "";  
        string hardCodeString = "";  
        string reportLabelID = "";  
        string needReplaceValue = "";  
        System.Text.StringBuilder sb = new StringBuilder();  
        Dictionary<string, string> existsDict = new Dictionary<string, string>();  
        Dictionary<string, string> existsLabelIdDict = new Dictionary<string, string>();  
        int duplicateLabelIdIndex = 0;  
        //INSERT INTO ODM_CDReportLabel ([ReportLabelID],[Code1],[Code2],[Code3],[ReportID],[Version]) VALUES ('lblAccident',N'Accident',N'意外',N'意外',N'ODMStaffInjury','KKKK')  
        foreach (var item in tbList)  
        {  
            //reportLabelID = (string)item.Element(ns + "DataField");  
            //----------------1.-  
            hardCodeString = string.IsNullOrEmpty((string)item.Element(ns + "Value")) ? "" : (string)item.Element(ns + "Value");  
            if (hardCodeString.Length > 0)  
            {  
                //string ss = item.Value;  
                //----begin-----------hardcode了英文的-------------------------------------------------------------  
                if (reg.IsMatch(item.ToString()))  
                {  
                    //判断是否已存在于这次已找出的结果里  
                    if (existsDict.Values.Contains(hardCodeString))  
                    {  
                        reportLabelID = existsDict.Where(ca => ca.Value == hardCodeString).First().Key;  
                    }  
                    else 
                    {  
                        //reportLabelID = "";  
                        //hardCodeString = "";  
 
                        reportLabelID = "lbl" + (hardCodeString.Length < 5 ? hardCodeString.Replace(" ", "") : hardCodeString.Substring(0, 5).Replace(" ", ""));  
                        reportLabelID = reportLabelID.Replace("'", "").Replace(":", "").Replace(".", "").Replace("Ⅰ", "").Replace("&", "").Replace("'", "").Replace("II", "").Replace(")", "").Replace("(", "");  
                        //DB  
                        if (this.oMISDBDataSet.ODM_CDReportLabel.Count > 0)  
                        {  
                            if (this.oMISDBDataSet.ODM_CDReportLabel.Where(ca => ca.ReportLabelID == reportLabelID).Any())  
                            {  
                                reportLabelID = reportLabelID + "ForStaffInjury";  
                            }  
                        }  
 
                        //再判断reportLabelID有没有重复的  
                        //existsLabelIdDict  
                        if (existsLabelIdDict.Values.Contains(reportLabelID))  
                        {  
                            reportLabelID = reportLabelID + duplicateLabelIdIndex.ToString();  
                        }  
 
                        lineStr = @"INSERT INTO ODM_CDReportLabel ([ReportLabelID],[Code1],[Code2],[Code3],[ReportID],[Version]) VALUES ('" 
                            + "" + reportLabelID + "'" 
                            + ",N'" + hardCodeString.Replace("'", "''")  + "'" 
                            + ",N'" + hardCodeString.Replace("'", "''") + "'" 
                            + ",N'" + hardCodeString.Replace("'", "''") + "'" 
                            + ",N'ODMStaffInjury'" 
                            + ", 'MTRC')" 
                            + "\r\n";  
                        Byte[] info = new UTF8Encoding(true).GetBytes(lineStr);  
                        // Add some information to the file.  
                        fs.Write(info, 0, info.Length);  
 
                        sb.Append("'" + reportLabelID + "',");  
                        existsLabelIdDict.Add(reportLabelID, reportLabelID);  
                        existsDict.Add(reportLabelID, hardCodeString);  
                    }  
                      
                    //--------------------------2.--  
                    //<Value>=First(Fields!Wasmahcineinmotion.value, "GetRptLabel")</Value>  
                    //replace  
                    needReplaceValue = "=First(Fields!" + reportLabelID  + ".value, \"GetRptLabel\")";  
                    item.Element(ns + "Value").Value = needReplaceValue;  
                }  
 
                //----end-----------hardcode了英文的-------------------------------------------------------------  
            }  
 
            duplicateLabelIdIndex ++;  
        }  
 
        Byte[] info2 = new UTF8Encoding(true).GetBytes(sb.ToString());  
        fs.Write(info2, 0, info2.Length);  
 
        eleReport.Save("StaffInjuryReport_FinishedReplace.rdl");  
 
        MessageBox.Show("finished!");  
    }  

        private void button1_Click(object sender, EventArgs e)
        {
            //
            XNamespace ns = "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition";
            if (File.Exists("output2.txt"))
            {
                File.Delete("output2.txt");
            }

            using (FileStream fs = File.Open("output2.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
            {
                XNamespace ns2 = "urn:schemas-microsoft-com:office:spreadsheet";
                XNamespace nsSS = "urn:schemas-microsoft-com:office:spreadsheet";

                //File file in dir.GetFiles("*.rdl")
                string fileName = Application.StartupPath + @"\StaffInjuryReport.rdl";
                XElement eleReport = XElement.Load(fileName);

                //Regex reg = new Regex(@"[<]Value[>][^=]*[<]/Value[>]");
                Regex reg = new Regex(@"[<]Value[>][^=]*[<]/Value[>]");
               
                IEnumerable<XElement> tbList =
                               from itemField in eleReport.Descendants(ns + "Textbox")
                               //where reg.IsMatch( itemField.Elements(ns + "Value").First().Value) == true
                               select itemField;

                string lineStr = "";
                string hardCodeString = "";
                string reportLabelID = "";
                string needReplaceValue = "";
                System.Text.StringBuilder sb = new StringBuilder();
                Dictionary<string, string> existsDict = new Dictionary<string, string>();
                Dictionary<string, string> existsLabelIdDict = new Dictionary<string, string>();
                int duplicateLabelIdIndex = 0;
                //INSERT INTO ODM_CDReportLabel ([ReportLabelID],[Code1],[Code2],[Code3],[ReportID],[Version]) VALUES ('lblAccident',N'Accident',N'意外',N'意外',N'ODMStaffInjury','KKKK')
                foreach (var item in tbList)
                {
                    //reportLabelID = (string)item.Element(ns + "DataField");
                    //----------------1.-
                    hardCodeString = string.IsNullOrEmpty((string)item.Element(ns + "Value")) ? "" : (string)item.Element(ns + "Value");
                    if (hardCodeString.Length > 0)
                    {
                        //string ss = item.Value;
                        //----begin-----------hardcode了英文的-------------------------------------------------------------
                        if (reg.IsMatch(item.ToString()))
                        {
                            //判断是否已存在于这次已找出的结果里
                            if (existsDict.Values.Contains(hardCodeString))
                            {
                                reportLabelID = existsDict.Where(ca => ca.Value == hardCodeString).First().Key;
                            }
                            else
                            {
                                //reportLabelID = "";
                                //hardCodeString = "";

                                reportLabelID = "lbl" + (hardCodeString.Length < 5 ? hardCodeString.Replace(" ", "") : hardCodeString.Substring(0, 5).Replace(" ", ""));
                                reportLabelID = reportLabelID.Replace("'", "").Replace(":", "").Replace(".", "").Replace("Ⅰ", "").Replace("&", "").Replace("'", "").Replace("II", "").Replace(")", "").Replace("(", "");
                                //DB
                                if (this.oMISDBDataSet.ODM_CDReportLabel.Count > 0)
                                {
                                    if (this.oMISDBDataSet.ODM_CDReportLabel.Where(ca => ca.ReportLabelID == reportLabelID).Any())
                                    {
                                        reportLabelID = reportLabelID + "ForStaffInjury";
                                    }
                                }

                                //再判断reportLabelID有没有重复的
                                //existsLabelIdDict
                                if (existsLabelIdDict.Values.Contains(reportLabelID))
                                {
                                    reportLabelID = reportLabelID + duplicateLabelIdIndex.ToString();
                                }

                                lineStr = @"INSERT INTO ODM_CDReportLabel ([ReportLabelID],[Code1],[Code2],[Code3],[ReportID],[Version]) VALUES ('"
                                    + "" + reportLabelID + "'"
                                    + ",N'" + hardCodeString.Replace("'", "''")  + "'"
                                    + ",N'" + hardCodeString.Replace("'", "''") + "'"
                                    + ",N'" + hardCodeString.Replace("'", "''") + "'"
                                    + ",N'ODMStaffInjury'"
                                    + ", 'MTRC')"
                                    + "\r\n";
                                Byte[] info = new UTF8Encoding(true).GetBytes(lineStr);
                                // Add some information to the file.
                                fs.Write(info, 0, info.Length);

                                sb.Append("'" + reportLabelID + "',");
                                existsLabelIdDict.Add(reportLabelID, reportLabelID);
                                existsDict.Add(reportLabelID, hardCodeString);
                            }
                           
                            //--------------------------2.--
                            //<Value>=First(Fields!Wasmahcineinmotion.value, "GetRptLabel")</Value>
                            //replace
                            needReplaceValue = "=First(Fields!" + reportLabelID  + ".value, \"GetRptLabel\")";
                            item.Element(ns + "Value").Value = needReplaceValue;
                        }

                        //----end-----------hardcode了英文的-------------------------------------------------------------
                    }

                    duplicateLabelIdIndex ++;
                }

                Byte[] info2 = new UTF8Encoding(true).GetBytes(sb.ToString());
                fs.Write(info2, 0, info2.Length);

                eleReport.Save("StaffInjuryReport_FinishedReplace.rdl");

                MessageBox.Show("finished!");
            }
        }
后记: linq to XML比以前的xml操作方法方便太多了, 当然可以更自动,遍历多文件之类的,但这种方便的小程序,够用就好, 纯碎是一种方法论.

 

Tags:

报表开发

Reporting Services 简介 (二) 文本框

by Lujun 15. July 2009 14:09

报表文本框是制作报表中最常见的工具,在此我简单介绍一下他的功能和特性。

文本框的值

 

在文本框中我们可以填写字符串, 也可以加入全局变量, 参数, 数据集字段.

在文本框中加入字符串(报表标题):

在文本框中加入全局变量 (打印时间,打印用户,报表页数):

在reporting services 中, 有8中全局变量:

ExecutionTime:报表生成时间

PageNumber:报表当前页

ReportFolder:报表文件夹

ReportName:报表文件名

ReportServerUrl:报表所在服务器url

TotalPages:报表总页数

UserID:执行报表的用户

Language:执行报表客户端的语言ID

其中, PageNumber 与 TotalPages 全局变量只能在页眉与页脚中使用, ReportFolder 与ReportServerUrl 全局变量只有在报表发布到报表服务器上以后, 才能显示.

在报表中加入打印时间,格式为"yyyy-MM-dd"

在报表中加入打印用户:

在报表中加入报表页数:

在文本框中加入参数(报表标题):

将报表标题改成根据参数的变化而变化

 

在文本框中加入数据集字段:

在报表页眉,页脚是不能加入数据集字段文本框的。

 

文本框属性

 

文本框"CanGrow"属性

默认情况下, "CanGrow"的值是 true , 当文本框的值大于文本框本身的长度时,文本框将自动调整自身的长度,以容纳更多的值

文本框显示check box, radio button

在我们设计报表中, 有些表单报表需要在报表中显示check box, radio button,这种情况我们该如何做呢, 难道需要嵌入图片以达到这种效果吗?

其实设置文本框的格式就能实现这种效果。

注意字体(机器中存在相应的字体)中选择"Wingdings"或"Wingdings2"(Wingdings字体是一种将字母与图形相关联的字体)。

Tags:

报表开发

Reporting Services 简介 (一) – 创建一个新报表

by Lujun 9. July 2009 11:40

制作报表是一个烦琐及复杂的工程, 目前公司许多项目都或多或少的用到reporting services 或者 crystal report 去制作报表. 这些开发工具各有各的特点,我将分几部分将我的开发经验分享给大家, 希望大家能够参与进来展开讨论,发表自己的意见与见解, 如果有讲得不对的地方, 希望大家多批评指正. 现在我们步入正题.

首先, 我先来简单介绍一下Reporting Services. Microsoft Reporting Service是一个完整的基于服务器的平台,可以建立、管理、发布传统的基于纸张的报表或者交互的、基于Web的报表。而且最大的特色是,它采用基于XML的RDL报表描述语言来定制报表,可以用于给第三方定制开发符合接口标准的报表工具,使得软件开发人员和企业可以将报表集成到已有的系统或第三方的应用中. Reporting Service可以连接到不同的数据库,如SQL Server,Oracle,DB2等,也可以将报表导出到pdf,Html.,txt,Excel等多种格式。而且,Reporting Server还可以将报表以XML WebService的形式对外发布,很容易地与企业的其他系统进行集成,而且,对于报表的使用者,制作者和管理者,都可以很方便地管理报表。

Reporting Services 的技术架构

制作一张漂亮的报表,其实十分费功夫, 需要有耐心. 对于一些简单的操作我就不再讲述了,我主要讲讲创建一个新报表需要做的工作。

首先, 在制作一张报表前, 我们需要先确立他的数据源, 报表的数据源连接支持广泛的数据源 : Microsoft SQL Server Oracle 数据库任何与ODBC 或 OLE DB 兼容的数据源

请注意,如果需要修改连接数据库的timeout, 可以选择 "高级" 进行编辑.

然后,我们就可以创建报表了.我们在创建的报表上, 添加数据集来获得数据.(这里的命令类型包括"text", "stored procedure". 为了方便维护,实际的项目开发最好用"stored procedure")

在开始制作报表之前,我们需要对报表页面进行设置, 这样避免在报表打印的时候, 出现空页, 断页的现象.

 

设置请遵循以下规则

 

页宽

页高

主体宽度

主体高度

A4 纵向

21cm

29.7cm

页宽-左右边距

页高-左右边距-页眉-页脚

A4横向

29.7cm

21cm

页宽-左右边距

页高-左右边距-页眉-页脚

 

现在,开发一个报表所需要准备的工作都做好了, 下一讲,我将具体讲讲各个报表工具的特性。

Tags:

报表开发

Copyright © 2009 APJ Software

最新评论

Comment RSS

公告

欢迎使用APJ Blog!

日历

<<  February 2012  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
2728291234
567891011

View posts in large calendar