开始使用

本章节介绍如何使用报表向导和报表详情视图创建并执行报表。

我们将使用图书馆(Library)应用程序作为本章节的示例程序,源码位于 GitHub

项目配置

  1. 下载并解压 Jmix Samples 项目,或者直接用 Git 克隆:

    git clone https://github.com/jmix-framework/jmix-samples-2
  2. 按照 打开已有项目 部分的说明,在 Studio 中打开 jmix-samples 项目。

  3. 选择 Library Jmix Application 配置,按照 启动应用程序 部分的说明启动应用程序。

  4. 使用 admin / admin 凭证登录 Library 应用。

打开 报表列表视图 然后点击 Create(新建)Using wizard(向导)

reports wizard main

使用向导可以创建下列类型的报表:

  1. 单个实体的报表。

  2. 实体列表的报表。

  3. 通过查询过滤的实体列表的报表。

使用向导创建报表的过程包含三个步骤:

  1. 创建报表的数据结构。

  2. 编辑报表区域。

  3. 保存报表。

向导创建的报表可以通过报表详情视图修改,并通过 报表列表视图 运行,或使用特定的 操作RunListEntityReportActionRunSingleEntityReportAction 等)运行。

使用报表向导

为了便于入门,报表扩展组件自带了一个报表向导,这是一个用来快速创建报表的可视化工具,包含 区域模板设计

本节中,我们将创建的报表包含书籍的主要数据以及书籍作者的信息。报表模板将使用 DOCX 格式,保存后的报表使用 PDF 格式。

从应用程序主菜单打开 Reports → Reports 视图,然后点击 Create(新建)Using wizard(向导)。在向导的第一步输入下列内容:

  • 报表实体:Book

  • 模板类型:DOCX

  • 报表名称:Book Record

  • 报表类型:Report for single entity

single entity step 1

定义属性

向导的下一步中,指定 Book 实体和关联的 LiteratureType 实体的属性,这些属性将在报表中展示:Book.Name, Book.Summary, Book.literatureType.Name。这些属性形成了 “简单展示区”(simple region)。

single entity attributes

点击 OK 移至下一步 - 报表展示区编辑。

出现的视图包含一个命名区域列表,这些区域是用来显示相关数据。向导支持向模板中添加多个纯文本区域,以显示不同的数据集。

加载到特定区域的实体属性列表可以通过单击属性列表链接来修改。还可以通过单击 Add simple region(添加简易展示区) 来添加新区域。

如果实体包含集合属性,则会出现 Add tabulated region(添加表格展示区) 按钮。可以添加显示表格数据的区域。

因此,为了展示该 Book 实体相关的作者列表,我们将创建另一个数据展示区。点击 Add tabulated region(添加表格展示区) 按钮。

single entity step 2

Entity tree lookup 对话框选择 Book.authors

然后选择 authors.firstNameauthors.lastName 属性。

report region

所有的展示区都配置完成后,可以进行最后一步了:保存报表。此时,可以查看完整的报表模板,或将输出文件的名称和格式更改为其他任意支持的类型。我们选择 PDF 作为报表输出类型。

点击 Save 按钮后,会显示标准的报表详情视图。可以对报表继续做微调。

配置输出文档

在报表详情视图中,切换至 Template(模板) 标签页。

报表的输出文档包含一个最初通过向导定义的模板。输出类型设置为 PDF,模板文件是 DOCX。

configure template

点击模板文件名并打开它,例如,通过 LibreOffice 打开。按照下图修改 模板内容

edit template for report1

报表的模板可以在 Demo 项目中下载: reports/templates

点击 Report template(报表模板) 对话框中的 Upload(上传) 按钮并选择上传的模板。

此外,还可以定义输出文档的文件名。可以使用静态名称,也可以编程式配置。

这里,对于 “The 20th Century Art Book” 这本书,文件名是:Book Record - The 20th Century Art Book.pdf

因此,我们需要配置一个引用特定报表区域的文件名:${Root.title}.pdf

output name pattern

Root.titleRoot 数据区域的 title 值。

切换至 Bands(报表数据区) 标签页。选择 Root 区,并勾选 Multi Datasets 复选框。

