运行报表

Users can run reports through the admin UI or from relevant application views using the actions provided by the Reports add-on. The report engine loads the report definition and the template from the application code or from the database and generates the output document:

run 1
Figure 1. Running a report

Running from Reports List

The easiest way to run reports is from the Run report view. The user must have the permission to access this view. The list will contain all reports that are available to the user in accordance with their role. If the report has external parameters, they will be requested in a special form when running the report.

从视图运行报表

在任意视图中,用户都可以使用特定操作及相关的按钮或组件右键菜单运行报表。此时,除了用户角色外,还将检查报表在此视图的 可用性

下面示例展示不同类型操作和使用方法。

RunReportAction

io.jmix.reportsflowui.action.RunReportAction 是一个 标准操作,可以在当前视图或列表组件运行报表。可以为 button 或列表组件(dataGrid 数据网格, treeDataGrid 树形数据网格)定义该操作。

下面是 DataGrid 使用声明式操作的示例:

<hbox id="buttonsPanel" classNames="buttons-panel">
    <!-- ...  -->
    <button id="runBtn" action="booksDataGrid.run"/> (1)
</hbox>
<dataGrid id="booksDataGrid"
          width="100%"
          minHeight="20em"
          dataContainer="booksDc">
    <actions>
        <!-- ...  -->
        <action id="run" type="report_runReport"/> (2)
    </actions>
</dataGrid>
1 添加运行报表的按钮。
2 type 属性定义了一个特殊的 report_runReport 操作类型,该操作由报表扩展组件提供。

使用编程式方法创建操作,该操作关联一个在 XML 描述中声明的按钮,示例:

@ViewComponent
private JmixButton runBtn;

@Autowired
private Actions actions;

@Subscribe
public void onInit(final InitEvent event) {
    RunReportAction<Book> action = actions.create(RunReportAction.ID);

    runBtn.setAction(action);
}

当操作执行时,会打开一个 Run report(运行报表) 对话框展示与当前视图相关的报表。当用户从列表中选择一个报表时,会展示参数输入表单(如果有的话),然后可以运行报表。

RunListEntityReportAction

io.jmix.reportsflowui.action.RunListEntityReportAction 是一个 标准操作,用来打印列表组件(dataGrid 数据网格, treeDataGrid 树形数据网格)中的实体集合报表。

此操作只会选择外部参数为 Entity 或者 List of entities 类型的报表,并且要求参数实体类型与列表组件展示的实体类型一致。如果最后筛选结果只有一个报表,则会立即调用该报表。如果有多个报表符合条件,则会展示报表列表交于用户选择。

使用以下规则将外部参数值传递给报表:

  • 如果参数是 List of entities 类型,会将列表组件中当前选择的实例列表传递给报表。

  • 如果参数是 Entity 类型,并且在列表组件选择了单个实例(高亮显示一行),则选中实例会传递到报表中。

  • 如果是 Entity 类型的参数,并且列表组件中选择了多行,则报表会根据选择的实例数量运行多次。执行之后,用户将得到一个包含所有生成的报表的 ZIP 文件。

下面是 DataGrid 使用声明式操作的示例:

<hbox id="buttonsPanel" classNames="buttons-panel">
    <!-- ...  -->
    <button id="runListBtn" action="authorsDataGrid.runList"/> (1)
</hbox>
<dataGrid id="authorsDataGrid"
          width="100%"
          minHeight="20em"
          dataContainer="authorsDc">
    <actions>
        <!-- ...  -->
        <action id="runList" type="report_runListEntityReport"/> (2)
    </actions>
</dataGrid>
1 添加运行实体报表的按钮。
2 type 属性定义了一个特殊的 report_runListEntityReport 操作类型,该操作由报表扩展组件提供。

使用编程式方法创建操作,该操作关联一个在 XML 描述中声明的按钮,示例:

@ViewComponent
private JmixButton runListBtn;

@Autowired
private Actions actions;

@Subscribe
public void onInit(final InitEvent event) {
    RunListEntityReportAction<Author> action = actions.create(RunListEntityReportAction.ID);

    runListBtn.setAction(action);
}

当操作执行时,如果列表组件没有选中实体,会显示一个确认窗口。

run list entity report action confirmation

之后,会打开一个 Run report(运行报表) 对话框展示与当前视图相关的报表。从该窗口中,用户可以针对选中的实体运行报表。

RunSingleEntityReportAction

io.jmix.reportsflowui.action.RunSingleEntityReportAction 是与实体详情视图关联的操作。该操作仅选择外部参数类型是 EntityList of entities 的报表,并且参数实体类型要与编辑的实体类型一样。如果只有一个这样的报表,则会立即调用该报表。如果有多个,则会显示一个列表供用户选择。

外部参数值 - 被编辑的实体实例会传递到报表中。如果参数是 List of entities 类型,则会传递一个包含单一实体的列表。

下面是在一个按钮中使用这个操作的示例,这个按钮位于标准的 OKCancel 按钮旁边:

