Embedded PDF stream from JasperReport

I’m learning a library from http://dynamicreports.sourceforge.net/
My problem is just connecting it with Embedded class from vaadin.

The following code compile perfectly but nothing displayed:

What’s wrong with it???

[size=2]





import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.HashMap;

import com.vaadin.Application;
import com.vaadin.terminal.ClassResource;
import com.vaadin.terminal.ExternalResource;
import com.vaadin.terminal.FileResource;
import com.vaadin.terminal.Resource;
import com.vaadin.terminal.StreamResource;
import com.vaadin.terminal.Terminal;
import com.vaadin.ui.Embedded;
import com.vaadin.ui.Window;

import net.sf.dynamicreports.examples.DataSource;
import net.sf.dynamicreports.jasper.builder.JasperReportBuilder;
import net.sf.dynamicreports.report.builder.DynamicReports;
import net.sf.dynamicreports.report.builder.column.Columns;
import net.sf.dynamicreports.report.builder.component.Components;
import net.sf.dynamicreports.report.builder.datatype.DataTypes;
import net.sf.dynamicreports.report.exception.DRException;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperRunManager;



///////////////////////////////////////////////////////////

public void build(Application app) throws IOException, DRException {

                final JasperReportBuilder report = DynamicReports.report();
		report.addColumn(Columns.column("Item",       "item",      DataTypes.stringType()));
		report.addColumn(Columns.column("Quantity",   "quantity",  DataTypes.integerType()));
		report.addColumn(Columns.column("Unit price", "unitprice", DataTypes.bigDecimalType()));
		report.addTitle(Components.text("Getting started"));
		report.addPageFooter(Components.pageXofY());
		report.setDataSource(createDataSource());
		
		Embedded c = new Embedded();
		StreamResource.StreamSource resstream = new StreamResource.StreamSource() {
			
			@SuppressWarnings("rawtypes")
			@Override
			public InputStream getStream() {
				//
				byte[] b = null;
				try {
					b = JasperRunManager.runReportToPdf(report.toJasperReport(), new HashMap());
				} catch (JRException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (DRException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				int ii = b.length;
				return new ByteArrayInputStream(b);
			}
		};
		
		//
		StreamResource ress = new StreamResource(resstream, "abc.pdf", app);
		
		//
		ress.setMIMEType("application/pdf");
		c.setMimeType("application/pdf");
		c.setType(Embedded.TYPE_OBJECT);
		c.setSizeFull();
		c.setHeight("800px");
		c.setSource(ress);
		c.setParameter("Content-Disposition", "attachment; filename=" + ress.getFilename());	
		
		//
		app.getMainWindow().removeAllComponents();
		app.getMainWindow().addComponent(c);

}


        //
	//
	//
	private JRDataSource createDataSource() {
		DataSource dataSource = new DataSource("item", "quantity", "unitprice");

		dataSource.add("Notebook", 1, new BigDecimal(500));
		dataSource.add("DVD", 5, new BigDecimal(30));
		dataSource.add("DVD", 1, new BigDecimal(28));
		dataSource.add("DVD", 5, new BigDecimal(32));
		dataSource.add("Book", 3, new BigDecimal(11));
		dataSource.add("Book", 1, new BigDecimal(15));
		dataSource.add("Book", 5, new BigDecimal(10));
		dataSource.add("Book", 8, new BigDecimal(9));
		return (JRDataSource) dataSource;
	}

[/size]

[size=2]



/* Dynamic reports - Free Java reporting library for creating reports dynamically
 *
 * (C) Copyright 2010 Ricardo Mariaca
 *
 * http://dynamicreports.sourceforge.net
 *
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as published by 
 * the Free Software Foundation; either version 3 of the License, or 
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
 * USA. 
 */
package net.sf.dynamicreports.examples;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;

/**
 * @author Ricardo Mariaca (dynamicreports@gmail.com)
 */
public class DataSource implements JRDataSource {
	private String[] columns;
	private List<Map<String, Object>> values;
	private Iterator<Map<String, Object>> iterator;
	private Map<String, Object> currentRecord;

	public DataSource(String ...columns) {	
		this.columns = columns;
		this.values = new ArrayList<Map<String, Object>>();		
	}
	
	public void add(Object ...values) {
		Map<String, Object> row = new HashMap<String, Object>();
		for (int i = 0; i < values.length; i++) {
			row.put(columns[i]
, values[i]
);
		}
		this.values.add(row);
	}

	public Object getFieldValue(JRField field) throws JRException {
		return currentRecord.get(field.getName());
	}

	public boolean next() throws JRException {
		if (iterator == null) {
			this.iterator = values.iterator();
		}
		boolean hasNext = iterator.hasNext();			
		if (hasNext) {
			currentRecord = iterator.next();
		}
		return hasNext;
	}		
}


[/size]

At least this is in wrong place:

The content-disposition header should be part of the pdf stream’s http headers. Parameters in the Embedded component are just a way to pass information to the plugin (if any) used to display the embedded data. For example in case of Java applets and Flash objects.

However, this is not probably the problem here. I cannot say for sure, but if you could catch the URL to the PDF stream using Firebug or similar (client-side) debug tool you can see wheter the problem is in the PDF creation or in the way how it is presented in Embedded.

Thank you for the reply Sam,

I’ve carefully debug my code but apparently, the function getStream() never get called so the export to PDF is of course never get called as well.

the following code I hope make everyone clear the real problem of mine.

I have a problem integrating dynamicreports which is based on jasperreport with vaadin class named “Embedded”. The “Embedded” class needs StreamResource object and all will be ended implementing getStream() function which is, in my case, never get called.

[size=3]



Here is my code:


	//
	//
	//
	public void build(Application app) throws IOException, DRException {
		
		final JasperReportBuilder report = DynamicReports.report();
		report.addColumn(Columns.column("Item",       "item",      DataTypes.stringType()));
		report.addColumn(Columns.column("Quantity",   "quantity",  DataTypes.integerType()));
		report.addColumn(Columns.column("Unit price", "unitprice", DataTypes.bigDecimalType()));
		report.addTitle(Components.text("Getting started"));
		report.addPageFooter(Components.pageXofY());
		report.setDataSource(createDataSource());
		
		StreamResource.StreamSource resstream = new filePDF(report);
		StreamResource ress = new StreamResource(resstream, "abc.pdf", app);
		
		//
		ress.setMIMEType("application/pdf");
		
		//
		Embedded c = new Embedded("Title", ress);
		c.setSource(ress);
		c.setMimeType("application/pdf");
		c.setType(Embedded.TYPE_BROWSER);
		c.setSizeFull();
		c.setHeight("800px");
		c.setParameter("Content-Disposition", "attachment; filename=" + ress.getFilename());
		
		//
		app.getMainWindow().removeAllComponents();
		app.getMainWindow().addComponent(c);
	}

	//
	//
	//
	private JRDataSource createDataSource() {
		DataSource dataSource = new DataSource("item", "quantity", "unitprice");

		dataSource.add("Notebook", 1, new BigDecimal(500));
		dataSource.add("DVD", 5, new BigDecimal(30));
		dataSource.add("DVD", 1, new BigDecimal(28));
		dataSource.add("DVD", 5, new BigDecimal(32));
		dataSource.add("Book", 3, new BigDecimal(11));
		dataSource.add("Book", 1, new BigDecimal(15));
		dataSource.add("Book", 5, new BigDecimal(10));
		dataSource.add("Book", 8, new BigDecimal(9));
		return (JRDataSource) dataSource;
	}

[/size]

And this is “filePDF” class:

[size=3]



	/**
	 * 
	 */
	package com.example.postgrekonek;

	import java.io.ByteArrayInputStream;
	import java.io.ByteArrayOutputStream;
	import java.io.IOException;
	import java.io.InputStream;
	import java.util.HashMap;

	import net.sf.dynamicreports.jasper.builder.JasperReportBuilder;
	import net.sf.dynamicreports.report.exception.DRException;
	import net.sf.jasperreports.engine.JRException;
	import net.sf.jasperreports.engine.JasperRunManager;

	import com.vaadin.Application;
	import com.vaadin.terminal.StreamResource;

	/**
	 * @author hehehe
	 *
	 */
	public class filePDF implements StreamResource.StreamSource {
		
		private JasperReportBuilder report;
		
		//
		public filePDF(final JasperReportBuilder rpt) {
			report = rpt;
		}
		
		@Override
		public InputStream getStream() {
			//
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			
			//
			//os.write(JasperRunManager.runReportToPdf(report.toJasperReport(), new HashMap()));
			try {
				report.toPdf(os);
				try {
					os.flush();
				} catch (IOException e) {
					//
					e.printStackTrace();
				}
			} catch (DRException e) {
				//
				e.printStackTrace();
			}
			return new ByteArrayInputStream(os.toByteArray());
		}

	}



[/size]

And this is “Datasource” class:

[size=3]



	/* Dynamic reports - Free Java reporting library for creating reports dynamically
	 *
	 * (C) Copyright 2010 Ricardo Mariaca
	 *
	 * http://dynamicreports.sourceforge.net
	 *
	 * This library is free software; you can redistribute it and/or modify it 
	 * under the terms of the GNU Lesser General Public License as published by 
	 * the Free Software Foundation; either version 3 of the License, or 
	 * (at your option) any later version.
	 *
	 * This library is distributed in the hope that it will be useful, but 
	 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
	 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
	 * License for more details.
	 *
	 * You should have received a copy of the GNU Lesser General Public
	 * License along with this library; if not, write to the Free Software
	 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
	 * USA. 
	 */
	package net.sf.dynamicreports.examples;

	import java.util.ArrayList;
	import java.util.HashMap;
	import java.util.Iterator;
	import java.util.List;
	import java.util.Map;

	import net.sf.jasperreports.engine.JRDataSource;
	import net.sf.jasperreports.engine.JRException;
	import net.sf.jasperreports.engine.JRField;

	/**
	 * @author Ricardo Mariaca (dynamicreports@gmail.com)
	 */
	public class DataSource implements JRDataSource {
		private String[] columns;
		private List<Map<String, Object>> values;
		private Iterator<Map<String, Object>> iterator;
		private Map<String, Object> currentRecord;

		public DataSource(String ...columns) {	
			this.columns = columns;
			this.values = new ArrayList<Map<String, Object>>();		
		}
		
		public void add(Object ...values) {
			Map<String, Object> row = new HashMap<String, Object>();
			for (int i = 0; i < values.length; i++) {
				row.put(columns[i]
, values[i]
);
			}
			this.values.add(row);
		}

		public Object getFieldValue(JRField field) throws JRException {
			return currentRecord.get(field.getName());
		}

		public boolean next() throws JRException {
			if (iterator == null) {
				this.iterator = values.iterator();
			}
			boolean hasNext = iterator.hasNext();			
			if (hasNext) {
				currentRecord = iterator.next();
			}
			return hasNext;
		}		
	}



[/size]

The following code configures Embedded in very minimalistic way to show a PDF:[code]

Embedded c = new Embedded();
c.setSource(new ExternalResource(“http://dev.vaadin.com/export/8173/doc/trunk/cheatsheet/vaadin-cheatsheet-duplex.pdf”));
c.setType(Embedded.TYPE_BROWSER);
layout.addComponent(c);

[/code](try live here:
http://uilder.virtuallypreinstalled.com/run/Embedded_PDF/
)

This only uses an
ExternalResource
instead of
StreamResource
.

This suggests that the URL to the StreamResource is never called and something very basic is wrong here. Unfortunately, I’m unable to spot the problem in the code. Are you sure the Embedded is visible? You can try with above code and external PDF first that the Embedded works as you like. After that see that the getStream and generation code is ok.

Try setting your embedded component’s width and height using pixel size (px) and remove the call to setSizeFull. Also, see if you can use the FileResource rather than the StreamResource. I’ve had success using the FileResource, but not the StreamResource as of yet.