使用 Business Intelligence and Reporting Tools 的提示与技巧

高级定制指南

开源的、基于 Eclipse 的 Business Intelligence and Reporting Tools 项目为诸如 DB2® Data Warehouse Edition 和 WebSphere® RFID Information Center 之类的 Information Management 产品带来了先进的报告生成能力。本文展示如何在基础功能之上进一步实现更多的功能,以满足用户社区更详细的报告需求。本文中的说明基于 BIRT V2.1.2。

Craig Tomlyn (tomlyn@us.ibm.com), 高级软件工程师, IBM

Craig Tomlyn photoCraig 在加利福尼亚州圣何塞市 IBM 硅谷实验室的 WebSphere RFID Information Center 开发小组工作。



Abdul Rasid (abdul.rasid@in.ibm.com), 软件工程师, IBM

Abdul Rasid photoAbdul 在 IBM 印度软件开发实验室的 WebSphere RFID Information Center 开发小组工作。



Yan Larsen (ylarsen@us.ibm.com), 软件工程师, IBM

Author Photo: Yan LarsenYan 在加利福尼亚州圣何塞市 IBM 硅谷实验室的 WebSphere RFID Information Center 开发小组工作。



2008 年 4 月 22 日

简介

Business Intelligence and Reporting Tools (BIRT) 项目是一个开源的、基于 Eclipse 技术的项目。BIRT 提供报告设计特性,使报告制作者可以创建可在 Web 浏览器中查看的高级报告。关于 BIRT 的详细信息,请参考 参考资料 小节中提供的 Eclipse Web 站点链接。

通过使用 BIRT 的报告设计器图形用户界面,可以实现很多报告功能。此外,BIRT 让您可以使用 JavaScript 扩展这些特性。

除了标准 BIRT 报告设计器提供的功能以外,还可以添加额外的功能到 BIRT 报告中,本文描述用于添加这些功能的一些技巧。要学习 BIRT 的基础知识,建议通过以下两本关于 BIRT 的书籍入手:BIRT A Field Guide to ReportingIntegrating and Extending BIRT,出版社均为 Addison-Wesley。

本文面向的读者是那些希望为 BIRT 报告的用户提供高级特性的解决方案开发人员。我们假设读者具备以下条件:

  • 熟悉 BIRT 报告设计器的各个方面,并且能够通过以下步骤从头开始创建报告设计:  
    • 创建数据源和数据集
    • 添加诸如网格和表之类的报告元素到设计中
    • 定制报告的样式、字体、颜色等
    • 为报告添加文本和标注
    • 指定报告的参数
  • 熟悉 JavaScript 语言,并知道如何将 JavaScript 代码插入到 BIRT 报告设计中
  • 能够将 BIRT 报告部署到 WebSphere Application Server。

下面的每一节将描述 BIRT 报告中可能需要的不同的高级特性。各节首先描述一个特性,然后描述实现该特性的步骤。每一节都独立于其他小节,所以可以单独参考。


用户可排序的单个列

描述

在查看一个报告时,用户常常希望以不同于报告设计提供的默认顺序的方式,根据表中某列的值对数据进行排序。例如,一个产品信息报告在默认情况下可能按产品名称排序,但是用户可能希望查看按交货日期排序的数据。

本节描述定制 BIRT 报告的 2 个技巧,使用户可以指定报告数据的排序顺序。

实现 – 方法 1

