前言
前面讲解了一些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把我们常用到的数据源形式提前帮我们写好了,我们所需要进行的二次开发就是在其基础上再进行优化和美化。