Add sub report to main report in JasperReport - jasper-reports

I have a Report that shows its items as it should.
Now i need to add 3 sub reports to the main one.
For this i used iReports.
My question is, how do i pass the list of items to the sub reports ???
I found some tutorials but in those cases the sub reports's data is inside of the first reports.
In my case, i have a report with 4 detail band, 3 of this with a sub report.
My code:
JRBeanCollectionDataSource beanCollection = new JRBeanCollectionDataSource(report.getList());
jasperPrint = JasperFillManager.fillReport("C:\\Users\\Desktop\\Report.jasper", new HashMap(), beanCollection) ;
HttpServletResponse http = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
http.addHeader("Content-disposition", "attachment; filename=report.pdf");
ServletOutputStream stream = http.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint, stream);
I am using jsf 2.0.
ps: i saw i can create 4 jasperPrint, and add each page to the main report but i would like to know if its possible what i looking for.
Regards.

Suppose your datasource has the following structure
public class MyPOJO{
private List<POJOSubData1> sub1;
private List<POJOSubData2> sub2;
private List<POJOSubData3> sub3;
//getters & setters
...
}
You can pass the desired datasource to your subreports by specifying the following to the subreport's properties
Connection type : Use a datasource expression
Data Source Expression : $F{sub1} //or sub2 or sub3
The Field Class of sub1 should be List.
Also, you dont need to put isolate 1 subreport to 1 detail band, you can put all the subreports in one detail band.

If you are using Ireport to create reports then open main report in Ireport and selelect Subreport and go to property section of the report, click on "Parameters" property and click on "Copy from master" tab, from there you can select the parameters which you want to pass to the sun report.

what i finally did :
for(JRPrintPage p : jasperPrint1.getPages()){
jasperPrint.addPage(p);
}
where jasperPrint is the main report and jasperPrint1 is the subreport(that is a report it self). On this way, i can pass the list of items to all the reports normally.
JRBeanCollectionDataSource beanCollection1 = new JRBeanCollectionDataSource(report.getSections().get(1).getRowsReports());
JasperPrint jasperPrint1 = JasperFillManager.fillReport("C:\\Users\\Desktop\\Meeting.jasper", new HashMap(), beanCollection1) ;

Related

Chart localization in JasperReports

I'm using JasperReports 5.5.1 to generate reports from Java. I designed the reports using Jaspersoft Studio. The report has several charts of different types and I have some problems when trying to localize the report using a ResourceBundle passed in the REPORT_RESOURCE_BUNDLE parameter. All the texts in the report are translated correctly except for the ones in the charts. I filled the keyExpression, labelExpression and seriesExpression with $R{STRING_KEY}, but the report is filled with the STRING_KEY instead of its value in the properties file. The title of the charts though is correctly translated.
Can anyone help me with this issue?
I found a solution.
First create a class responsible for getting the localized string from a specific resource bundle.
public class ReportLocalizer {
private static String resourceBundleBaseName = "com.company.package.boundle_name";
public static String getLocalizedString(Locale locale, String key) {
ResourceBundle resourceBundle = ResourceBundle.getBundle(resourceBundleBaseName, locale);
return resourceBundle.getString(key);
}
}
Set the desired locale using JasperReports' parameters:
Map<String, Object> parameters = new HashMap<String, Object>();
...
parameters.put(JRParameter.REPORT_LOCALE, locale);
...
final JasperPrint print = JasperFillManager.fillReport(report, parameters, datasource);
To translate a string in a chart, pass it together with the report's locale to ReportLocalizer's getLocalizedString method.
[CDATA[com.company.package.ReportLocalizer.getLocalizedString($P{REPORT_LOCALE}, "string_key")]]>
For example, we can localize a pie chart showing the amount of men and women this way:
<pieChart>
<chart>
...
</chart>
<pieDataset>
<dataset>
...
</dataset>
<keyExpression><![CDATA[com.company.package.ReportLocalizer.getLocalizedString($P{REPORT_LOCALE}, $F{gender}.toString())]]></keyExpression>
<valueExpression><![CDATA[$F{amount}]]></valueExpression>
<labelExpression><![CDATA[String.valueOf($F{amount})]]></labelExpression>
</pieDataset>
<piePlot>
...
</piePlot>
</pieChart>

GXT Grid export to excel file