在这个实现中,通过修改数据集使用的 SQL 查询,将排序下推到数据库。用户通过单击要进行排序的列的标题来指定按哪个列排序。

  1. 将以下代码添加到初始化处理程序中,获得完整的报告定义。为此,打开 layout 编辑器,单击报告空白处(以避免选中报告元素),单击 Script 选项卡,在下拉列表中选择 initialize。添加代码之后,将第一行中的 dataSetName 替换为您想要对其排序的数据集的名称。
    dataSetName = "EPCLifecycleDataSet";
    sortCol     = reportContext.getHttpServletRequest().getParameter("sortCol");
    sortDir     = reportContext.getHttpServletRequest().getParameter("sortDir");
    currentURL  = reportContext.getHttpServletRequest().getRequestURL() + "?" + 
    reportContext.getHttpServletRequest().getQueryString();
    sortClause  = "";
    targetURL   = "";
    abbrSortCol = "";
    
    if (sortDir != null)
    {
      if (sortDir.indexOf("ASC") != -1)
        sortDir = "DESC";
      else
        sortDir = "ASC";
    }
    
    else
      sortDir = "ASC";
    
    if (sortCol != null && sortCol.length != 0)
    {
      sortClause = " ORDER BY " + sortCol + " " + sortDir;
      
      lastIndex = sortCol.lastIndexOf(".");
      
      if (lastIndex == -1)
        abbrSortCol = sortCol;
       
      else
        abbrSortCol = sortCol.substring(lastIndex + 1);
    }
    
    reportContext.getReportRunnable().getDesignInstance().
    getDataSet(dataSetName).queryText += sortClause;
        
    if (currentURL.indexOf("__sorting=") != -1 )
      targetURL = currentURL.substring(0, currentURL.indexOf("__sorting") - 1);
    else
      targetURL = currentURL;
        
    targetURL = targetURL + "&__sorting=true&sortDir=" + sortDir + "&sortCol=";
  2. 选中允许用户对其排序的列的列标题,如图 1 所示。
    图 1. 选中的列标题
    选中的列标题
  3. 在 Property Editor 视图中:
    1. 单击 Properties 选项卡。
    2. 从表中单击 Hyperlink
    3. 单击 Link To: 输入字段旁边的 ... 按钮。
    4. Hyperlink Options 对话框中,选择 Hyperlink Type 作为 URI
    5. 单击 Location: 输入框旁边的 ... 按钮。
    6. 在 Expression Builder 中,输入以下内容作为超级链接的表达式:
      targetURL + "VIEWSCHEMA.EPC_LIFECYCLE.EPC";
      将表达式中的列名改为关系数据库中希望根据已选的特定列进行排序的列的名称。
  4. 对于允许用户对其排序的每个列,执行步骤 2 和 3。
  5. 如果希望显示图像表明进行排序的列以及排序的方向,那么可以将以下代码添加到要排序的每个列标题的 onCreate 处理程序中。为此,在 layout 编辑器中,单击允许用户对其排序的列的列标题文本,使标题文本像前面显示的那样高亮显示。单击 Script 选项卡,然后从下拉列表中选择 onCreate,添加以下代码:
    var sortedColName = abbrSortCol;
    var sortedDirName = sortDir;
    
    if (sortedColName != null)
    {
      if (sortedColName == "EPC")
      {
        if (sortedDirName == "DESC")
          this.getStyle().backgroundImage = "images/up.gif";
        else
          this.getStyle().backgroundImage = "images/down.gif";
                
        this.getStyle().backgroundRepeat    = "no-repeat";
        this.getStyle().backgroundPositionX = "98%";
        this.getStyle().backgroundPositionY = "50%";
      }
      else
        this.getStyle().backgroundImage = null;
    }
  6. 将用于表明排序方向的图像添加到适当的图像目录中。

实现 – 方法 2

这种实现允许用户指定排序的顺序和方向(升序或降序)作为报告的参数。

  1. 创建一个数据类型为 String 的报告参数 sortColumn,并单击 Linked to Report Parameter 字段旁边的 ... 按钮。
  2. 以静态值形式添加报告中的列名。将一个列设为默认值,如图 2 所示。这些值是可对其排序的列的名称。
    图 2. 排序列
    排序列
  3. 创建一个名为 sortOrder 的报告参数,如图 3 所示,为该参数添加静态值 ascending 和 descending。将其中一个值设为默认值。
    图 3. 排序顺序
    排序顺序
  4. 在用于为报告提供数据的数据集的 beforeOpen 事件处理程序中,添加以下 JavaScript 代码。
    queryString = this.queryText;
    queryString = queryString + 
                  " order by " +
                  reportContext.getParameterValue("sortColumn") + 
                  " " + 
                  reportContext.getParameterValue("sortOrder");
    this.queryText = queryString ;

控制分页

描述

在查看报告时,用户可能想选择每页显示的行数。您应该能够从一个下拉列表中选择要显示的行数。

