需求描述(我想,应该很多公司的商务都需要这种类型的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);
// 工作表名称
WritableSheet ws = wwb.createSheet(PROJECTBILL_NAME,0);
// 声明表头(列)样式
WritableFont wf1 = new WritableFont(WritableFont.ARIAL, 10,
WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE);
WritableCellFormat wcf1 = new WritableCellFormat(wf1);
// wcf1.setBackground(jxl.format.Colour.ICE_BLUE);
wcf1.setBorder(jxl.format.Border.ALL,
jxl.format.BorderLineStyle.THIN);
// 声明表数据样式
WritableFont wf = new WritableFont(WritableFont.ARIAL, 10,
WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE);
WritableCellFormat wcf = new WritableCellFormat(wf);
wcf.setBorder(jxl.format.Border.ALL,
jxl.format.BorderLineStyle.THIN);
//声明一个单元格对象
jxl.write.Label label;
//插入列值
for (int i = 0; i < cols.length; i++)
{
//设置第i列的宽度
ws.setColumnView(i, 10);
label = new jxl.write.Label(i, 0, cols[i], wcf1);
//将定义好的单元格添加到工作表ws对象中
ws.addCell(label);
}
for (int j = 0; j < list.size(); j++)
{
Projectbill projectbill = list.get(j);
String pocode = projectbill.getPocode();
String poname = projectbill.getPoname();
String odc = projectbill.getOdc();
String ponumber = projectbill.getPonumber();
String totalprice = projectbill.getTotalprice()+"";
String month4 = projectbill.getMonth4()+"";
String month5 = projectbill.getMonth5()+"";
String month6 = projectbill.getMonth6()+"";
String month7 = projectbill.getMonth7()+"";
String month8 = projectbill.getMonth8()+"";
String month9 = projectbill.getMonth9()+"";
String month10 = projectbill.getMonth10()+"";
String month11 = projectbill.getMonth11()+"";
String month12 = projectbill.getMonth12()+"";
String month1 = projectbill.getMonth1()+"";
String month2 = projectbill.getMonth2()+"";
String month3 = projectbill.getMonth3()+"";
String totalmonth = projectbill.getTotalmonth()+"";
label = new jxl.write.Label(0,j+1,pocode,wcf);
ws.addCell(label);
label = new jxl.write.Label(1,j+1,poname,wcf);
ws.addCell(label);
label = new jxl.write.Label(2,j+1,odc,wcf);
ws.addCell(label);
label = new jxl.write.Label(3,j+1,ponumber,wcf);
ws.addCell(label);
label = new jxl.write.Label(4,j+1,(totalprice.equals("0.0")? " ":totalprice),wcf);
ws.addCell(label);
label = new jxl.write.Label(5,j+1,(month4.equals("0.0")? " ":month4),wcf);
ws.addCell(label);
label = new jxl.write.Label(6,j+1,(month5.equals("0.0")? " ":month5),wcf);
ws.addCell(label);
label = new jxl.write.Label(7,j+1,(month6.equals("0.0")? " ":month6),wcf);
ws.addCell(label);
label = new jxl.write.Label(8,j+1,(month7.equals("0.0")? " ":month7),wcf);
ws.addCell(label);
label = new jxl.write.Label(9,j+1,(month8.equals("0.0")? " ":month8),wcf);
ws.addCell(label);
label = new jxl.write.Label(10,j+1,(month9.equals("0.0")? " ":month9),wcf);
ws.addCell(label);
label = new jxl.write.Label(11,j+1,(month10.equals("0.0")? " ":month10),wcf);
ws.addCell(label);
label = new jxl.write.Label(12,j+1,(month11.equals("0.0")? " ":month11),wcf);
ws.addCell(label);
label = new jxl.write.Label(13,j+1,(month12.equals("0.0")? " ":month12),wcf);
ws.addCell(label);
label = new jxl.write.Label(14,j+1,(month1.equals("0.0")? " ":month1),wcf);
ws.addCell(label);
label = new jxl.write.Label(15,j+1,(month2.equals("0.0")? " ":month2),wcf);
ws.addCell(label);
label = new jxl.write.Label(16,j+1,(month3.equals("0.0")? " ":month3),wcf);
ws.addCell(label);
label = new jxl.write.Label(17,j+1,(totalmonth.equals("0.0")? " ":totalmonth),wcf);
ws.addCell(label);
}
wwb.write();
wwb.close();
os.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
最后在action中设置response相应的都不信息,并调用上面的这个方法
try
{
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename="
+ new String(exlName.getBytes(),"iso-8859-1"));
OutputStream os = response.getOutputStream();
DownExcel.downProjectBill(os, projectbills, cols);
}catch(UnsupportedEncodingExcep tion ex)
{
ex.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
return null;
以其中一个excel为例。
先说商务的要求,商务要管理所有的项目的各种各样的钱,其中有一项是已付金额,要求是这个项目的实际付款日期只要填写上了,比 如 是2007-11-11,那么这个项目的已付金额就应该出现在生成的excel的11月份的那一栏。
整个excel(第一行所有列名)需要显示:项目编号,项目名称,所属部门(ODC),po单号,po金额,4月,5月,6月,7月,8月,9月,10月,11月,12月,1月,2月,3月,合计
如图:
![java生成excel报表完全解决方案(看完你绝对会了) java生成excel报表完全解决方案(看完你绝对会了)](https://i-blog.csdnimg.cn/blog_migrate/9675eb7a9cd474f2809f673bdb42a0de.gif)
我们公司的财年是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
最后在action中设置response相应的都不信息,并调用上面的这个方法
try