mabutabee
(Mabuta Musilizo)
November 20, 2019, 10:13am
#1
Hi all,
Is there a way to print a report directly from your application without using the browser’s print action.
For example if you print out an invoice, its just directly sent to the printer rather than opening a new tab where one can have options to save or print.
Thanks.
shchienko
(Nikita Schienko)
November 26, 2019, 11:15am
#3
Hello @mabutabee ,
Tell me more about what you want to do. Do you want to programmatically configure the printer and print a report by pressing a button?
Regards,
Nikita
mabutabee
(Mabuta Musilizo)
November 27, 2019, 2:04pm
#4
Hi,
Yes i want to programmatically configure the printer and print a report by pressing a button.
The challenge with the pop-up is that it gives the user an option to save or download the report and once it is saved it could be printed multiple times from the user’s machine. So in the case of an invoice multiple copies can be reprinted from the saved or downloaded one.
thanks
shchienko
(Nikita Schienko)
December 10, 2019, 11:21am
#5
Hello @mabutabee ,
Sorry for the long answer. You can do it like this.
Controller:
@Inject
private DataService dataService;
@Inject
private ReportService reportService;
@Subscribe("printBtn")
public void onPrintBtnClick(Button.ClickEvent event) throws IOException, PrinterException {
LoadContext<Report> lContext = new LoadContext<>(Report.class);
lContext.setQueryString("select r from report$Report r where r.code = 'code'");
Report report = dataService.load(lContext);
ReportOutputDocument reportOutputDocument = reportService.createReport(report, new HashMap<>());
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(reportOutputDocument.getContent());
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
String printServiceName = service.getName();
PDDocument document = PDDocument.load(byteArrayInputStream);
PrintService myPrintService = findPrintService(printServiceName);
PrinterJob job = PrinterJob.getPrinterJob();
job.setPageable(new PDFPageable(document));
job.setPrintService(myPrintService);
job.print();
}
protected PrintService findPrintService(String printerName) {
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
for (PrintService printService : printServices) {
if (printService.getName().trim().equals(printerName)) {
return printService;
}
}
return null;
}
Screen:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd"
caption="msg://caption"
messagesPack="com.company.reporttest.web.screens">
<layout>
<vbox>
<button caption="Print report"
id="printBtn"/>
</vbox>
</layout>
</window>
And you will need to add reporting.openoffice.path
to the core
module.
Regards,
Nikita
1 Like
mabutabee
(Mabuta Musilizo)
December 15, 2019, 1:12pm
#6
Hi @shchienko ,
Thanks for the help, it has solved my challenge
l37sedoc
(Lloyd S)
May 7, 2021, 8:01pm
#8
HI,
I’m trying to use this code in my browser, but i keep getting this error:
package org.apache.pdfbox.pdmodel does not exist
package org.apache.pdfbox.printing does not exist
cannot find symbol class PDDocument
cannot find symbol variable PDDocument
cannot find symbol class PDFPageable
cuba version 7.2.12. legacy browser screen.
Can anyone please help?
Regards,
LS
albudarov
(Alexander Budarov)
May 11, 2021, 2:34pm
#9
Hi,
You need to add the PDFBox library dependency to your project to get access to these classes.
l37sedoc
(Lloyd S)
May 11, 2021, 3:21pm
#10
Thanks Alex the error is gone.
But now i’m getting a null pointer exception. my guess is that the output document(report template) is missing in the code.
at com.company.hrmmulti.web.screens.payrollitem.PayrollItemBrowse.onPrintBtnClick(PayrollItemBrowse.java:38) ~[HRIntelli-web-0.1-SNAPSHOT.jar:na]
Controller:
ReportOutputDocument reportOutputDocument = reportService.createReport(report, new HashMap<>());
What am i missing?
Lloyd
l37sedoc
(Lloyd S)
May 11, 2021, 4:00pm
#11
Problem solved. report system code added in the controller.
The report required parameter, which is generated when creating a report is not found.
" IllegalArgumentException: Required report parameter “entity” not found".
please help
l37sedoc
(Lloyd S)
May 13, 2021, 7:09pm
#12
Update:
I found a topic where is stated that in the parameter editor of the report Default value must not be empty. So when i select a default value, everything works except the fact that only one record can be printed(the default value). How do i get this to print selected records or records presented after filtering?
albudarov
(Alexander Budarov)
May 14, 2021, 6:51am
#13
Hi,
When you invoke report programmatically, you must pass all required parameters in a Map.
E.g. call this method:
com.haulmont.reports.app.service.ReportService#createReport(com.haulmont.reports.entity.Report, java.util.Map<java.lang.String,java.lang.Object>)
l37sedoc
(Lloyd S)
May 14, 2021, 3:57pm
#14
shchienko:
new HashMap<>()
Thanks for the reply Alexander. I still can’t get this to work. So far this is my code but the parameters are still not found.
@Inject
private DataService dataService;
@Inject
private ReportService reportService;
@Inject
private Button reportButton;
@Inject
private Button printButton;
@Inject
private GroupTable payrollItemsTable;
@Subscribe("printBtn")
public void onPrintBtnClick(Button.ClickEvent event) throws IOException, PrinterException {
LoadContext<Report> lContext = new LoadContext<>(Report.class);
lContext.setQueryString("select r from report$Report r where r.code = 'werknemers_loonstrook'");
Report report = dataService.load(lContext);
Map<String, Object> params = new HashMap<>();
super.init(params);
ReportOutputDocument reportOutputDocument = reportService.createReport(report, new HashMap<>(params));
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(reportOutputDocument.getContent());
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
String printServiceName = service.getName();
PDDocument document = PDDocument.load(byteArrayInputStream);
PrintService myPrintService = findPrintService(printServiceName);
PrinterJob job = PrinterJob.getPrinterJob();
job.setPageable(new PDFPageable(document));
job.setPrintService(myPrintService);
job.print();
}
protected PrintService findPrintService(String printerName) {
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
for (PrintService printService : printServices) {
if (printService.getName().trim().equals(printerName)) {
return printService;
}
}
return null;
}
l37sedoc
(Lloyd S)
May 14, 2021, 10:25pm
#15
With this code the problem is partly solved. If i don’t select a record i still get the error message that the parameter is not found, where else i should expect an error like “No record selected”. When i select a record the document is sent to my printer. That woks fine. Although the output is not aligned al the template, but that’s another problem. Maybe a preview before printing could solve that problem. Any ideas how to do that?
So for anyone who needs it this is the code:
@Inject
private DataService dataService;
@Inject
private ReportService reportService;
@Inject
private Button reportButton;
@Inject
private Button printButton;
@Inject
private GroupTable payrollItemsTable;
@Subscribe("printBtn")
public void onPrintBtnClick(Button.ClickEvent event) throws IOException, PrinterException {
Map<String, Object> reportParams = new HashMap<>();
reportParams.put("entity", payrollItemsTable.getSingleSelected());
LoadContext<Report> lContext = new LoadContext<>(Report.class);
lContext.setQueryString("select r from report$Report r where r.code = 'contractors_loonstrook'");
Report report = dataService.load(lContext);
ReportOutputDocument reportOutputDocument = reportService.createReport(report, reportParams);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(reportOutputDocument.getContent());
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
String printServiceName = service.getName();
PDDocument document = PDDocument.load(byteArrayInputStream);
PrintService myPrintService = findPrintService(printServiceName);
PrinterJob job = PrinterJob.getPrinterJob();
job.setPageable(new PDFPageable(document));
job.setPrintService(myPrintService);
job.print();
}
protected PrintService findPrintService(String printerName) {
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
for (PrintService printService : printServices) {
if (printService.getName().trim().equals(printerName)) {
return printService;
}
}
return null;
}