Reports addon available?

Does the current JMix release include the Reports addon ?

Hi,

The Reporting add-on is in the phase of testing and stabilitization, and it’s not published yet. It will appear at https://www.jmix.io/marketplace when it’s ready.

2 Likes

I’ve done the job with jasper reports and call the report with jasper class directly
Suppose you have the jasper report file called “report”, add the xml definition to resources folder in a file called “report.jrxml”.

Put the code in a java class for the report generation

@RestController
@Service
public class ReportCustomerService {

@Autowired
@Secure
private DataManager dataManager;
protected JasperPrint jasperPrint;

public void exportReport() throws JRException, IOException {

    List<Customer> customerlist = dataManager.load(Customer.class)
                        .query("select e from customer e ")
                        .list();

    ClassLoader classLoader = getClass().getClassLoader();
    InputStream url = null;
    url = classLoader.getResourceAsStream("report.jrxml");
    JasperReport jasperReport = JasperCompileManager.compileReport(url);
    JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(customerlist);
    Map<String, Object> parameters =new HashMap<>();
    parameters.put("createdBy","You");
    this.jasperPrint = JasperFillManager.fillReport(jasperReport,parameters,dataSource);
    return ;

}

@RequestMapping(value = "/report", method = RequestMethod.GET,produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<InputStreamResource> getDocument() throws JRException {

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    JasperExportManager.exportReportToPdfStream(this.jasperPrint, out);;
    ByteArrayInputStream bis = new ByteArrayInputStream(out.toByteArray());


    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Disposition", "inline; filename=report.pdf");

    return ResponseEntity
            .ok()
            .headers(headers)
            .contentType(MediaType.APPLICATION_PDF)
            .body(new InputStreamResource(bis));

}

}

Then call the report from your form

inject the ReportCustomerService class in the controller
@Autowired
private ReportCustomerService reportCustomerService;

@Subscribe("btnGenerateReport")
public void onBtnGenerateReportClick(Button.ClickEvent event) throws JRException, IOException {

    reportCustomerService.exportReport();
    webBrowserTools.showWebPage("/report", ParamsMap.of("_target", "blank"));

}

Dear Camil

Thank you a lot for your sample. It works like a charm.

I want to print an invoice, therefore need the adressdetails.

When i change now the JPQL to

List<Orders> customerlist = dataManager.load(Orders.class).query("SELECT o, a FROM Orders o LEFT JOIN Adres a where o.id = " + order.getId()).list();

I get a message

DevelopmentException: DataManager cannot execute query for single attributes

Anybody any idea what am I doing wrong ?

Thank you for your help !

Felix

I suppose Orders.class does not match your query as you have 2 tables there.
May be you split in 2 and adress you send it as parameters to the report.

List customerlist = dataManager.load(Orders.class).query("SELECT a FROM Orders where o.id = " + order.getId()).list();

    ClassLoader classLoader = getClass().getClassLoader();
    InputStream url = null;
    url = classLoader.getResourceAsStream("reports/bill.jrxml");
    JasperReport jasperReport = JasperCompileManager.compileReport(url);
    JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(customerlist);
    Map<String, Object> parameters =new HashMap<>();

    adress.load();  // adress is a class that can load with getters all the data you need (like adress,getCity(), etc
    parameters.put("adress",adress);
    this.jasperPrint = JasperFillManager.fillReport(jasperReport,parameters,dataSource);

  // in jasper report file make adress class as a parameter and call in your report where you want to display city adress.getCity() and so on.

May be is another solution but this worked for me.

Dear Camil

Thank you for your tip. I think i did hit here a JPQL error in JMix.

I am aware, that i could manually set all the parameters in the source, which i do not like to much.

BUT, the approach about handing over a class to the Jasper-Report I do like. BUT, how does JasperReport know about the Adres class ?

((Adres)parameter_adress.getValue()).getCountry()

→ error: cannot find symbol

Thank you for your effort. But it seems some important things are missing ?

image

What to put here in class ?

Best regards

Felix

In jrxml report file, where import lines are
<property name=com.jaspersoft.studio.unit.columnWidth value=pixel/>
<property name=com.jaspersoft.studio.unit.columnSpacing value=pixel/>
<import value=java.time.LocalDate/>
...
<import value=ro.infoexpert.pontaj.Adress/>

Then before field tags put 
<parameter name="adress" class="ro.blabla.Adress" isForPrompting="false"/>
<field name="..." class="java.lang.Integer"/>

Then for the real field (note the $P)
<textFieldExpression><![CDATA[$P{adress}.getCity()]]></textFieldExpression>

1 Like

Dear Camil

It was some fiddeling, but it is working now ! Thank you a lot !

Did you try to work with fontextensions ? I did add the montserrat font and add the exported jar to the Lib path and still get the message “JRFontNotFoundException: Font “Montserrat” is not available to the JVM. See the Javadoc for more details.”

Regards

Felix

Dear Camil

I have now a working Project with Jasper Reporting and Fontextension enabled thanks to you and Add Custom Fonts to Jasper Report in Java - The Geeky Asian.

If people are interested, i could make a sample project. This would help everybody working with Jasper and Jmix, as there are some details to take care, where there is little to no documentation.

Regards

Felix

2 Likes

Hello,

Yes please, a sample project would be beneficial.

Kind regards,
Mladen Bucan