2007-07-05
Jasper编程方式实现报表导出
项目里用到了jasperreport,平时都是用ireport来设计好报表模板直接使用就好了,但是碰到动态表头等情况就比较麻烦了,而且有些报表可能仅是针对一个数据表或者说一个实体对象的操作,对于这种报表一个个设计JRXML也比较麻烦,尝试了一下编程的方式来生成报表,只是个简单的测试。在网上找一些资料发现纯编程来写报表的相关内容很少,也是看了相关的API后才写了个例子。
ReportProcess.java是一个简单的用来构造、编译并导出报表的类。
CsvDataSource.java是摘自JASER例子里的一个数据源实现,有现成的做例子的时候就拿来用了,用这个比较简单,不用写数据库那一堆。
Data.csv里的数据。
结果大致是这个样子。
这里就是个实验性的代码,但至少可以知道,我们可以通过一些手段来编程处理JASPER的报表。可以写得更完善一些,动态获取表头个数与内容,写QUERY查询,填充报表。
比如一张表有一部分表头是不定的,那就可以在程序中追加表头定义,追加字段定义等。
ReportProcess.java是一个简单的用来构造、编译并导出报表的类。
package jasper.test;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
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.design.JRDesignBand;
import net.sf.jasperreports.engine.design.JRDesignExpression;
import net.sf.jasperreports.engine.design.JRDesignField;
import net.sf.jasperreports.engine.design.JRDesignStaticText;
import net.sf.jasperreports.engine.design.JRDesignTextField;
import net.sf.jasperreports.engine.design.JasperDesign;
public class ReportProcess {
public static void main(String[] args) {
try {
JasperReport jp = getJasperReport();
InputStream in = new FileInputStream(
"src/test/java/jasper/test/Data.csv");// 换成自己目录
CsvDataSource csvDataSource = new CsvDataSource(
new InputStreamReader(in));
in.close();
JasperPrint jpr = JasperFillManager.fillReport(jp, null,
csvDataSource);
JasperExportManager.exportReportToHtmlFile(jpr, "c:/test.html");// 写的时候随便指定了个查看的目录
} catch (Exception e) {
e.printStackTrace();
}
}
public static JasperReport getJasperReport() throws JRException {
JasperDesign design = new JasperDesign();
design.setName("testReport");
JRDesignBand title = new JRDesignBand();
title.setHeight(50);
JRDesignStaticText titleText = new JRDesignStaticText();
titleText.setText("test report");
titleText.setX(230);
titleText.setFontSize(20);
titleText.setHeight(50);
titleText.setWidth(100);
title.addElement(titleText);
design.setTitle(title);
String[] headers = { "name", "age", "gender", "like" };
JRDesignBand columnHeader = new JRDesignBand();
columnHeader.setHeight(30);
JRDesignBand detail = new JRDesignBand();
detail.setHeight(30);
for (int i = 0; i < headers.length; i++) {
// add column headers
JRDesignStaticText staticText = new JRDesignStaticText();
staticText.setText(headers[i]);
staticText.setFontSize(16);
staticText.setHeight(30);
staticText.setWidth(50);
staticText.setX(50 * i);
columnHeader.addElement(staticText);
// define fields
JRDesignField field = new JRDesignField();
field.setName(headers[i]);
field.setValueClass(String.class);
design.addField(field);
// add text fields for displaying fields
JRDesignTextField textField = new JRDesignTextField();
JRDesignExpression expression = new JRDesignExpression();
expression.setText("$F{" + headers[i] + "}");
expression.setValueClass(String.class);
textField.setExpression(expression);
textField.setFontSize(14);
textField.setHeight(30);
textField.setWidth(50);
textField.setX(50 * i);
detail.addElement(textField);
}
design.setColumnHeader(columnHeader);
design.setDetail(detail);
return JasperCompileManager.compileReport(design);
}
}
CsvDataSource.java是摘自JASER例子里的一个数据源实现,有现成的做例子的时候就拿来用了,用这个比较简单,不用写数据库那一堆。
package jasper.test;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;
import net.sf.jasperreports.engine.JRRewindableDataSource;
import au.com.bytecode.opencsv.CSVReader;
/**
*
* 这个类摘自JASPER带的一个例子里的CSV数据源实现。
*
*/
public class CsvDataSource implements JRRewindableDataSource {
private CSVReader csvReader;
private List rows;
private int currentRowIndex = -1;
private int currentColIndex = 0;
private int totalRows;
public CsvDataSource(Reader reader) {
try {
csvReader = new CSVReader(reader);
rows = csvReader.readAll();
totalRows = rows.size();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean next() throws JRException {
boolean retVal = true;
currentRowIndex++;
currentColIndex = 0;
if (currentRowIndex >= totalRows) {
retVal = false;
}
return retVal;
}
public Object getFieldValue(JRField arg0) throws JRException {
String value = null;
String[] currentRow = (String[]) rows.get(currentRowIndex);
value = currentRow[currentColIndex];
currentColIndex++;
return value;
}
public void moveFirst() throws JRException {
currentRowIndex = 0;
currentColIndex = 0;
}
}
Data.csv里的数据。
jim,12,male,basketball lily,13,female,dancing david,23,male,swimming su,23,female,running
结果大致是这个样子。
test report
name age gender like
jim 12 male basketb
lily 13 female dancing
david 23 male swimmi
su 23 female running
这里就是个实验性的代码,但至少可以知道,我们可以通过一些手段来编程处理JASPER的报表。可以写得更完善一些,动态获取表头个数与内容,写QUERY查询,填充报表。
比如一张表有一部分表头是不定的,那就可以在程序中追加表头定义,追加字段定义等。
评论
diystyle
2007-12-03
其实动态的表头功能,其实如果报表格式(布局)简单一点的话,完全可以通过程序来构造报表文件,然后通过报表的xml,通过程序动态的编译成jasper文件,同时实现一个jasper的JRDataSource,这样自己处理报表就灵活了许多。思路和 sunsy 的有点类似
fire01312
2007-12-03
在网上找一些资料发现纯编程来写报表的相关内容很少,也是看了相关的API后才写了个例子。
你在那找的api文档啊 ?? 我也想研究研究 谢谢!
你在那找的api文档啊 ?? 我也想研究研究 谢谢!
laiseeme
2007-08-21
sql语句里面的from table 这个table可以是变量么?
ssy8110
2007-08-21
duochunyu 写道
嗯~~~,谢谢分享思路,我现在结合ireport设计报表样式,也为动态表头头疼,可以参考参考,谢谢楼主。
当然,这么做貌似对数据的规则性就要求很强了。。
我现在ireport设计模版时直接用的jdbc - sql 方式获取数据结构,配置完报表模版后,实际运行时,数据则是动态从hibernate加载(当然,有些复杂的查询直接用hib的执行sql方式获取的数据),唯一不够灵活的就是动态表头和数据条件的问题,哎。。。总觉得老外的报表不够灵活。。。。
动态表头,可以使用交叉报表来实现呀当然,这么做貌似对数据的规则性就要求很强了。。
我现在ireport设计模版时直接用的jdbc - sql 方式获取数据结构,配置完报表模版后,实际运行时,数据则是动态从hibernate加载(当然,有些复杂的查询直接用hib的执行sql方式获取的数据),唯一不够灵活的就是动态表头和数据条件的问题,哎。。。总觉得老外的报表不够灵活。。。。
duochunyu
2007-08-08
嗯~~~,谢谢分享思路,我现在结合ireport设计报表样式,也为动态表头头疼,可以参考参考,谢谢楼主。
当然,这么做貌似对数据的规则性就要求很强了。。
我现在ireport设计模版时直接用的jdbc - sql 方式获取数据结构,配置完报表模版后,实际运行时,数据则是动态从hibernate加载(当然,有些复杂的查询直接用hib的执行sql方式获取的数据),唯一不够灵活的就是动态表头和数据条件的问题,哎。。。总觉得老外的报表不够灵活。。。。
当然,这么做貌似对数据的规则性就要求很强了。。
我现在ireport设计模版时直接用的jdbc - sql 方式获取数据结构,配置完报表模版后,实际运行时,数据则是动态从hibernate加载(当然,有些复杂的查询直接用hib的执行sql方式获取的数据),唯一不够灵活的就是动态表头和数据条件的问题,哎。。。总觉得老外的报表不够灵活。。。。
sunsy
2007-07-05
不知道大家在处理动态表头之类的报表时有什么好的方法可以共享一下。
- 浏览: 8649 次
- 性别:

- 来自: 厦门

- 详细资料
搜索本博客
最新评论
-
Jasper编程方式实现报表导 ...
其实动态的表头功能,其实如果报表格式(布局)简单一点的话,完全可以通过程序来构造 ...
-- by diystyle -
Jasper编程方式实现报表导 ...
在网上找一些资料发现纯编程来写报表的相关内容很少,也是看了相关的API后才写了个 ...
-- by fire01312 -
Jasper编程方式实现报表导 ...
sql语句里面的from table 这个table可以是变量么?
-- by laiseeme -
Jasper编程方式实现报表导 ...
duochunyu 写道嗯~~~,谢谢分享思路,我现在结合ireport设计报表 ...
-- by ssy8110 -
Jasper编程方式实现报表导 ...
嗯~~~,谢谢分享思路,我现在结合ireport设计报表样式,也为动态表头头疼, ...
-- by duochunyu






评论排行榜