第一步: 传参,后期可根据自己需要进行调整。我这里需要的是
quarter 代表季度
dptid 部门编号 根据接受过来的参数进行文档命名。
UserInfo userInfo=(UserInfo)request.getSession().getAttribute("userInfo"); String userid=userInfo.getUserID(); String quarter = request.getParameter("quarter"); String dptid = request.getParameter("dptid"); /***********************EXCEL导出部分**************************/ String str3 = FileInfoTools.getSystemFilePath() + "/documentTemp/"; File file = new File(str3); if (!file.exists() && !file.isDirectory()) { file.mkdir(); } String names = new SimpleDateFormat("yyyyMMddhhmmssSSS").format(new Date()); String ourl = str3 + names + "_"+userid+".xls"; FileOutputStream fos = null; String fileName = ""; try { HSSFWorkbook wb = new HSSFWorkbook();//创建工作薄 fileName = "安全可控导出"+"_"+userid+"_"+names+".xls"; DBManager dbm = new DBManager(); System.out.println("quarter+"+quarter+"dptid="+dptid); try{ dbm.newConnection(); String str = "select departmentname from dpt_department where departmentid='"+dptid+"'"; //获取唯一id String dptName = dbm.executeQueryString(str); fileName=dptName+"部门安全可控清单汇总"+"_"+userid+"_"+names+".xls"; //创建sheet页,并写入内容 createSheet(dbm,wb,getCardInfo(dbm,quarter,dptid)); }catch(Exception e){ e.printStackTrace(); }finally{ dbm.closeConnection(); } File ff = new File(ourl); if (ff.exists()) { ff.delete(); } fos = new FileOutputStream(ourl); wb.write(fos); fos.close(); String u = "/project/system/fileAction.do?filePath=" + URLEncoder.encode(ourl) + "&fileName=" + URLEncoder.encode(fileName); response.sendRedirect(u); } catch (Exception e) { e.printStackTrace(); }
第二步:创建sheet页签
public void createSheet(DBManager dbm,HSSFWorkbook w,Vector vt) throws Exception{
for(int i=0;i
String id = (String)ht.get("id");
String quarter = (String)ht.get("quarter");
HSSFSheet sheet = w.createSheet("安全可控清单");
//写入数据
wirteSheet(dbm,sheet,w,id,quarter);
}
}
我这里页签是固定的名称
可根据自己的需要根据参数来进行判断页签。如果多个页签的话 可以这样:
public void createSheet(DBManager dbm,HSSFWorkbook w,Vector vt) throws Exception{
Hashtable temp = (Hashtable)vt.get(0);
String id = (String)temp.get("id");
String quarter = (String)temp.get("quarter");
System.out.println("DumpExcel.jsp id"+id+"quarter:"+quarter);
//查询得到当前模板对应的页签
String sheets = "select a7 from a_templet_col_num where templet_id='"+id+"' group by a7 order by a7 ";
Vector sheetsVc = dbm.executeQueryVector3LowerCase(sheets.toString());
if (sheetsVc != null && sheetsVc.size() > 0) {
for (int i = 0; i < sheetsVc.size(); i++) {
Hashtable ht = (Hashtable) sheetsVc.get(i);
System.out.println("导出的页签:ht"+ht.get("a7"));
HSSFSheet sheet = w.createSheet(ht.get("a7").toString());
//写入数据
wirteSheet(dbm,sheet,w,id,quarter,ht.get("a7").toString());
}
}
}
此处的a7 就是页签的名称 在数据库里有对应。此处id是根据另一个方法里查询的!
多个页签样式
请注意第一处代码处:createSheet()方法
createSheet()方法中调用getCardInfo()方法 此方法就是返回你部门的数据。
public Vector getCardInfo(DBManager dbm,String quarter,String departmentid) throws Exception{ String sql = "select id,quarter from a_templet where quarter= "+quarter+" and department="+departmentid; Vector vc = dbm.executeQueryVector3LowerCase(sql); return vc; }
此处可根据需要来进行返回,不做多解释!
第三步:写入数据
每一个页签都会有不同的数据,在创建页签时就会对该页签写入数据。循环操作!
31.创建表头
我此处的数据不存在数据库我是固定的。list命名方式自己定义。我这里定义的意义代表他是报表的第几行数据 col是跨几列属性 可根据自己习惯来进行定义
//第一列数据 List第二列这里的参数col_name 是为了跟数据库的属性进行对比取值。
//第二列数据
Hashtable tweDump = new Hashtable();
tweDump.put("show_name", "代码");
tweDump.put("col_name", "a1");;
listTwe.add(tweDump);
Hashtable tweDump0 = new Hashtable();
tweDump0.put("show_name", "代码");
tweDump0.put("col_name", "a2");;
listTwe.add(tweDump0);
Hashtable tweDump1 = new Hashtable();
tweDump1.put("show_name", "名称");
tweDump1.put("col_name", "a3");;
listTwe.add(tweDump1);
Hashtable tweDump2 = new Hashtable();
tweDump2.put("show_name", "厂商名称");
tweDump2.put("col_name", "a4");;
listTwe.add(tweDump2);
Hashtable tweDump3 = new Hashtable();
tweDump3.put("show_name", "厂商性质");
tweDump3.put("col_name", "a5");;
listTwe.add(tweDump3);
Hashtable tweDump4 = new Hashtable();
tweDump4.put("show_name", "厂商外资国别");
tweDump4.put("col_name", "a6");;
listTwe.add(tweDump4);
Hashtable tweDump5 = new Hashtable();
tweDump5.put("show_name", "2017年1季度末总数");
tweDump5.put("col_name", "a7");;
listTwe.add(tweDump5);
Hashtable tweDump6 = new Hashtable();
tweDump6.put("show_name", "2017年2季度新增数量");
tweDump6.put("col_name", "tbsl");;
listTwe.add(tweDump6);
Hashtable tweDump7 = new Hashtable();
tweDump7.put("show_name", "2017年2季度新增投入金额(万元)");
tweDump7.put("col_name", "tbje");;
listTwe.add(tweDump7);
Hashtable tweDump8 = new Hashtable();
tweDump8.put("show_name", "备注");
tweDump8.put("col_name", "a8");;
listTwe.add(tweDump8);
第三列。这里下面的循环主要是为了报表上 跨行列跨行显示条线,不多解释
//第三列数据
Hashtable Tree = new Hashtable();
Tree.put("show_name", "大类");
Tree.put("col_name", "1");;
listTree.add(Tree);
Hashtable Tree1 = new Hashtable();
Tree1.put("show_name", "小类");
Tree1.put("col_name", "2");;
for(int i=0;i<9;i++){
listTree.add(Tree1);
}
插入数据:这里需要进行查询数据库操作 。这里我不合并到一起是有原因的。因为每个大类上面有个类别样式
所以需要这样做判断。
//插入的数据
List
List
List
List
List
List
List
List
List
List
System.out.println("templetid:"+templetid+"--time:"+time);
//查询数据
String sql="select t1.*,t2.*,t3.tbjd,t3.tbje,t3.tbsl from (select * from a_templet_safe_control_colnum where templet_id='"+templetid+"' order by A2) t1 left join (select A2,count(*) as counts from a_templet_safe_control_colnum where templet_id='"+templetid+"' group by A2) t2 on t1.A2=t2.A2 left join (select * from a_templet_safe_control_colval where tbjd='"+time+"') t3 on t1.id=t3.templet_num_id where 1=1 ";
for(int i=0;i<10;i++){
Vector var =null;
switch(i){
case 0:
var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='A' ");
break;
case 1:
var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='B' ");
break;
case 2:
var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='C' ");
break;
case 3:
var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='D' ");
break;
case 4:
var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='E' ");
break;
case 5:
var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='F' ");
break;
case 6:
var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='G' ");
break;
case 7:
var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='H' ");
break;
case 8:
var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='I' ");
break;
case 9:
var=dbm.executeQueryVector3LowerCase(sql.toString()+" and t1.a1='J' ");
break;
}
if (var != null && var.size() > 0) {
for (int j = 0; j < var.size(); j++) {
Hashtable ht = (Hashtable) var.get(j);
switch(i){
case 0:
listA.add(ht);
break;
case 1:
listB.add(ht);
break;
case 2:
listC.add(ht);
break;
case 3:
listD.add(ht);
break;
case 4:
listE.add(ht);
break;
case 5:
listF.add(ht);
break;
case 6:
listG.add(ht);
break;
case 7:
listH.add(ht);
break;
case 8:
listI.add(ht);
break;
case 9:
listJ.add(ht);
break;
}
}
}
把数据添加到对应的list中
创建表头开始:这里的前三列是固定的可根据自己需求来修改
//配置显示的固定列数固定值添加完成,开始数据库的值
//写入数据
HSSFRow row=null;
//样式颜色
HSSFCellStyle s = getCellStyle(w,1);
HSSFCellStyle r = getCellStyle(w,2);
HSSFCellStyle y = getCellStyle(w,3);
HSSFCellStyle g = getCellStyle(w,4);
int rowspan=3;
System.out.println("rowspan==="+rowspan);
if(listA.size()>0){
for(int j=0;j
for(int col=0;col
cell.setCellStyle(s);
}
}
for(int j=0;j
for(int k=0;k
if(listA.get(k).get("a1").equals(listA.get(j).get("a1"))){
nums+=1;
}
}
if(j==0){
//System.out.println("列高rowspan==="+rowspan);
sheet.getRow(rowspan).setHeight((short)1000);//设置列高
createCell(sheet, sheet.getRow(rowspan), w, g, 0, "A", rowspan, rowspan, 0, 0);
createCell(sheet, sheet.getRow(rowspan), w, g, 1, "", rowspan, rowspan, 1, 1);
createCell(sheet, sheet.getRow(rowspan), w, g, 2, "计算机设备", rowspan, rowspan, 2, 2);
createCell(sheet, sheet.getRow(rowspan), w, g, 3, "", rowspan, rowspan, 3, 9);
rowspan++;
}
//System.out.println("列高rowspan==="+rowspan);
sheet.getRow(rowspan).setHeight((short)500);//设置列高
for(int k=0;k
//第二行
if(k==0){
//System.out.println("j====="+j+"--"+listA.get(j).get("counts")+"rowspan:"+rowspan+"ID:"+listA.get(j).get("id"));
createCell(sheet, sheet.getRow(rowspan), w, s, k, listA.get(j).get(listTwe.get(k).get("col_name"))==null?"":listA.get(j).get(listTwe.get(k).get("col_name")), rowspan, (listA.size()+3), k, k);
}else if(k==1||k==2){
createCell(sheet, sheet.getRow(rowspan), w, s, k, listA.get(j).get(listTwe.get(k).get("col_name"))==null?"":listA.get(j).get(listTwe.get(k).get("col_name")), rowspan, rowspan+Integer.parseInt(listA.get(j).get("counts")+"")-1, k, k); //第二列
}else{
createCell(sheet, sheet.getRow(rowspan), w, s, k, listA.get(j).get(listTwe.get(k).get("col_name"))==null?"":listA.get(j).get(listTwe.get(k).get("col_name")), rowspan, rowspan, k, k);
}
}
rowspan++;
}
}
我这里做的判断是 刚进入循环代表循环有值时 打印出类别,
打印类别记得rowspan++操作。因为类别没有在数据库里。如果不做该操作 则会打印时最后一条数据打印不了。因为位置被占了!
然后在进行循环listTwe第二列的数据 这时候刚才定义的col_name用得上了。循环listA的值看哪个能对应col_name则输出!
K==0进行判断 k代表 第几列 第一列要跨当前类的所有行,只打印一次。循环完之后进行rowspan++操作 ,让下次循环知道是第几行的,不会覆盖当前行
一下的listB ...listJ 的类似
最后还有样式:因为需求需要我在定义样式的时候传入值 num 根据num进行打印不同的背景颜色。可根据需求进行调整
打印的字体样式: 根据自己的需求来进行修改。
public static HSSFFont getContentFont(HSSFWorkbook wb,int i) {
HSSFFont fontStyle = wb.createFont();
fontStyle.setFontName("微软雅黑");
if(i==1){
fontStyle.setFontHeightInPoints((short) 16);
}else if(i==2){
fontStyle.setFontHeightInPoints((short) 9);
}
fontStyle.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
fontStyle.setColor(HSSFColor.GREY_80_PERCENT.index);
return fontStyle;
}
java引用包
<%@page contentType="text/html; charset=GBK"%>
<%@page import="java.net.URLEncoder"%>
<%@page import="java.io.File"%>
<%@page import="java.io.FileOutputStream"%>
<%@page import="java.util.*"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="java.text.DecimalFormat"%>
<%@page import="java.math.BigDecimal"%>
<%@page import="org.apache.poi.hssf.usermodel.*"%>
<%@page import="org.apache.poi.hssf.util.*"%>
到这,也就完成了导出操作!
有什么不懂得可以一起探讨,有比我更便捷的方法或方式,请告知!
完整代码就不贴了,太多。
原文:http://www.cnblogs.com/huole/p/6141814.html