Jump to content
We've recently updated our Privacy Statement, available here ×

marciopd

Members
  • Posts

    21
  • Joined

  • Last visited

 Content Type 

Profiles

Forum

Events

Featured Visualizations

Knowledge Base

Documentation (PDF Downloads)

Blog

Documentation (Test Area)

Documentation

Dr. Jaspersoft Webinar Series

Downloads

Posts posted by marciopd

  1. Hi,

    maybe you could pass your data to thereport as a LazyList (a list that gets its data on demand).

    There's an example here:

    http://www.ilikespam.com/blog/paging-large-data-sets-with-a-lazylist)

    You will just have to remember clearing the loaded data in order to avoid memory usage problems.

    Doing this way, you would implement at least two methods: one for retrieving how many results there is in the list; and another for querying the data to be presented, page by page. You can do some tests to figure out the right page size.

    hope it helps, cheers

  2. Guys,

    I have a report which columns are dynamic and the number of columns can be big enough so they don't fit all in one page.

     

    I though the best way to implement this was using crosstabs, because they deal with column breaks automatically.

    The problem with crosstabs is that if the data being rendered is a really big datatable, then the crosstab will eat all memory and crash the report no matter if you're using a virtualizer.

     

    What's the best solution for this situation? (dynamic columns + page column breaks + lots of data)

    Thanks

  3. I think you should take a look at JRBeanCollectionDataSource:

    http://jasperreports.sourceforge.net/api/net/sf/jasperreports/engine/data/JRBeanCollectionDataSource.html

    It's a datasource provided by jasper which you can initialize with a collection of your own java beans.

    Look at the example code below.

    Then the attributes of "YourClass" could be used as fields in the detail section of the report.

    Hope it helps!

    Code:
    ...List<YourClass> yourBeanCollection = queryData();JRDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(yourBeanCollection);JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,				reportParams, beanCollectionDataSource);...
  4. In my case, i'm dealing with large tables.

    I used crosstabs because it deals well with dynamic columns and when theses columns gets larger than the page width.

     

    Can I design a report so that its columns are dynamic and jasper will deal automatically with column breaks?

     

    Thanks for helping

  5. CrossTabDataVO.java

    Code:
    package model; import java.io.Serializable; /** * Data to be used inside crosstab. */public class CrossTabDataVO implements Serializable {     /** serial. */    private static final long serialVersionUID = 3785582945804552430L;     private String state;     private String city;     private String amount;     public String getState() {        return state;    }     public void setState(String state) {        this.state = state;    }     public String getCity() {        return city;    }     public void setCity(String city) {        this.city = city;    }     public String getAmount() {        return amount;    }     public void setAmount(String amount) {        this.amount = amount;    }}
  6. QueryLazyList.java

    Code:
    /** * */package model; import java.util.ArrayList;import java.util.List; /** * Test implementation for a lazy list. */public class QueryLazyList extends AbstractLazyList<CrossTabDataVO> {    /**     * Total number of results.     */    int totalNumberResults = Integer.MAX_VALUE;     public QueryLazyList(int pageSize) {        super(pageSize);    }     @Override    public int getTotalQueryResultsSize() {        return totalNumberResults;    }     @Override    public List<CrossTabDataVO> queryPage(int position, int pageSize) {        List<CrossTabDataVO> resultsPage = new ArrayList<CrossTabDataVO>(pageSize);        for(int i = position; i < position + pageSize; i++) {            CrossTabDataVO crossTabDataVO = new CrossTabDataVO();            crossTabDataVO.setState("State " + i);            crossTabDataVO.setCity("City " + i);            crossTabDataVO.setAmount(i + ",00");            resultsPage.add(crossTabDataVO);        }        return resultsPage;    }}
  7. AbstractLazyList.java

    Code:
    package model;import java.util.AbstractList;import java.util.HashMap;import java.util.List;import java.util.Map;/** * Lazy list to a generic type. */public abstract class AbstractLazyList<T> extends AbstractList<T> {	/**	 * Already loaded data.	 */	private final Map<Integer, T> loadedData;	/**	 * How much itens shoud be retrieved at a query.	 */	private final int pageSize;	/**	 * Constructor with page size.	 * @param pageSize page size	 */	public AbstractLazyList(int pageSize) {		super();		this.pageSize = pageSize;		this.loadedData = new HashMap<Integer, T>(pageSize);	}	@Override	public T get(int position) {		if (!loadedData.containsKey(position)) {			loadedData.clear();			List<T> results = queryPage(position, pageSize);			int index = position;			for (T item : results) {				loadedData.put(index, item);				index++;			}		}		return loadedData.get(position);	}	@Override	public int size() {		return getTotalQueryResultsSize();	}	/**	 * Queries the new page.	 * @param position initial position	 * @param pageSize page size	 * @return results from position to page size	 */	public abstract List<T> queryPage(int position, int pageSize);	/**	 * Returns the total results returned by the query.	 * @return total number of results	 */	public abstract int getTotalQueryResultsSize();}
  8. class that generates the report: ReportServiceImpl.java

    Code:
    package report;import java.util.HashMap;import java.util.Map;import model.QueryLazyList;import net.sf.jasperreports.engine.JREmptyDataSource;import net.sf.jasperreports.engine.JRException;import net.sf.jasperreports.engine.JRParameter;import net.sf.jasperreports.engine.JRVirtualizer;import net.sf.jasperreports.engine.JasperExportManager;import net.sf.jasperreports.engine.JasperFillManager;import net.sf.jasperreports.engine.JasperPrint;import net.sf.jasperreports.engine.JasperReport;import net.sf.jasperreports.engine.fill.JRSwapFileVirtualizer;import net.sf.jasperreports.engine.util.JRSwapFile;import ar.com.fdvs.dj.core.DJConstants;import ar.com.fdvs.dj.core.DynamicJasperHelper;import ar.com.fdvs.dj.core.layout.ClassicLayoutManager;import ar.com.fdvs.dj.domain.DJCalculation;import ar.com.fdvs.dj.domain.DJCrosstab;import ar.com.fdvs.dj.domain.DynamicReport;import ar.com.fdvs.dj.domain.Style;import ar.com.fdvs.dj.domain.builders.CrosstabBuilder;import ar.com.fdvs.dj.domain.builders.DynamicReportBuilder;import ar.com.fdvs.dj.domain.constants.Border;public class ReportServiceImpl {	/**	 * Tmp dir path.	 */	private static final String TMP_DIR_PATH = "/tmp";	/**	 * Generates test report.	 * @return	 * @throws JRException erro	 */	public byte[] generateCrossTabReport() throws JRException {		DynamicReportBuilder drb = new DynamicReportBuilder();;		DJCrosstab djcross = new CrosstabBuilder().setHeight(200).setWidth(500)				.setDatasource("sr",						DJConstants.DATA_SOURCE_ORIGIN_PARAMETER,						DJConstants.DATA_SOURCE_TYPE_COLLECTION,						true)				.setUseFullWidth(true)				.setAutomaticTitle(false)				.setCellBorder(Border.THIN)				.addColumn("State", "state", String.class.getName(), false)				.addRow("City", "city", String.class.getName(),false)				.addMeasure("amount", String.class.getName(),						DJCalculation.NOTHING, "Amount", new Style())				.setCellDimension(17, 60)				.setColumnHeaderHeight(30)				.setRowHeaderWidth(80)				.build();		drb.addHeaderCrosstab(djcross);		DynamicReport dr = drb.build();		// put a collection in the parameters map to be used by the crosstab		Map<String, Object> reportParams = new HashMap<String, Object>();		reportParams.put("sr", getTestDataLazyList());		// set a swap file virtualizer		JRSwapFile swapFile = new JRSwapFile(TMP_DIR_PATH, 1024, 10);		JRVirtualizer virtualizer = new JRSwapFileVirtualizer(1024, swapFile, true);		reportParams.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);		// generates jasper report		JasperReport jasperReport = DynamicJasperHelper.generateJasperReport(dr,			new ClassicLayoutManager(), reportParams);		// fills report and generates jasperprint		JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,			reportParams, new JREmptyDataSource());		// export to pdf bytes		return JasperExportManager.exportReportToPdf(jasperPrint);	}	/**	 * returns test data.	 * @return test data	 */	private QueryLazyList getTestDataLazyList() {		return new QueryLazyList(1000);	}	public static void main(String[] args) throws JRException {		byte[] result = new ReportServiceImpl().generateCrossTabReport();		System.out.println(result.length);	}}
  9. I'm using crosstabs in a possibly pretty large report.

    I designed the report so that the data didn't get all loaded together into memory. Well,  tried :D
    The thing is that it seems that there's a problem with jasperreports' crosstab report filling engine (JRFillCrosstab).

    Using  a eclipse plugin (http://www.eclipse.org/mat/) to analyse the heap dump on out of memory error, i get that

    JRFillCrossTab stores the data in a arraylist that keeps growing and growing...

    Code to reproduce the issue is attached.
    Class ReportServiceImpl has the main method to be executed.
    You should modify the constant ReportServiceImpl.TMP_DIR_PATH to a temporary path in your file system.


    Any help please?



    Post Edited by marciopd at 07/17/2010 05:04
×
×
  • Create New...