运行报表

从报表列表视图运行

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

从其他视图运行报表

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

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

  • io.jmix.reportsflowui.action.RunReportAction - 是一个 标准操作,可以在当前视图或列表组价运行报表。可以为 button 或列表组件(DataGridTreeDataGrid)定义该操作。

    下面是 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 reports(运行报表) 对话框展示与当前视图相关的报表。当用户从列表中选择一个报表时,会展示参数输入表单(如果有的话),然后可以运行报表。

  • io.jmix.reportsflowui.action.RunListEntityReportAction - 是一个 标准操作,用来打印列表组件(DataGridTreeDataGrid)中的实体集合报表。

    此操作只会选择外部参数为 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

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

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

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

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

    • XML 描述

      <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

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 实例运行报表。
    点击操作面板的 Code Snippets 自动生成 使用 ReportRunner 接口运行报表的代码。
  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() 方法为指定的集合中每个对象运行一次报表。集合中的对象需要是同一类型的,并且使用指定的别名作为报表的输入参数。

点击操作面板的 Code Snippets 自动生成 使用 UiReportRunner 接口运行报表的代码。

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);