I am using GXT.
I have a Grid.
com.sencha.gxt.widget.core.client.grid.Grid<RiaBean> grid;
I want to export this to excel file.
i dont want to use external Jar files.
Can any body Help.
Your Grid is composed of ColumnConfig<RiaBean,?>.
Every ColumnConfig<RiaBean,?> is linked to a ValueProvider<RiaBean,?>. Every ValueProvider<RiaBean,?> contains a methodgetPath() which is intended to return the path of the displayed elements.
Hence, you can easily get the paths of your displayed elements, send them to the server and get back the value by Introspection or EL.
For example, let's take this class
public class RIABean{
private String a;
private Integer b;
private Boolean c;
private Integer idFoo;
}
Use an interface which extends PropertyAccess to easily define your ValueProviders. It will also generate the methods getPath() with the accurate value.
public interface RIABeanPropertyAccess extends PropertyAccess<RIABean>{
//The generated getPath() method returns "a"
ValueProvider<RIABean,String> a();
//The generated getPath() method returns "b"
ValueProvider<RIABean,Integer> b();
//The generated getPath() method returns "c"
ValueProvider<RIABean, Boolean> c();
//The generated getPath() method returns "foo.id"
#Path("foo.id")
ValueProvider<RIABean, Integer> idFoo();
}
Create the ColumnModel for your grid:
RIABeanPropertyAccess pa=GWT.create(RIABean.class);
List<ColumnConfig<RIABean,?>> listCols=new ArrayList<ColumnConfig<RIABean,?>>();
listCols.add(new ColumnConfig(pa.a(),100,"Header text for column A");
listCols.add(new ColumnConfig(pa.b(),100,"Header text for column B");
listCols.add(new ColumnConfig(pa.c(),100,"Header text for column C");
ColumnModel colModel=new ColumnModel(listCols);
When the user clicks on "export" button, just iterate on the list of ColumnConfig<RiaBean,?> of your grid in order to get the Path of each of them and send this list of paths to the server. The server might then use introspection/reflexion/EL to get the values corresponding to each path.
There is no way to generate the file on client side. As the server must do it, it is the easiest way I know and that's what we do in my team.
Finally, ask yourself if you really need an excel file or if a csv file would be enough. The csv file can easily be done without any library and can be opened with Excel.

How to replace an existing collection on an Entity Frameworks POCO object

Let's say I create a new Entity and Save it as follows:
UserReport report = new UserReport() {//set the props}
manager.SaveUserReport(report)
Public UserReport SaveUserReport(UserReport report)
{
using(var context = new ReportDatabase())
{
context.UserReports.AdObject(report);
context.SaveChanges();
}
return report;
}
so far so good
I then read back the saved Report
savedReport = manager.GetUserReports(new int[] {report.Id}).FirstOrDefault();
Public List<UserReport> GetUserReports(IEnumerable<int> reportIds)
{
using (var context = new ReportDatabase())
{
var reports = from UserReport in context.UserReports
where reportIds.Contains(userReport.Id)
select userReport;
return visibleReports.ToList();
}
}
savedReport is now an attached UserReport
The UserReport object has a collection of Columns attached to it.
I want to replace the set of Columns attached with another set (that already exist in the database).
savedReport.Columns = newColumnCollection
This fails with the error "The property Columns" on type UserReport_etc' cannot be set because the collection is already set to an EntityCollection"
I've looked at this article: the problem is the same, but I cannot use that solution.
What is the correct way to tackle this?
OK - looks like it's just a case of setting the non-navigation properties to not be virtual.
That is one hell of a weird situation, given that the behaviour that is modified is of properties that remain as virtual.

How Vector<Vector> Receipt used as JasperReports DataSource with Java?

I have a Vector receiptOrder and I want to print that receipt to thermal printer using iReport.
I get 3 classes:
MyDataSource which implements JRDataSource
MyDataSourceProvider which implements JRDataSourceProvider
JRBasicField which implements JRField
How I can setup the JasperReports datasource with that vector?
i made this changes .
load jrxml file
JasperDesign jasperDesign = JRXmlLoader.load("c:/PrintReceipt.jrxml");
JasperReport jr = JasperCompileManager.compileReport(jasperDesign);
pass orderRows which is Vector<Vector> to MyDataSourceProvider then Create datasource
JRDataSourceProvider dsp = new MyDataSourceProvider(orderRows);
JRDataSource dataSource = dsp.create(jr);
JasperPrint jasperPrint = JasperFillManager.fillReport(jr, new HashMap(), dataSource);
JasperExportManager.exportReportToPdfFile(jasperPrint, "c:/test.pdf");
JasperViewer.viewReport(jasperPrint);
but JasperReport show me empty view and also test.pdf is empty .
any idea ...?
I fixed my problem .
The problem because of MyDataSourceProvider fields didn't match ireport.jrxml fields
After i fix that problem All thing work good .

passing value dynamically to the JASPER API to generate a Report

I am generating the Report using the Jasper Reports .
Inside the JRXML file in queryString , the query that is formed is
SELECT * FROM Address WHERE city = $P{customerId}
Now inside my servlet please tell me how can i pass this value dynamically ??
int custid = Integer.parseInt(request.getParameter("customerId")) ;
Map parameters = new HashMap();
parameters.put("customerId", custid);
Please tell me is this the correct way of passing the data ??
You can implement your own datasource (must be net.sf.jasperreports.engine.JRDataSource interface implementation).
After filling (preparing) datasource it should be passed to the JasperFillManager.fillReport(java.lang.String sourceFileName, java.util.Map parameters, JRDataSource jrDataSource) method.
The sample:
JRMapArrayDataSource dataSource = new JRMapArrayDataSource(data);
JasperPrint jasperPrint = JasperFillManager.fillReport(sourceFileName, paramsMap, dataSource);