This is an extension to the JasperReport step by step tutorial to demonstrate how to generate an Excel file. This extends the tutorial on stand-alone excel file to demonstrate how to produce xls as a file attachment via Spring MVC RESTful service call.
The controller class will be something like
//...
@Controller
public class MyApproller
{
@Resource(name = "myAppService")
private MyAppService myAppService;
@Resource(name = "reportWriter")
private ReportWriter reportWriter;
@RequestMapping(
value = "/person.xls",
method = RequestMethod.GET,
produces = "application/vnd.ms-excel")
@ResponseBody
public void getCashForecastCSV(HttpServletResponse response) throws Exception
{
//get the report data from the service layer
Collection<Person> reportData = myAppService.getReportData();
//get the parameters as a Map from the service layer
Map<String, Object> reportParameters = myAppService.getReportParameters();
//generate the xls report
byte[] xlsAsStringForPerson = reportWriter.getXlsAsStringForPerson(reportData, reportParameters);
response.setContentType("application/vnd.ms-excel");
response.addHeader("Content-Disposition", "attachment; filename=" + "person.xls");
//since binary, write it as stream
response.getOutputStream().write(xlsAsStringForPerson);
}
//..
}
//...........
@Service(value = "myAppService")
public class MyAppServiceImpl implements MyAppService {
public Collection<Person> getReportData()
{
//declare a list of object
List<Person> data = new LinkedList<Person>();
Person p1 = new Person();
p1.setFirstName("John");
p1.setSurname("Smith");
p1.setAge(Integer.valueOf(5));
data.add(p1);
return data;
}
public Map<String, Object> getReportParameters()
{
Map<String, Object> params = new HashMap<String, Object>();
params.put("footerText", "Just to demonstrate how to pass parameters to report");
return params;
}
}
Finally, the writer class the creates the xls file from the data
//..
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.Map;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.engine.xml.JRXmlLoader;
import org.springframework.stereotype.Component;
//...
@Component(value = "reportWriter")
public class JasperReportWriterImpl implements ReportWriter
{
public static JasperDesign jasperDesign;
public static JasperPrint jasperPrint;
public static JasperReport jasperReport;
public static String reportTemplateUrl = "jasper/person-template.jrxml";
public byte[] getXlsAsStringForPerson(Collection<Person> reportData, Map<String, Object> reportParameters)
{
ByteArrayOutputStream output = null;
try
{
InputStream resourceAsStream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(reportTemplateUrl);
//get report file and then load into jasperDesign
jasperDesign = JRXmlLoader.load(resourceAsStream);
//compile the jasperDesign
jasperReport = JasperCompileManager.compileReport(jasperDesign);
output = new ByteArrayOutputStream();
//fill the ready report with data and parameter
jasperPrint = JasperFillManager.fillReport(jasperReport, reportParameters,
new JRBeanCollectionDataSource(
reportData));
//coding for Excel
JRXlsExporter exporterXls = new JRXlsExporter();
exporterXls.setParameter(JRXlsExporterParameter.JASPER_PRINT, jasperPrint);
exporterXls.setParameter(JRXlsExporterParameter.OUTPUT_STREAM, output);
exporterXls.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.TRUE);
exporterXls.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
exporterXls.exportReport();
}
catch (JRException e)
{
e.printStackTrace();
}
return output.toByteArray();
}
}