本节描述如何使用 BIRT 报告参数和分组功能定制报告,以允许用户使用动态分页。在报告设计期间,先设置一些值,例如 20、30 和 40。当报告在 BIRT Report Viewer 中运行时,用户将看到一个报告参数列表框,其中包含设计时指定的一组值。

注意:该特性只能在部署在 WebSphere Application Server 中的 Report Viewer 中测试。

实现

该特性是通过按所需行数对数据行进行分组,然后在每个组之后插入一个分页符来实现的。为了按特定的行数对行进行分组,每一行都执行索引。

  1. 在报告中选择包含数据的表,然后在 Property Editor 中,选择 Binding 以创建一个新的列绑定。指定 Total.runningCount() 作为表达式。当 BIRT 处理每个数据行时,这个聚合函数将提供当前行数。图 4 显示了使用 Total.runningCount() 的列绑定 row_index
    图 4. 指定运行数
    指定运行数
  2. 在 Property Editor 中为该表选择 Group,在列绑定 row_index 上添加一个组,如图 5 所示。字段 Range 的值将由用户输入并通过 JavaScript 动态地设置。将这个组命名为 Rows_group,确保选择了 Repeat Header 选项,并且将 Page Break After 设为 Always
    图 5. 组细节
    组细节
  3. 在 layout 编辑器中,删除 BIRT 自动添加到组标题的数据元素。如果不这样做,报告就会在每个组的开头处显示行数。
  4. 创建一个报告参数 RowsTobeDisplayed,并添加一些静态值,这些值对应于您希望用户指定每页报告显示的行数,如图 6 所示。
    图 6. 报告参数
    报告参数
  5. 在 outline 编辑器中,选择步骤 2 中创建的组 Rows_group,如图 7 所示,并单击 Script 选项卡。从下拉列表中选择 onPrepare 事件处理程序,并输入以下 JavaScript 代码:
    NoOfRows = reportContext.getParameterValue("RowsToBeDisplayed");
    NoOfRows = parseInt(NoOfRows) + parseInt(1);
    NoOfRows = NoOfRows * 1;
    this.intervalRange = NoOfRows;

    图 7. 选择组
    选择组

展开和折叠详细数据

描述

用户可能想在报告细节和报告摘要之间来回切换。例如,假设一个报告有三个列:PRODUCTLINE(Category)、PRODUCTNAME 和 BUYPRICE。该报告按 PRODUCTLINE 分组,每个类别有一个总的 BUYPRICE。用户希望首先查看包含所有产品名称和价格等细节的报告,然后切换到一个摘要报告视图,只显示类别和总价。

实现

我们将使用报告元素的超级链接属性来启用这个功能,这种超级链接将链接到另一个报告,这个报告是详细报告的一个摘要。

  1. 为详细报告创建一个新的报告,并用如下所示的查询创建一个数据集:
    select CLASSICMODELS.PRODUCTS.PRODUCTLINE,
               CLASSICMODELS.PRODUCTS.PRODUCTNAME,
               CLASSICMODELS.PRODUCTS.BUYPRICE
    from   CLASSICMODELS.PRODUCTS

     
  2. 将数据集中的列与 Report Designer 的 palette 视图中的表进行绑定。
  3. 在 layout 视图中,选择之前步骤中创建的表,并单击 Groups 选项卡。
  4. 创建一个新组,如图 8 所示。 
    图 8. 组细节
    组细节
  5. 在 layout 视图中选择报告,并在初始化事件处理程序中添加以下两行:
    totalPrice       = 0 // For storing the total buy price of each category
    allCategoryTotal = 0 // For storing the total buy price of all
                         // categories
  6. 选择表的细节行,如图 9 所示,并在 onCreate 事件处理程序中添加以下代码:
    total = this.getRowData().getExpressionValue("row[BUYPRICE]");
    total = total * 1;
    totalPrice = total + totalPrice;
    allCategoryTotal = allCategoryTotal + total;

    图 9. 选择细节行
    选择细节行
  7. 在 Group Footer Row 中添加一个标签(Label),如图 10 所示。 
    图 10. 添加标签
    添加标签
  8. 将以下代码添加到这个标签的 onCreate 事件处理程序中:
    this.text  = "Total BUY Price-----" + totalPrice
    totalPrice = 0    // initializing to zero every group
  9. 在表下面的报告布局中创建一个 label,并添加以下代码。它显示所有类别的总数。
    this.text = "ALL CATEGORY TOTAL=" + allCategoryTotal
  10. 使用以下数据集查询创建一个新报告,以显示详细报告的摘要:
    select   CLASSICMODELS.PRODUCTS.PRODUCTLINE,
             SUM(CLASSICMODELS.PRODUCTS.BUYPRICE) as TOTAL
    from     CLASSICMODELS.PRODUCTS
    group by CLASSICMODELS.PRODUCTS.PRODUCTLINE

    遵循前面描述的用于详细报告的步骤,显示所有类别的 Total。
  11. 将一个名为 Summary 的标签添加到第一个详细报告中,并添加到摘要报告的超级链接,如图 11 和 12 所示。
    图 11. 到摘要报告的超级链接
    到摘要报告的超级链接
    图 12. 超级链接细节
    超级链接细节
  12. 类似地,在摘要报告中添加 Go back to details 标签和到详细报告的超级链接。

