前言
前面讲解了一些JasperReport给我们提供的一些实现好的数据源,当然如果我们有自己的特殊需要,还可以自定义数据源。
正题
跟之前的一样,我们要生成报表需要以下几个步骤:
1.引入jar包,请看《静态文本报表》 。
2.新建报表模版:
跟我们前一篇的AircraftReport报表模版是一样的,请参见《不同数据源之Map数据源》;
3.编译报表模版,请看《静态文本报表》。
4.编写自定义数据源ListOfArraysDataSource:
package com.dan.jasper; import java.util.List; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRField; import net.sf.jasperreports.engine.JRRewindableDataSource; import org.apache.commons.lang.ArrayUtils; /** * 自定义数据源 * @author zdd * */ public class ListOfArraysDataSource implements JRRewindableDataSource { private List<String[]> listOfArrays; private String[] fieldNames; private int index = -1; public ListOfArraysDataSource(List<String[]> listOfArrays){ this.listOfArrays = listOfArrays; } @Override public Object getFieldValue(JRField jrField) throws JRException { int fieldIndex = ArrayUtils.indexOf(fieldNames, jrField.getName()); if (fieldIndex == ArrayUtils.INDEX_NOT_FOUND){ throw new JRException("Invalid field" + jrField.getName()); } return listOfArrays.get(index)[fieldIndex]; } @Override public boolean next() throws JRException { index++; boolean returnVal = true; if (index >= listOfArrays.size()){ returnVal = false; } return returnVal; } @Override public void moveFirst() throws JRException { index = 0; } public List<String[]> getListOfArrays() { return listOfArrays; } public void setListOfArrays(List<String[]> listOfArrays) { this.listOfArrays = listOfArrays; } public String[] getFieldNames() { return fieldNames; } public void setFieldNames(String[] fieldNames) { this.fieldNames = fieldNames; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } }
5.编写servlet:
package com.dan.servlet; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.sf.jasperreports.engine.JRDataSource; import net.sf.jasperreports.engine.JasperRunManager; import com.dan.jasper.ListOfArraysDataSource; /** * 使用自定义数据源填充 * @author zdd * */ public class CustomDataSourceReportServlet extends HttpServlet { /** * */ private static final long serialVersionUID = 2174316885912562306L; /** * 创建数据源 * @return */ private JRDataSource createReportDataSource(){ String[] headers = {"ID","NAME","SEX"}; ListOfArraysDataSource dataSource; List<String[]> reportRows = initializeListOfArrays(); dataSource = new ListOfArraysDataSource(reportRows); dataSource.setFieldNames(headers); return dataSource; } private List<String[]> initializeListOfArrays(){ List<String[]> reportRows = new ArrayList<String[]>(); String[] row1 = {"1","rebecca1","female"}; String[] row2 = {"2","rebecca2","female"}; String[] row3 = {"3","rebecca3","female"}; String[] row4 = {"4","rebecca4","female"}; reportRows.add(row1); reportRows.add(row2); reportRows.add(row3); reportRows.add(row4); return reportRows; } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletOutputStream servletOutputStream = resp.getOutputStream(); InputStream reportStream = getServletConfig().getServletContext().getResourceAsStream("/WEB-INF/classes/reports/AircraftReport.jasper"); try{ JRDataSource dataSource = createReportDataSource(); JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, new HashMap(),dataSource); resp.setContentType("application/pdf"); servletOutputStream.flush(); servletOutputStream.close(); }catch(Exception e){ StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); e.printStackTrace(printWriter); resp.setContentType("text/plain"); resp.getOutputStream().print(stringWriter.toString()); } } }
6.配置web.xml,就是配置servlet
7.运行项目
看一下我的运行结果:
小结:
通过这么多不同数据源的介绍我们不难看到,其实所有的数据源都是对于接口JRDataSource 的一个实现,只不过是JasperReport把我们常用到的数据源形式提前帮我们写好了,我们所需要进行的二次开发就是在其基础上再进行优化和美化。