add title dataset

新建一个 title 数据集。

使用基于 groovy 的数据集定义 title 属性的值,如下:

def bookName = params["entity"]["name"] (1)

return [
    ["title" : "Book Record - $bookName"] (2)
]
1 params 变量访问不同的外部参数。params["entity"] 表示选择的 book 实例。
2 Groovy 脚本需要返回一个 Map 的列表。title 键值对应的就是目标文件名。

从 Books 视图运行报表

另外,我们可以在 book 的列表视图启用报表运行。首先,我们需要在 book-list-view.xml 视图描述中声明一个标准的 RunListEntityReport

<hbox id="buttonsPanel" classNames="buttons-panel">
    <!-- ...  -->
    <button id="printBtn" action="booksDataGrid.reportPrint"/> (1)
</hbox>
<dataGrid id="booksDataGrid"
          width="100%"
          minHeight="20em"
          dataContainer="booksDc">
    <actions>
        <!-- ...  -->
        <action id="reportPrint" type="report_runListEntityReport"
                text="Print details"/> (2)
    </actions>
</dataGrid>
1 添加一个用来运行报表的按钮。
2 type 属性定义特定的 report_runListEntityReport 操作类型。

然后,我们需要将报表与 Book 列表视图关联起来。打开报表详情视图,切换到 Roles and views(角色和视图) 标签页,并从下拉列表中将 Book.list 视图添加到表格:

single entity screens

保存报表。

现在,可以通过在表格选中任何书籍并单击 Print details 按钮来运行对应的报表。

single entity running

输出如下:

single entity result

手动创建报表

本节中,我们将不使用向导创建一个稍微复杂一些的报表。

报表将包含出版物(publications)列表,列表通过文献类型(literature types)和书籍分组。

报表的上半部分包含关于报表创建人的信息以及报表的生成日期。下半部分是展示分组的出版物列表。

报表的配置如下:

  • 模板类型:XLSX

  • 报表名称:Publications grouped by types and books

创建模板

使用 Microsoft Office 或 LibreOffice 创建一个 Template for publications by type.xlsx 模板。

template for report2

报表模板需要包含命名区域:主区域的三组数据集(typebookpublisher),表头(tableheader),以及报表的附加信息(header)。

报表的模板可以在 Demo 项目中下载: reports/templates

定义报表结构

从应用程序主菜单打开 Reports → Reports 视图,然后点击 Create → New

会显示 报表详情 标签页。

定义报表名称 - Publications grouped by types and books

structure for report2

点击 Create template(创建模板) 按钮。

Report template(报表模板) 弹窗中,上传前一步定义的报表模板,并定义输出名称格式(output name pattern)。

upload template for report2

下面我们创建报表区域。

  • header 区域包含使用 Groovy 脚本定义的数据集,脚本会输出当前用户的名称和当前日期。

    import io.jmix.core.security.CurrentAuthentication;
    import io.jmix.core.TimeSource;
    
    def user = currentAuthentication.getUser().getUsername();
    def currentDate = timeSource.currentTimestamp();
    
    return [["generated_by":user, "generated_when":currentDate]]
  • tableheader 区域是空的,用来展示表头。

  • type 区域通过运行下列 JPQL 语句输出文献类型:

    select b.literatureType.id as typeId,
    b.literatureType.name as type
    from Book b
  • book 区域,是 type 的子区域,运行下列 JPQL 语句输出书籍:

    select b.id as bookId,
    b.name as bookName
    from Book b
    where b.literatureType.id = ${type.typeId}

    这个查询语句使用了父区域的字段 typeId 作为查询参数。框架提供了父子区域之间的依赖。

  • publisher 区域,是 book 的子区域,运行下列 JPQL 语句输出出版物信息:

    select bp.publisher.name as publisher,
    bp.year as year,
    bp.city as town
    from BookPublication bp
    where bp.book.id = ${book.bookId}

    这个查询语句使用了父区域的字段 bookId 作为查询参数。

最终完成的报表结构如下:

report structure report2

从报表列表视图运行报表

报表一旦保存之后,可以通过通用 运行报表视图 运行。

输出如下:

output report2