<hbox id="detailActions">
    <button id="saveAndCloseBtn" action="saveAction"/>
    <button id="closeBtn" action="closeAction"/>
    <button id="reportButton" icon="PRINT"/>
</hbox>
@Autowired
private Actions actions;

@ViewComponent
private JmixButton reportButton;

@Subscribe
public void onInitEntity(final InitEntityEvent<Book> event) {
    RunSingleEntityReportAction<Book> action = actions.create(RunSingleEntityReportAction.ID);
    action.setReportOutputName(null);

    reportButton.setAction(action);
}

报表 API

可以使用 代码片段 功能生成使用 API 运行报表的代码。

ReportRunner

ReportRunner 是用来运行报表的接口。其所有的方法都返回 ReportOutputDocument 对象,包含报表执行结果。

下面是几个 ReportRunner 用法的示例:

  1. 基于 ReportRunContext 对象提供的信息运行报表:

    @Autowired
    private ReportRunner reportRunner;
    
    @Subscribe("rrcBtn2")
    public void onRrcBtn2Click(ClickEvent<JmixButton> event) {
        ReportOutputDocument document = reportRunner
                .run(new ReportRunContext(report).setParams(paramsMap)); (1)
    }
    1 ReportRunContext 包含报表实体和参数。
  2. 通过报表编码和流式接口指定的附加信息运行报表:

    @Autowired
    private ReportRunner reportRunner;
    
    @Subscribe("rrBtn1")
    public void onRrBtn1Click(ClickEvent<JmixButton> event) {
        ReportOutputDocument document = reportRunner.byReportCode("BOOKS") (1)
                .addParam("type", type) (2)
                .withTemplateCode("books-template") (3)
                .run(); (4)
    }
    1 指定编码报表流式接口的入口点。
    2 在参数 map 中添加一个输入参数。
    3 设置模板的编码,将用于运行报表。
    4 构建一个 ReportRunContext 实例,并使用该 Context 实例运行报表。
  3. 通过报表实体和流式接口指定的附加信息运行报表:

    @Autowired
    private ReportRunner reportRunner;
    
    @Subscribe("rrBtn2")
    public void onRrBtn2Click(ClickEvent<JmixButton> event) {
        ReportOutputDocument document = reportRunner.byReportEntity(report)
                .addParam("type", type)
                .withOutputType(ReportOutputType.PDF) (1)
                .withOutputNamePattern("Books") (2)
                .run();
    }
    1 设置输出文档类型。
    2 设置输出文档的命名格式。

可以直接从 ReportOutputDocument 获取报表内容和文件名:

String documentName = document.getDocumentName();

byte[] content = document.getContent();

UiReportRunner

UiReportRunner 是一个从应用程序视图运行报表的接口。除了运行报表之外,UiReportRunner 还支持配置下列功能:

  • 在浏览器展示报表运行的结果(使用表格模板)。

    uiReportRunner.runAndShow(new UiReportRunContext(report));
  • 在运行报表前是否展示用于输入报表参数的对话框。使用 ParametersDialogShowMode,支持三种模式:

    • YES(是) - 展示输入报表参数对话框。

    • NO(否) - 不展示输入报表参数对话框。

    • IF_REQUIRED(需要时) - 下列情况才展示输入报表参数对话框:

      • 报表有输入参数;

      • 报表有多个模板;

      • 报表只有一个模板,但有多个输出类型。

  • 同步执行报表或者后台异步执行:

    uiReportRunner.byReportEntity(report)
            .withParametersDialogShowMode(ParametersDialogShowMode.IF_REQUIRED)
            .inBackground(RunReportView.this)
            .runAndShow();
  • 为指定的参数别名和值运行多次报表:

    uiReportRunner.byReportEntity(report)
            .withOutputType(ReportOutputType.PDF)
            .withTemplateCode("publication-template")
            .withParametersDialogShowMode(ParametersDialogShowMode.NO)
            .runMultipleReports("entity", publicationList);

    runMultipleReports() 方法为指定的集合中每个对象运行一次报表。集合中的对象需要是同一类型的,并且使用指定的别名作为报表的输入参数。

ReportRunContext

ReportRunContext 类保存运行报表所需要的下列信息:

  • Report 实体;

  • ReportTemplate 实体:如果未指定,则使用默认模板;

  • 输入参数;

  • 输出文档的类型;

  • 输出文档的命名格式。

创建 ReportRunContext 的示例:

ReportRunContext context = new ReportRunContext(report)
        .addParam("type", type)
        .setOutputNamePattern("Books");

ReportRunContext context = new ReportRunContext(report)
        .setReportTemplate(template)
        .setOutputType(ReportOutputType.PDF)
        .setParams(paramsMap);

ReportZipUtils

ReportZipUtils 接口支持将一组 ReportOutputDocument 对象打包成一个 ZIP 压缩包。

byte[] zipArchiveContent = reportZipUtils.createZipArchive(documents);
downloader.download(zipArchiveContent, "Reports.zip", DownloadFormat.ZIP);