I´m facing one problem, I have two jrmxl files. I want to join then in one pdf file, but each in one page.
I saw some tips below but I don´t know if they are the best, because my first file have 3 bands: title, detail and summary. The second have detail and summary.
So I want to keep this format if is possible, because in the summary have the page counter.
I´ve tried this but my second page is blank and have 5 cm of heigth.
List pages = new ArrayList<>();
for (String caminhoRelatorio : caminhoRelatorios) {
reportPath = JasperCompileManager.compileReport(caminhoRelatorio);
reportPage = JasperFillManager.fillReport(reportPath, parameters, ds);
pages.add(reportPage);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
JRPdfExporter jrPdfExporter = new JRPdfExporter();
jrPdfExporter.setParameter(JRExporterParameter.JASPER_PRINT_LIST, pages);
jrPdfExporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);
jrPdfExporter.setParameter(JRPdfExporterParameter.IS_CREATING_BATCH_MODE_BOOKMARKS, Boolean.TRUE);
jrPdfExporter.exportReport();
So what I need to do?
To add multiple JRXMLs in one report/PDF, you can follow the below mentioned way:
Consider the method below to generate a PDF report with 2 JRXMLs which have added in the "jrxmlFileNames" list
public static void reportGenerator(String reportType, List<String> jrxmlFileNames,
Datasource dataSource , String SwapFile)
{
JRConcurrentSwapFile swapFile = new JRConcurrentSwapFile(SwapFile, 102400 , 10);
JRAbstractLRUVirtualizer virtualizer = new JRSwapFileVirtualizer(1000, swapFile, true);
Map<String, JRAbstractLRUVirtualizer> parameters = new HashMap<String, JRAbstractLRUVirtualizer>();
parameters.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);
try
{
if (reportType.equalsIgnoreCase("PDF"))
{
try
{
JasperReport jreport1 = JasperCompileManager.compileReport(ReportGenerator.class.getResourceAsStream(jrxmlFileNames.get(0)));
JasperPrint jprint1 = JasperFillManager.fillReport(jreport1, parameters, new JRBeanCollectionDataSource(dataSource.getDataSourceFor1()));
JasperReport jreport2 = JasperCompileManager.compileReport(ReportGenerator.class.getResourceAsStream(jrxmlFileNames.get(1)));
JasperPrint jprint2 = JasperFillManager.fillReport(jreport2, parameters, new JRBeanCollectionDataSource(dataSource.getDataSourceFor2()));
List<JasperPrint> jprintlist = new ArrayList<JasperPrint>();
jprintlist.add(jprint1);
jprintlist.add(jprint2);
String fileName="TESTReport.pdf";
JRExporter exporter = new JRPdfExporter();
exporter.setParameter(JRPdfExporterParameter.JASPER_PRINT_LIST, jprintlist);
exporter.setParameter(JRPdfExporterParameter.OUTPUT_FILE_NAME, fileName);
exporter.exportReport();
}
catch(Exception e)
{
e.printStackTrace();
}
}
swapFile.dispose();
}
catch(Exception e)
{
e.printStackTrace();
}
}
In the above code the following part will help you adding the multiple JRXMLs
List<JasperPrint> jprintlist = new ArrayList<JasperPrint>();
jprintlist.add(jprint1);
jprintlist.add(jprint2);
JRExporter exporter = new JRPdfExporter();
exporter.setParameter(JRPdfExporterParameter.JASPER_PRINT_LIST, jprintlist);
Hope it helps!
To get two pages in report you can use Report group and delete all other bands like detail, summary.
To add report group :-
1:- Open report and in Report inspector right click and select "Add Report Group".
2:- Give any name and choose "Group by the following expression" radio button and leave the expression blank and then Next, select only Report header and then finish.
3:- Now for the second page you can add one more Report Group in the same way.
Here there is a similar question: How do i add a second page on Jaspersoft iReport designer. There is also a simpler way: Put a Page Break component on your Detail Band, which means, drag and drop a 'Break' component, and on the popUp that will get displayed select "Page Break"
Related
I have created two report jrxml with jasper report. In my java program I merge the two report into one PDF with iText.
The problem is that the pdf contains only one report plus a blank page.
I have also done this proof:
in my java program creation report one creation report two, merge and I see pdf containig only report one plus blank page
in my java program creation report two and then creation report one, merge and I see pdf containing only report two plus blank page
I have to obtain the pdf with both reports
Does someone help me to solve the problem?
Thanks in advance
Attach the code of my java program:
#Name("pdfFactory")
public class PdfScalareFactory {
private static final String JASPER_FILE_MOVIMENTI = "scalarePdf/pdf_movimenti.jrxml";
private static final String JASPER_FILE_SCALARE = "scalarePdf/pdf_scalare.jrxml";
#SuppressWarnings("rawtypes")
public byte[] rawPdf(BeScalare beScalare, String codTabulato, String output) throws JRException, IOException {
JRBeanArrayDataSource dataSource = new JRBeanArrayDataSource(new Object[]{beScalare});
//report's list
List<byte[]> pdfFilesAsByteArray = new ArrayList<byte[]>();
//Report one
Class cScalare = this.getClass();
ClassLoader clScalare = cScalare.getClassLoader();
InputStream isScalare = clScalare.getResourceAsStream(JASPER_FILE_SCALARE);
JasperDesign jasDesignScalare = JRXmlLoader.load(isScalare);
//compile report one
JasperReport reportScalare = JasperCompileManager.compileReport(jasDesignScalare);
//parameters report one
Map<String, Object> paramScalare = new HashMap<String, Object>();
JRBeanCollectionDataSource itemsScalareSaldiPerValuta = new JRBeanCollectionDataSource(beScalare.getLstBeScalareSaldiPerValuta());
paramScalare.put("scalareSaldiPerValuta", itemsScalareSaldiPerValuta);
//fill report one
JasperPrint jasperPrintScalare = JasperFillManager.fillReport(reportScalare, paramScalare, dataSource);
pdfFilesAsByteArray.add(JasperExportManager.exportReportToPdf(jasperPrintScalare));
//Report two
Class c = this.getClass();
ClassLoader cl = c.getClassLoader();
InputStream is = cl.getResourceAsStream(JASPER_FILE_MOVIMENTI);
JasperDesign jasDesign = JRXmlLoader.load(is);
//compile report two
JasperReport reportMovimenti = JasperCompileManager.compileReport(jasDesign);
//parameters report two
Map<String, Object> paramMovimenti = new HashMap<String, Object>();
BufferedImage imgNumeroVerde = ImageIO.read(getClass().getResource("/scalarePdf/headphones.png"));
paramMovimenti.put("numeroVerde", imgNumeroVerde);
BufferedImage imgInternet = ImageIO.read(getClass().getResource("/scalarePdf/internet.png"));
paramMovimenti.put("internet", imgInternet);
JRBeanCollectionDataSource itemsScalareMovimenti = new JRBeanCollectionDataSource(beScalare.getLstBeScalareMovimenti());
paramMovimenti.put("scalareMovimenti", itemsScalareMovimenti);
//fill report two
JasperPrint jasperPrintMovimenti = JasperFillManager.fillReport(reportMovimenti, paramMovimenti, dataSource);
pdfFilesAsByteArray.add(JasperExportManager.exportReportToPdf(jasperPrintMovimenti));
//merge the two reports in one
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
Document document = null;
PdfCopy writer = null;
for (byte[] pdfByteArray : pdfFilesAsByteArray) {
try {
PdfReader reader = new PdfReader(pdfByteArray);
int numberOfPages = reader.getNumberOfPages();
if (document == null) {
document = new Document(reader.getPageSizeWithRotation(1));
writer = new PdfCopy(document, outStream); // new
document.open();
}
PdfImportedPage page;
for (int i = 0; i < numberOfPages;) {
++i;
page = writer.getImportedPage(reader, i);
writer.addPage(page);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
document.close();
outStream.close();
return outStream.toByteArray();
}
}
Problem is in the data source and not in merging. You create one data source for both reports but the first report will consume it and then the second report has data source with pointer at the end.
You use JRBeanArrayDataSource which implements JRRewindableDataSource so you can call the moveFirst() method to return data source pointer on the first position:
//Report two
dataSource.moveFirst();
Or you can create the data source again for the second report:
//Report two
dataSource = new JRBeanArrayDataSource(new Object[]{beScalare});
Note: But as Amongalen mentioned in the comment it is easier to merge two and more Jasper reports using JRPdfExporter and List<JasperPrint> instance as an input.
I have a problem, i generate XLSX with JasperReports, but if i want print document, he's break page not correctly.
I need last page footer not split.
I can't use ignorePagination or ignoreMargins, because they delete space (delete page break) and my last page footer split on another page...
Split type on last page footer set Prevent
What do you recommend to me?
JasperReports library - 6.3.0
iReport - 5.6.0
Java - 1.8
MS Excel - 2016
My report design:
The generated XLSX file looks like:
You can see, if page break move on 1 cell down, page print correctly, but i can't open every document for correction him
The splitType for lastPageFooter is set as Prevent.
Java code
public void createReport(Map<String,Object> dataMap, HttpServletResponse response, HttpServletRequest request){
String pathToServletRoot = request.getSession(true).getServletContext().getRealPath("/");
String sourceFileName = pathToServletRoot + "/resources/template/jasper/reportT12.jasper";
try {
ArrayList<DataBean> dataList = dataBeanArrayList(dataMap);
JRBeanCollectionDataSource beanColDataSource = new JRBeanCollectionDataSource(dataList);
Map parameters = new HashMap();
try {
JasperPrint jasperPrint = JasperFillManager.fillReport(sourceFileName,
parameters, beanColDataSource);
JRXlsxExporter exporter = new JRXlsxExporter();
ByteArrayOutputStream xlsxReport = new ByteArrayOutputStream();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(xlsxReport));
SimpleXlsxReportConfiguration configuration = new SimpleXlsxReportConfiguration();
configuration.setOnePagePerSheet(false);
configuration.setDetectCellType(true);
exporter.setConfiguration(configuration);
exporter.exportReport();
response.getOutputStream().write(xlsxReport.toByteArray());
} catch (JRException e) {
e.printStackTrace();
}
} catch(Exception ex) {
CrmLogger.error(ex);
}
}
I have made an application in Java. For the application bill receipt is required and I have used JasperReports (.jrxml ) file.
I have used JasperReports call in Java code for the generating bill.
When I click on print bill the print is not proper, size is reduced.
Actually the problem is strange. I am working on desktop computer and when I print from it , the print is ok.. but when I move my project to other system (say, Laptop) The print I get is approx 50% reduced than the original print. Is there any problem with iReport?
I have used below Java code:
public static void main(String[] args) throws JRException,
ClassNotFoundException, SQLException {
String reportSrcFile = "F:/Bills/FirstJasperReport.jrxml";
// First, compile jrxml file.
JasperReport jasperReport = JasperCompileManager.compileReport(reportSrcFile);
Connection conn = ConnectionUtils.getConnection();
// Parameters for report
Map<String, Object> parameters = new HashMap<String, Object>();
JasperPrint print = JasperFillManager.fillReport(jasperReport,
parameters, conn);
// Make sure the output directory exists.
File outDir = new File("C:/jasperoutput");
outDir.mkdirs();
// PDF Exportor.
JRPdfExporter exporter = new JRPdfExporter();
ExporterInput exporterInput = new SimpleExporterInput(print);
// ExporterInput
exporter.setExporterInput(exporterInput);
// ExporterOutput
OutputStreamExporterOutput exporterOutput = new SimpleOutputStreamExporterOutput(
"C:/jasperoutput/FirstJasperReport.pdf");
// Output
exporter.setExporterOutput(exporterOutput);
//
SimplePdfExporterConfiguration configuration = new SimplePdfExporterConfiguration();
exporter.setConfiguration(configuration);
exporter.exportReport();
System.out.print("Done!");
}
How to resolve this issue
I was facing the same issue. It is kind weird but when I search at Jasper Community I had found the solution
The code solved the problem
PrintRequestAttributeSet printRequestAttrs = new HashPrintRequestAttributeSet();
printRequestAttrs.add(new PrinterResolution(600, 600, ResolutionSyntax.DPI)); // this resolution solved the problem
JRPrintServiceExporter exporter = new JRPrintServiceExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, report);
exporter.setParameter(JRPrintServiceExporterParameter.PRINT_REQUEST_ATTRIBUTE_SET, printRequestAttrs);
exporter.setParameter(JRPrintServiceExporterParameter.DISPLAY_PRINT_DIALOG, Boolean.TRUE);
exporter.exportReport();
Hope this will help!
Have you tried checking the printer properties before printing? Maybe The size of your report template does not match with the paper size set on the printer.
I have two JRXML File with two different data source.
in first jasper report data source is JRXmlDataSource and in second jasper report data source is JRResultSetDataSource
try
{
conn= objConnector.getConnection();
conn.setAutoCommit(false);
PreparedStatement ps = conn.prepareCall("{ call Sp_DEMO(?) }");
ps.setString(1,condition);
ResultSet rs = ps.executeQuery();
JasperReport jreport1 = JasperCompileManager.compileReport("d:\\JRXML\\ECGImage.jrxml");
JasperPrint jprint1 = JasperFillManager.fillReport(jreport1, new HashMap(), new JRResultSetDataSource(rs));
jprintlist.add(jprint1);
JasperReport jasperReport = JasperCompileManager.compileReport("d:\\JRXML\\RadiologyReport.jrxml");
JRXmlDataSource xmlDataSource = new JRXmlDataSource("d:\\abc.xml"+, "/X-RayReport/Type");
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, new HashMap(),xmlDataSource);
jprintlist.add(jasperPrint);
File file = new File("d:\\demo.pdf");
if(file.exists())
{
file.delete();
}
JRExporter exporter = new JRPdfExporter();
exporter.setParameter(JRPdfExporterParameter.JASPER_PRINT_LIST, jprintlist);
OutputStream output = new FileOutputStream(new File("d:\\demo.pdf"));
exporter.setParameter(JRPdfExporterParameter.OUTPUT_STREAM, output);
exporter.exportReport();
}
catch(Exception e)
{
e.printStackTrace();
}
i want to create single pdf file as output from both jrxml file.
You can merge the above two pdf like this
List pages = jasperPrint.getPages();
for (int j = 0; j < pages.size(); j++) {
JRPrintPage object = (JRPrintPage)pages.get(j);
jprint1.addPage(object);
}
And jprint1 will be your single output .
Well, that is what JasperReport Subreports are meant to do. You have to create another .jrxml which would be the master report, and include the other existing two in this one as "Subreports". So you'll have a single output.
To create subreports (if you don't know), please refer to these tutoriale: JasperReports - Create SubReports, SubReports.
From the fact that you have two different data sources, I think that you might as well need to read this too: Pass parameter to subreports.
You might need this to pass the different data sources as parameters to the subreports, thus not in your JasperPrint object instance.
I have no factual defence or argumentation about how I do it normally and all that is just matter of personal preference and the ease that I have during the merging and post-processing stages for adding some general additional stuff to the merged report i.e. page numbers, header, footer, etc.
The correct jasper-report way is to stay away from joining reports in Java and instead, to make a main report and then adding subreports to it. However, if you really want to do that in Java, you can use markers and afterwards post-process everything again, check here.
Still, I just don't do that.
Most of the time I prefer to first generate and export different sections of my final report in pdf separately and afterward merge them all together utilizing PDFBox. By not following the jasper report's way, usually I avoid a hell of subreports hierarchy as normally each section of the final report on their own contain couple of other subreports. So, I just find it better to focus on each section separately and later doing the final merging.
I normally do something like this:
public final class Report
{
List<File> MergingFiles;
ReportData data;
public Report(ReportData data)
{
// I prefer to pack all the data like, jrxml files path or
// the data that fills the report in a separate object -> ReportData
this.data = data;
MergingFiles = new ArrayList<>();
}
private void generateCoverPage() throws JRException
{
/* Setting up the data which needs to be passed to cover page
reading the cover page jrxml file
compiling the report */
// and Exporting - I normally use JRPdfExporter for that
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(data.getCoverPageExportPath()));
exporter.exportReport();
MergingFiles.add(new File(data.getCoverPageExportPath()));
}
private void generateSecondPart() throws JRException
{
/* similar to generateCoverPage() to create another part of the report */
}
public void generateReport()
{
generateCoverPage();
generateSecondPart();
mergePDFFiles(MergingFiles, data.getPrintFileName());
/* Do additional general post process i.e. page numbers, header, footer, etc. here
and then clean up temp files */
}
private void mergePDFFiles(List<File> files, String mergedFileName)
{
// all classes are imported from "org.apache.pdfbox"
try
{
PDFMergerUtility pdfmerger = new PDFMergerUtility();
for (File file : files)
{
PDDocument document;
document = PDDocument.load(file);
pdfmerger.setDestinationFileName(mergedFileName);
pdfmerger.addSource(file);
pdfmerger.mergeDocuments(MemoryUsageSetting.setupTempFileOnly());
document.close();
}
}
catch (IOException e)
{
System.out.println("Error to merge files. Error: " + e.getMessage());
}
}
}
// are just my side notes, however comments surrender with /* */ are the parts which you have to take care of them in case that you wanted to use my approach.
I have one jrxml file that I would like to populate with 3 different datasources. Then I would like to export to an XLS or XLXS file with the 3 reports concatenated together on one sheet.
String input = "C:\\location\\report1.jrxml";
JasperReport jreport = JasperCompileManager.compileReport(input);
JasperPrint jprint1 = JasperFillManager.fillReport(jreport, new HashMap<String, Object>(), new JRBeanCollectionDataSource(getReportData(1)));
JasperPrint jprint2 = JasperFillManager.fillReport(jreport, new HashMap<String, Object>(), new JRBeanCollectionDataSource(getReportData(2)));
JasperPrint jprint3 = JasperFillManager.fillReport(jreport, new HashMap<String, Object>(), new JRBeanCollectionDataSource(getReportData(3)));
List<JasperPrint> jprintlist = new ArrayList<JasperPrint>();
jprintlist.add(jprint1);
jprintlist.add(jprint2);
jprintlist.add(jprint3);
JRXlsxExporter exporter = new JRXlsxExporter();
exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
exporter.setParameter(JRXlsExporterParameter.JASPER_PRINT_LIST, jprintlist);
String xlsFile = "C:\\location\\test.xlsx";
exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, xlsFile);
exporter.exportReport();
The reports are all generating as I would expect, however in excel they are being generated on 3 different tabs, what I would like is to have them be built one on top of another. How can I merge them in this way?
You could be to wrap the 3 reports as sub reports in a master report and run that one instead. In order to do so you would need to add the logic for which data source to access into the subreport's data source expression.
alternatively you could post process the excel sheet outside JasperReports.