运行报表

从报表浏览界面运行

运行报表最简单的方式是使用通用报表浏览界面,通过 Reports(报表) → Run Reports(运行报表) 打开该界面。用户需要有访问此界面的权限。在报表浏览界面列出了当前用户 可用 的所有报表。如果报表有外部参数,则在运行报表会显示一个表单来获取这些参数。

从其他界面运行报表

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

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

  • io.jmix.reportsui.action.list.RunReportAction - 是一个 标准操作,用于展示可用的报表列表。可以为 Button 或列表组件(TableDataGrid 等)定义该操作。

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

    <actions>
        <action id="run" type="runReport"/> (1)
    </actions>
        <button id="runBtn" action="booksTable.run"/> (2)
    </buttonsPanel>
    1 type 属性定义了一个特殊的 runReport 操作类型,该操作由框架提供。
    2 添加运行报表的按钮。

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

    @Autowired
    private Button runReportBtn;
    
    @Autowired
    private Actions actions;
    
    @Subscribe
    public void onInit(InitEvent event) {
        RunReportAction action = actions.create(RunReportAction.class, "runReport");
    
        runReportBtn.setAction(action);
    }

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

  • io.jmix.reportsui.action.list.ListPrintFormAction - 是一个 标准操作,用来打印实体实例集合报表,实体实例与列表组件(TableDataGrid 等)关联。

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

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

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

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

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

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

      <actions>
          <action id="list" type="listPrintForm"/> (1)
      </actions>
      <buttonsPanel id="buttonsPanel"
                    alwaysVisible="true">
          <button id="listBtn" action="authorsTable.list"/> (2)
      </buttonsPanel>
      1 type 属性定义了一个特殊的 listPrintForm 操作类型,该操作由框架提供。
      2 添加运行报表的按钮。

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

      @Autowired
      private Button listPrintFormBtn;
      
      @Autowired
      private Actions actions;
      
      @Subscribe
      public void onInit(InitEvent event) {
          ListPrintFormAction action = actions.create(ListPrintFormAction.class, "listPrintForm");
          listPrintFormBtn.setAction(action);
      }

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

      run actions listPrint confirmation
      Figure 1. 确认窗口

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

  • io.jmix.reportsui.action.list.EditorPrintFormAction - 与实体编辑器界面关联的操作。该操作仅选择外部参数类型是 EntityList of entities 的报表,并且参数实体类型要与编辑的实体类型一样。如果只有一个这样的报表,则会立即调用该报表。如果有多个,则会显示一个列表供用户选择。

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

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

    • XML 描述

      <hbox id="editActions" spacing="true">
          <button id="reportButton" icon="PRINT"/>
      </hbox>
    • 控制器

      @Inject
      private Button reportButton;
      
      @Autowired
      private Actions actions;
      
      @Subscribe
      public void onInit(InitEvent event) {
          EditorPrintFormAction action = actions.create(EditorPrintFormAction.class);
          action.setEditor(this);
          action.setReportOutputName(null);
          reportButton.setAction(action);
      }

报表 API

ReportRunner

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

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

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

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

    @Autowired
    protected ReportRunner reportRunner;
    
    @Subscribe("rrBtn1")
    protected void onRrBtn1Click(Button.ClickEvent 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
    protected ReportRunner reportRunner;
    
    @Subscribe("rrBtn2")
    protected void onRrBtn2Click(Button.ClickEvent 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(RunReportScreen.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);