java生成excel
来源:互联网 发布:中国乳业大数据平台 编辑:程序博客网 时间:2024/06/07 00:14
需求描述(我想,应该很多公司的商务都需要这种类型的excel)
以其中一个excel为例。
先说商务的要求,商务要管理所有的项目的各种各样的钱,其中有一项是已付金额,要求是这个项目的实际付款日期只要填写上了,比如是2007-11-11,那么这个项目的已付金额就应该出现在生成的excel的11月份的那一栏。
整个excel(第一行所有列名)需要显示:项目编号,项目名称,所属部门(ODC),po单号,po金额,4月,5月,6月,7月,8月,9月,10月,11月,12月,1月,2月,3月,合计
如图:
我们公司的财年是4月开始到次年3月,算一个财年,这也无形中增大了难度。要算横行的合计,又要算每个竖行的合计,相当麻烦啊。而且所需的数据在3张表里面,都要取出来。
总体思路
1.所有复杂的业务逻辑,全部封装到oracle的存储过程里,将生成的结果(一个系统游标)再插入到一个新建的表中。
2.在java的bo(vo)中建一个新的类型,要完全符合这个新建的表,所有字段和它一模一样。
3.在java中调用存储过程,返回一个结果集,将结果集中的数据全部封装到你新建的那个类的对象里去。再添加到List中
4.从List中取出所有对象,写进excel。
以上思路说起来好说,实现起来相当麻烦,很多小地方不注意就要很久,有可能最终都搞不出来。
1.我是搞java的,sql当然是会写,但是复杂的存储过程就力不从心了,还好及时请教了报表组的同事。
先写存储过程(p_projectpayment),并建立一张新的表(t_projectpayment)。
2.存储过程写好后,建bo(一定要和新建的那个表的字段一模一样才行。)
3.调用存储过程返回结果集。代码如下:
这是调用的工具类的方法。传入2个值:1 年份 2 调用存储过程的sql语句
public class SaveProcess
{
public static ResultSet getResult(String year,String sql){
Connection cn=null;
CallableStatement cal = null;
ResultSet result = null;
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
String url="jdbc:oracle:thin:@192.168.1.10:1521:xxxx";
cn=DriverManager.getConnection(url,"xxx","xxx");
cal=cn.prepareCall(sql);
cal.registerOutParameter(2,oracle.jdbc.driver.OracleTypes.CURSOR);
cal.setString(1, year);
cal.execute();
result = (ResultSet)cal.getObject(2);
}
catch (Exception e)
{
e.printStackTrace();
}
return result;
}
}
这里要注意几点:
(1).传入的第2个参数String sql,我之前也是不会写吗,从网上查,有个SB说这样写:
String sql = "{ ? = call p_projectbill(?)}";这是他妈错误的,我在这搞了好久好久,因为从来没怀疑这点错了,以为是其他什么地方错了,我草你妈。
正确的写法应该是String sql = "{ call p_projectbill(?,?)}";无论你是输入还是输出的参数,都要写在后面,用?表示,根本不是输出的写前面(其中p_projectbill为存储过程名)
(2).要在Connection对象调用存储过程后(cal=cn.prepareCall(sql);),设置输入输出参数,里面的1和2就代表?的位置,还有就是游标类型竟然是oracle.jdbc.driver.OracleTypes.CURSOR。
(3).就是不要忘了执行(cal.execute();)
4.封装到对象,添加到list中。这段代码很简单,就不写了。
5.写入到excel表中。其中String[] cols={"项目编号","项目名称","所属ODC","po单号","po金额","4月","5月","6月","7月","8月",
"9月","10月","11月","12月","1月","2月","3月","合计",};
public static void downProjectBill(OutputStream os, List<Projectbill> list,String[] cols
)
{
try
{
//设置excel的编码格式
WorkbookSettings wset = new WorkbookSettings();
wset.setEncoding("gb2312");
// 构建excel工作表
WritableWorkbook wwb = Workbook.createWorkbook(os);
// 工作表名称
以其中一个excel为例。
先说商务的要求,商务要管理所有的项目的各种各样的钱,其中有一项是已付金额,要求是这个项目的实际付款日期只要填写上了,比如是2007-11-11,那么这个项目的已付金额就应该出现在生成的excel的11月份的那一栏。
整个excel(第一行所有列名)需要显示:项目编号,项目名称,所属部门(ODC),po单号,po金额,4月,5月,6月,7月,8月,9月,10月,11月,12月,1月,2月,3月,合计
如图:
我们公司的财年是4月开始到次年3月,算一个财年,这也无形中增大了难度。要算横行的合计,又要算每个竖行的合计,相当麻烦啊。而且所需的数据在3张表里面,都要取出来。
总体思路
1.所有复杂的业务逻辑,全部封装到oracle的存储过程里,将生成的结果(一个系统游标)再插入到一个新建的表中。
2.在java的bo(vo)中建一个新的类型,要完全符合这个新建的表,所有字段和它一模一样。
3.在java中调用存储过程,返回一个结果集,将结果集中的数据全部封装到你新建的那个类的对象里去。再添加到List中
4.从List中取出所有对象,写进excel。
以上思路说起来好说,实现起来相当麻烦,很多小地方不注意就要很久,有可能最终都搞不出来。
1.我是搞java的,sql当然是会写,但是复杂的存储过程就力不从心了,还好及时请教了报表组的同事。
先写存储过程(p_projectpayment),并建立一张新的表(t_projectpayment)。
2.存储过程写好后,建bo(一定要和新建的那个表的字段一模一样才行。)
3.调用存储过程返回结果集。代码如下:
这是调用的工具类的方法。传入2个值:1 年份 2 调用存储过程的sql语句
public class SaveProcess
{
}
这里要注意几点:
(1).传入的第2个参数String sql,我之前也是不会写吗,从网上查,有个SB说这样写:
String sql = "{ ? = call p_projectbill(?)}";这是他妈错误的,我在这搞了好久好久,因为从来没怀疑这点错了,以为是其他什么地方错了,我草你妈。
正确的写法应该是String sql = "{ call p_projectbill(?,?)}";无论你是输入还是输出的参数,都要写在后面,用?表示,根本不是输出的写前面(其中p_projectbill为存储过程名)
(2).要在Connection对象调用存储过程后(cal=cn.prepareCall(sql);),设置输入输出参数,里面的1和2就代表?的位置,还有就是游标类型竟然是oracle.jdbc.driver.OracleTypes.CURSOR。
(3).就是不要忘了执行(cal.execute();)
4.封装到对象,添加到list中。这段代码很简单,就不写了。
5.写入到excel表中。其中String[] cols={"项目编号","项目名称","所属ODC","po单号","po金额","4月","5月","6月","7月","8月",
public static void downProjectBill(OutputStream os, List<Projectbill> list,String[] cols