对数据使用空白选择条件

描述

可以为 BIRT 报告指定参数,并要求用户为参数提供一个值。这些参数常用于按某种方式过滤报告数据行。在某些情况下,您可能希望指定一个参数来过滤报告的数据行,但是同时用户也可以表示希望显示所有行,而不使用过滤参数值。提供这个功能的一种方式是允许用户将参数值留空;然后,报告将空白的参数解释为不需要对那个参数进行过滤。

例如,假设一个报告有三个列:PRODUCTLINE、PRODUCTNAME 和 BUYPRICE。该报告还有一个参数,使用户可输入一个特定的 PRODUCTLINE 值,以便根据这个值对报告进行过滤。所以,当用户为该参数输入一个值时,只有 PRODUCTLINE 值等于该参数值的行才会显示。

现在,如果用户选择将 PRODUCTLINE 参数值留空,那么所有行都将显示,无论它们的 PRODUCTLINE 值是什么。

实现

通过使用一个报告参数,并在报告使用的数据集的 beforeOpen 事件处理程序中添加一些 JavaScript 代码,可以实现这个功能。

  1. 创建一个名为 “DataSet” 的数据集,该数据集将用于显示报告上的数据,并将该数据集的 SQL 查询定义如下:
    select CLASSICMODELS.PRODUCTS.PRODUCTLINE,
           CLASSICMODELS.PRODUCTS.PRODUCTNAME,
           CLASSICMODELS.PRODUCTS.BUYPRICE
    from   CLASSICMODELS.PRODUCTS

    当 PRODUCTLINE 上的选择标准留空时,将执行该查询。
  2. 创建另一个名为 “ProductLine” 的数据集,并将 SQL 查询定义如下:
    select CLASSICMODELS.PRODUCTS.PRODUCTLINE
    from   CLASSICMODELS.PRODUCTS

    该查询将用于为参数提供选择值。
  3. 创建一个报告参数 “Product Line”,并将它绑定到数据集 ProductLine 的列 PRODUCTLINE。在创建这个报告参数时,确认选择了 Allow blank values 选项,如图 13 所示。
    图 13. 编辑参数
    编辑参数
  4. 将以下 JavaScript 代码添加到报告中将显示的数据集 DataSet 的 beforeOpen 事件处理程序中。每当选中一个条件时,这组脚本将更改 queryText。
    productLine = reportContext.getParameterValue("Product Line");
     if (productLine != '')
     {
         queryString = this.queryText;
         queryString = queryString + 
                     " where CLASSICMODELS.PRODUCTS.PRODUCTLINE = " +
                     "'" + 
                     productLine + 
                             "'";
        this.queryText = queryString;
    }  
     

用户可排序的多个列

描述

当查看一个报告时,用户可能希望根据多个条件对数据进行排序。有时候,用户可能希望只根据一个可用的选择条件对数据排序,而将其他条件留空,或者不选择任何条件,将所有条件留空。

