先來個最終結果樣式:
第一步: 傳參,后期可根據自己需要進行調整。我這里需要的是
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<vt.size();i++){ Hashtable ht = (Hashtable)vt.get(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<Map<String, Object>> listOne = new ArrayList<Map<String, Object>>();
Hashtable htss = new Hashtable(); htss.put("group_name", +year+"年第"+ji+"季度信息技術情況調研表"); htss.put("col", "10"); listOne.add(htss);
第二列這里的參數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<Map<String,Object>> listA = new ArrayList<Map<String,Object>>(); List<Map<String,Object>> listB = new ArrayList<Map<String,Object>>(); List<Map<String,Object>> listC = new ArrayList<Map<String,Object>>(); List<Map<String,Object>> listD = new ArrayList<Map<String,Object>>(); List<Map<String,Object>> listE = new ArrayList<Map<String,Object>>(); List<Map<String,Object>> listF = new ArrayList<Map<String,Object>>(); List<Map<String,Object>> listG = new ArrayList<Map<String,Object>>(); List<Map<String,Object>> listH = new ArrayList<Map<String,Object>>(); List<Map<String,Object>> listI = new ArrayList<Map<String,Object>>(); List<Map<String,Object>> listJ = new ArrayList<Map<String,Object>>(); 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中
創建表頭開始:這里的前三列是固定的可根據自己需求來修改
//配置顯示的固定列數 int col_num=9; //創建表頭開始 HSSFRow row0 = sheet.createRow(0); HSSFRow row1 = sheet.createRow(1); HSSFRow row2 = sheet.createRow(2); for(int j=0;j<col_num;j++){ HSSFCellStyle s = getTitleStyle(w,2); HSSFCell cell0 = row0.createCell(j); HSSFCell cell1 = row1.createCell(j); HSSFCell cell2 = row1.createCell(j); cell0.setCellStyle(s); cell1.setCellStyle(s); cell2.setCellStyle(s); } int startCol=0; for(int i=0;i<listOne.size();i++){ Hashtable ht = (Hashtable)listOne.get(i); String group_name = (String)ht.get("group_name"); int colspan =Integer.parseInt((String)ht.get("col")); sheet.getRow(0).setHeight((short)600);//設置列高 HcreateCell(sheet, row0, w, startCol, group_name, 0, 0, startCol, (startCol+colspan-1),0); startCol+=colspan; } startCol=0; sheet.getRow(1).setHeight((short)500);//設置列高 sheet.getRow(2).setHeight((short)500);//設置列高 for(int i=0;i<listTwe.size();i++){ Hashtable ht = (Hashtable)listTwe.get(i); String show_name = (String)ht.get("show_name"); //System.out.println("i==="+i+"--"+ht.get("show_name")); sheet.setColumnWidth((short)i, (short)4000);//設置列寬 if(i==0){ HcreateCell(sheet, row1, w, startCol, show_name, 1, 1, startCol, 1,i); }else{ HcreateCell(sheet, row1, w, startCol, show_name, 1, 2, startCol, startCol,i); } startCol++; } startCol=0; for(int i=0;i<listTree.size();i++){ Hashtable ht = (Hashtable)listTree.get(i); String show_name = (String)ht.get("show_name"); //System.out.println("i==="+i+"--"+ht.get("show_name")); if(i==1||i==0){ sheet.setColumnWidth((short)i, (short)2000);//設置列寬 } HcreateCell(sheet, row2, w, startCol, show_name, 2, 2, startCol, startCol, i); HcreateCell(sheet, row2, w, startCol, show_name, 2, 2, startCol, startCol, i); startCol++; } //表頭結束
固定值添加完成,開始數據庫的值
//寫入數據 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<listA.size()+1;j++){ row =sheet.createRow(j+3); for(int col=0;col<col_num;col++){ HSSFCell cell = row.createCell(col); cell.setCellStyle(s); } } for(int j=0;j<listA.size();j++){ int nums=0; for(int k=0;k<j;k++){ //System.out.println(listA.get(k).get("a1")+"---"+listA.get(j).get("a1")); 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<listTwe.size();k++){ //System.out.println("值:"+listA.get(j).get(listTwe.get(k).get("col_name"))==null?"":listA.get(j).get(listTwe.get(k).get("col_name"))); //第二行 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 HSSFCellStyle getCellStyle(HSSFWorkbook wb,int num) { HSSFCellStyle cellStyle = wb.createCellStyle(); cellStyle.setWrapText(true); if(num==1){ cellStyle.setFillForegroundColor(HSSFColor.WHITE.index); }else if(num==2){ cellStyle.setFillForegroundColor(HSSFColor.RED.index); }else if(num==3){ cellStyle.setFillForegroundColor(HSSFColor.YELLOW.index); }else if(num==4){ cellStyle.setFillForegroundColor(HSSFColor.GREEN.index); } cellStyle.setFillPattern(HSSFCellStyle.BORDER_THIN); cellStyle.setBorderBottom((short) 1); cellStyle.setBorderLeft((short) 1); cellStyle.setBorderRight((short) 1); cellStyle.setBorderTop((short) 1); cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中 cellStyle.setBottomBorderColor(HSSFColor.GREY_80_PERCENT.index); cellStyle.setLeftBorderColor(HSSFColor.GREY_80_PERCENT.index); cellStyle.setRightBorderColor(HSSFColor.GREY_80_PERCENT.index); cellStyle.setTopBorderColor(HSSFColor.GREY_80_PERCENT.index); cellStyle.setFont(getContentFont(wb,2)); cellStyle.setLocked(false); return cellStyle; }
打印的字體樣式: 根據自己的需求來進行修改。
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
