Report printing or viewing option

As explained in the user guide, we can quickly get the report of an entity in Editor (or browser) using CUBA built-in API e.g.


XML descriptor
<layout expand="windowActionsBox">
    ...
    <hbox id="windowActionsBox"
          spacing="true">
        <iframe id="windowActions"
                screen="editWindowActions"/>
        <button id="reportButton"/>
    </hbox>
</layout>

Controller


@Inject
private Button reportButton;

@Override
public void init(Map<String, Object> params) {
    reportButton.setAction(new EditorPrintFormAction("report", this, null));
}

How can we get a Popup selection option with 1- Print 2- View 3-Download in the screen (Browser and Editor) when clicked on the Print button, is there any built-in functions?

Hi,

Currently EditorPrintFormAction does not provide this option and the only way to achieve it is to write code that will use ReportGuiManager.

Let’s say we have pretty simple editor screen for Client entity:


<layout expand="windowActions"
        spacing="true">
    <button id="printBtn" caption="Print" invoke="print"/>
    <fieldGroup id="fieldGroup"
                datasource="clientDs">
        <column width="250px">
            <field id="title"/>
            <field id="summary"
                   rows="5"/>
        </column>
    </fieldGroup>
    <frame id="windowActions"
           screen="editWindowActions"/>
</layout>

First step - get available reports and let user to choose one if we have many suitable reports for this screen and entity:


 @Inject
private ReportGuiManager reportGuiManager;
@Inject
private UserSession userSession;
@Inject
private ExportDisplay exportDisplay;

public void print() {
    List<Report> reports = reportGuiManager.getAvailableReports(getId(), userSession.getUser(), getItem().getMetaClass());
    if (reports.size() > 1) {
        openLookup("report$Report.run", items -> {
            if (!items.isEmpty()) {
                Report report = (Report) items.iterator().next();
                runReport(report);
            }
        }, OpenType.DIALOG, ParamsMap.of(ReportRun.REPORTS_PARAMETER, reports));
    } else if (reports.size() == 1) {
        Report report = reports.get(0);
        runReport(report);
    } else {
        showNotification(messages.getMessage(ReportGuiManager.class, "report.notFoundReports"),
                NotificationType.HUMANIZED);
    }
}

Then we can run selected report and show Show/Download options. Currently you cannot trigger print action from a server-side, but you show a document to a user and they will be able to print it using standard Print action from a browser.


private void runReport(Report report) {
    ReportInputParameter parameter = report.getInputParameters().stream()
            .filter(inputParam -> reportGuiManager.parameterMatchesMetaClass(inputParam, getItem().getMetaClass()))
            .findFirst()
            .orElseThrow(() -> new ReportingException("No suitable report parameter found"));

    ReportOutputDocument reportResult =
            reportGuiManager.getReportResult(report, ParamsMap.of(parameter.getAlias(), getItem()), null);

    showOptionDialog("Print options", "What do you want to do with the report?",
            MessageType.CONFIRMATION, new Action[]{
                    new AbstractAction("show", Action.Status.PRIMARY) {
                        {
                            setCaption("Show");
                        }

                        @Override
                        public void actionPerform(Component component) {
                            exportDisplay.show(new ByteArrayDataProvider(reportResult.getContent()),
                                    reportResult.getDocumentName());
                        }
                    },
                    new AbstractAction("download") {
                        {
                            setCaption("Download");
                        }

                        @Override
                        public void actionPerform(Component component) {
                            exportDisplay.show(new ByteArrayDataProvider(reportResult.getContent()),
                                    reportResult.getDocumentName(), ExportFormat.OCTET_STREAM);
                        }
                    },
                    new DialogAction(DialogAction.Type.CANCEL)
            });
}

At the moment it is not that simple task, so we are going to simplify API for Report printing in the future releases.

Hi Yuriy
I understand you wanted to simplify the Report printing APIs last year. I am wondering if I have missed anything here!
Mortoza