例如,假设一个报告包含三个列:CUSTOMERNAME、COUNTRY 和 CITY,用户可能希望首先按照 COUNTRY 对数据排序,然后在 COUNTRY 内按照 CITY 排序,或者用户可能希望只按照 CITY 排序,或者将所有排序条件留空,不进行任何排序。

实现

本节描述解决方案开发人员如何使用 BIRT 报告参数和一个 JavaScript 事件处理程序定制 BIRT 报告,以实现这个功能。

  1. 创建一个名为 DataSet 的数据集,该数据集将用于在报告中显示数据,并将该数据集的 SQL 查询定义如下:
    select CLASSICMODELS.CUSTOMERS.COUNTRY, 
               CLASSICMODELS.CUSTOMERS.CUSTOMERNAME,
               CLASSICMODELS.CUSTOMERS.CITY
    from   CLASSICMODELS.CUSTOMERS
  2. 创建一个名为 First Sort Criteria 的报告参数,如图 14 所示。
    图 14. 第一个排序参数
    第一个排序参数
  3. 创建另一个名为 Second Sort Criteria 的报告参数,如图 15 所示。
    图 15. 第二个报告参数
    第二个报告参数
  4. 在 outline 视图中选择数据集 DataSet,并单击 Script 选项卡。
    图 16. 在 outline 中选择数据集
    在 outline 中选择数据集
  5. 在 script 选项卡中选择事件处理程序 beforeOpen,并添加以下代码:
    sortC1 = reportContext.getParameterValue("First Sort Criteria")
    sortC2 = reportContext.getParameterValue("Second Sort Criteria")
        
    if (sortC1 != '')
    {
       queryString = this.queryText;
       queryString = queryString + " order by " + 
                         reportContext.getParameterValue("First Sort Criteria");
       this.queryText = queryString;
    }
    
    if (sortC2 != '')
    {
       if (sortC1 != '')
       {
              this.queryText = this.queryText + 
                               " , " + 
                               reportContext.getParameterValue("Second Sort Criteria");
        }
        else 
        {
           this.queryText = this.queryText + 
                               " order by " + 
                               reportContext.getParameterValue("Second Sort Criteria");
        }
    }


隐藏或显示列

描述

用户在查看报告时,可能希望先去掉一些列,然后再将这些列加回到报告中。

实现

可以通过使用一个报告参数和列的 visibility 属性在 BIRT 中实现该特性。在此,我们将显示一个包含 FIRSTNAME、LASTNAME 和 EMAIL 这三个列的报告。用户可以通过在报告参数窗口中选中适当的复选框,隐藏或显示其中的任何列。

  1. 创建 Data Source 和一个 Data Set,并且按如下方式定义查询:
    select CLASSICMODELS.EMPLOYEES.FIRSTNAME, 
           CLASSICMODELS.EMPLOYEES.LASTNAME, 
           CLASSICMODELS.EMPLOYEES.EMAIL
    from   CLASSICMODELS.EMPLOYEES
  2. 创建一个名为 hideFirstName 的报告参数,如图 17 所示。
    图 17. hideFirstName 参数
    hideFirstName 参数
  3. 对于其他两个列 Last Name 和 Email,像步骤 2 那样再创建两个报告参数 hideLastNamehideEmail
  4. 在 layout 视图中,选择每个列,然后在 Property Editor 中选择 visibility 属性,并编写以下表达式:
    params [“hideFirstName"] 
    params [“hideLastName"] 
    params [“hideEmail"]

    如图 18 和 19 所示。
    图 18. 列可见性表达式
    列可见性表达式
    图 19. 表达式条目
    表达式条目

结束语

借助以上列出的 6 个技巧,解决方案开发人员应该可以扩展 BIRT 报告,使之为报告用户提供更多的交互能力。希望这些技巧能够帮助您进一步理解 JavaScript 和 BIRT 在报告增强和定制方面的作用。

参考资料

学习

获得产品和技术

  • eclipse.org 上的 BIRT 项目:获取更多关于 BIRT 的详细信息,并下载代码。
  • 下载 IBM 试用软件,并获取来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Information Management, Open source
ArticleID=302299
ArticleTitle=使用 Business Intelligence and Reporting Tools 的提示与技巧
publish-date=04222008