在實際的項目開發中,常常會有一些涉及到導入導出的文檔的功能。apache開源項目之一poi對此有很好的支持,對以前的使用作一些簡要的總結。html
爲了保證對格式的兼容性,在項目的pom.xml添加這三個jar:git
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.13</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>3.13</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.13</version> </dependency>
通常咱們對導出的數據變化不會太大,因此考慮到重複使用,咱們能夠在服務端生成一個文件,在用戶再次導出時直接取這個文件下載便可,至關於一個緩存,固然若是服務端文件數過多須要定時任務或者shell去清理.. 很少囉嗦,下面開始貼代碼sql
/** * 生成考勤信息文檔 * @param date 導出日期 * @param type 1考勤統計總數word,2考勤詳情excle * @return * @throws IOException */ @RequestMapping(value="/export_message",method=RequestMethod.GET) public @ResponseBody CommonResponse export(@RequestParam String date, @RequestParam Integer type, @RequestParam Integer orgId, @RequestParam String orgName, HttpServletResponse response, HttpServletRequest request) throws IOException{ CommonResponse rsp = null; if (!StringUtil.isEmpty(date)) { String fileName = ""; File file; if (type == 1) { fileName = date.trim()+ ".docx"; file = new File(WORD+ fileName); }else{ fileName = date.trim() + orgId + ".xls"; file = new File(EXCEL + fileName); } if (file.exists()) { rsp = new CommonResponse(1, "exists",fileName); }else{ //文件不存在,用poi生成 int rs = messageService.exportMessage(DateUtil.str2Date(date),type,orgId,orgName); if (rs == 1){ rsp = new CommonResponse(0, "ok",fileName); }else{ rsp = new CommonResponse(-1, "error"); } } }else{ //參數錯誤 rsp = new CommonResponse(-1,"error"); logger.error("Fail to convert the parameters for export_message,date:{}", date); } return rsp; }
/** * 下載考勤信息文檔 * @param response * @param request * @throws FileNotFoundException * @throws UnsupportedEncodingException */ @RequestMapping(value="/down_info_file",method = RequestMethod.GET) public @ResponseBody void downFile(HttpServletResponse response,HttpServletRequest request) throws FileNotFoundException, UnsupportedEncodingException { String filePath,newFileName; String fileName = request.getParameter("fileName"); //兼容性配置 if (request.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0){ fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");//firefox }else if(request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0){ fileName = URLEncoder.encode(fileName, "UTF-8");//IE } if (fileName.endsWith(".docx")) filePath = WORD; else filePath = EXCEL; // 讀到流中 InputStream inStream = new FileInputStream(filePath + fileName); if (fileName.endsWith(".docx")) newFileName = fileName.substring(0, 10) + "勤務上報數與排名統計.docx"; else newFileName = fileName.substring(0, 10) + "勤務詳情統計.xls"; // 設置輸出的格式 response.reset(); response.setCharacterEncoding("UTF-8"); response.setContentType("application/x-msdownload"); response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(newFileName, "UTF-8")+ "\""); // 循環取出流中的數據 byte[] b = new byte[1024]; int len; try { while ((len = inStream.read(b)) > 0) response.getOutputStream().write(b, 0, len); inStream.close(); } catch (IOException e) { logger.error("Download the document is failed,message:{}", e.getMessage()); } }
@Override public int exportMessage(Date date,Integer type,Integer orgId,String orgName) { int rs = 0; File wordfile = new File(WORD); File excelfile = new File(EXCEL); if (!wordfile.exists() || !excelfile.exists()) { wordfile.mkdirs();// 目錄不存在的狀況下,建立目錄。 excelfile.mkdirs(); } String exportExcel = EXCEL + DateUtil.date2Str(date) + orgId +".xls"; String exportWord = WORD + DateUtil.date2Str(date) +".docx"; if (type == 1) { try { List<MessageCount> listMc = new ArrayList<>(); List<MessageTopUser> listMt = null; List<Organization> list = organizationService.findLessFour(); for (int i = 0; i < list.size(); i++) { Integer _orgId = list.get(i).getOrgId(); if (_orgId != 1) { MessageCount mc = messageDao.findAllCountByOrgId(date, _orgId); listMt = messageDao.findTopThree(date); listMc.add(mc); } } rs = exportWord(date, exportWord, listMc, listMt); } catch (Exception e) { e.printStackTrace(); } }else{ List<Message> mes = messageDao.exportMessage(date,orgId); rs = exportExcle(date, mes, exportExcel, orgName); } return rs; }
public int exportWord(Date date,String exportPath, List<MessageCount> listMc, List<MessageTopUser> listMt) throws Exception{ int result = 1; logger.debug("export excle start!,which date is : {}" + date); XWPFDocument doc = new XWPFDocument();//新建一個文檔 XWPFParagraph nav = doc.createParagraph(); nav.setStyle("1"); //1級大綱 XWPFRun runNav = nav.createRun(); runNav.setBold(true); //加粗 runNav.setText("【塔式智能系統每日監測狀況通報】"); String text = DateUtil.date2Str(date) + ","; int alarm = 0,news = 0,danger = 0,duty = 0,other = 0,police = 0,trail = 0; String allOutText = ""; for (int i = 0; i < listMc.size(); i++) { MessageCount list = listMc.get(i); int getalarm = list.getAlarm().intValue();//一鍵報警 int getnews = list.getNews().intValue();//動態 int getdanger = list.getDanger().intValue();//隱患 int getduty = list.getDuty().intValue();//勤務記錄 int getother = list.getOther().intValue();//其餘 int getpolice = list.getPolice().intValue();//警情 int gettrail = list.getTrail().intValue();//線索 alarm += getalarm;//一鍵報警 news += getnews;//動態 danger += getdanger;//隱患 duty += getduty;//勤務記錄 other += getother;//其餘 police += getpolice;//警情 trail += gettrail;//線索 int count = getalarm + getnews + getdanger + getduty + getother + getpolice + gettrail; /*if (count != 0) {}*/ String name = organizationService.findByOrgId(list.getOrgId()).getName().replace("中隊", "所"); allOutText += i+1 +"." + name + count + "條。"; } int allCount = alarm + news + danger + duty + other + police + trail; text += "發佈信息總數" + allCount + "條。"; text += "其中動態" + news + "條,"; text += "警情" + police + "條,"; text += "線索" + trail + "條,"; text += "隱患" + danger + "條,"; text += "勤務記錄" + duty + "條,"; text += "一鍵報警" + alarm + "條,"; text += "其餘" + other + "條。"; XWPFParagraph para = doc.createParagraph(); XWPFRun run = para.createRun(); run.setText(text); run.setFontSize(8); run.setFontFamily("微軟雅黑"); XWPFParagraph everyOrg = doc.createParagraph(); XWPFRun ev = everyOrg.createRun(); ev.setText(allOutText); ev.setFontSize(8); ev.setFontFamily("微軟雅黑"); String topThree = ""; for (int j = 0; j < listMt.size(); j++) { int total = listMt.get(j).getTotal().intValue(); NumberFormat nt = NumberFormat.getPercentInstance(); nt.setMinimumFractionDigits(2);//百分數保留兩位 double divisor = (double)total/allCount; String percent = nt.format(divisor); logger.debug("The export word data for percent is "+percent); /*DecimalFormat df2 = new DecimalFormat("###.00");//保留兩位小數 System.out.println("小數"+df2.format(p));*/ topThree += j+1 + "." + listMt.get(j).getOrgName().replace("中隊", "所") + listMt.get(j).getUname() + ",發佈數" + total + "條,佔比" + percent + "; "; } XWPFParagraph topThreeP = doc.createParagraph(); XWPFRun evp = topThreeP.createRun(); evp.setText(topThree); evp.setFontSize(8); evp.setFontFamily("微軟雅黑"); try { FileOutputStream fout = new FileOutputStream(exportPath); logger.debug("export excle end!"); doc.write(fout); //把doc輸出到輸出流 fout.close(); } catch (Exception e){ result = 0; logger.error("export excle error!,{}",e.getLocalizedMessage()); } return result; }
@SuppressWarnings("deprecation") public int exportExcle(Date date,List<Message> mes,String exportPath,String orgName){ int result = 1; logger.debug("Start export excle,which date is : {}" + date); HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet(DateUtil.date2Str(date)); HSSFRow rowMerging = sheet.createRow((short) 0); HSSFRow row = sheet.createRow((short) 1); //標題樣式 HSSFCellStyle titleStyle = wb.createCellStyle(); titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 居中 titleStyle.setBorderBottom((short)100);// 下邊框 titleStyle.setBorderTop((short)100);// 上邊框 HSSFFont titleFont = wb.createFont(); titleFont.setFontHeightInPoints((short) 20);//設置字體大小 titleFont.setFontName("宋體"); titleFont.setColor(HSSFColor.RED.index);//紅字 titleStyle.setFont(titleFont); //導航行樣式 HSSFCellStyle navStyle = wb.createCellStyle(); navStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); navStyle.setBorderBottom((short)50);// 下邊框 navStyle.setBorderTop((short)50);// 上邊框 HSSFFont font = wb.createFont(); font.setFontName("宋體"); font.setFontHeightInPoints((short) 14); navStyle.setFont(font); sheet.addMergedRegion(new Region(0, (short) (0), 0,(short) (11))); //設置跨行, 四個參數分別是:起始行,起始列,結束行,結束列 //設置列寬,第一個參數表明列id(從0開始),第2個參數表明寬度值 sheet.setColumnWidth(0, 6500); sheet.setColumnWidth(1, 4000); sheet.setColumnWidth(2, 8000); sheet.setColumnWidth(3, 5000); sheet.setColumnWidth(4, 4000); sheet.setColumnWidth(5, 4000); sheet.setColumnWidth(6, 4000); sheet.setColumnWidth(7, 4000); sheet.setColumnWidth(8, 4000); sheet.setColumnWidth(9, 4000); sheet.setColumnWidth(10, 4000); HSSFCell merging = rowMerging.createCell((short) 0); merging.setCellValue(DateUtil.date2Str(date) + orgName + "羣防羣治數據統計表"); merging.setCellStyle(titleStyle); HSSFCell cell = row.createCell((short) 0); cell.setCellValue("時間"); cell.setCellStyle(navStyle); cell = row.createCell((short) 1); cell.setCellValue("主題"); cell.setCellStyle(navStyle); cell = row.createCell((short) 2); cell.setCellValue("描述"); cell.setCellStyle(navStyle); cell = row.createCell((short) 3); cell.setCellValue("發送人"); cell.setCellStyle(navStyle); cell = row.createCell((short) 4); cell.setCellValue("機構ID"); cell.setCellStyle(navStyle); cell = row.createCell((short) 5); cell.setCellValue("機構名稱"); cell.setCellStyle(navStyle); cell = row.createCell((short) 6); cell.setCellValue("派出所ID"); cell.setCellStyle(navStyle); cell = row.createCell((short) 7); cell.setCellValue("所屬派出所"); cell.setCellStyle(navStyle); cell = row.createCell((short) 8); cell.setCellValue("發佈數"); cell.setCellStyle(navStyle); cell = row.createCell((short) 9); cell.setCellValue("發佈率"); cell.setCellStyle(navStyle); cell = row.createCell((short) 10); cell.setCellValue("重複數"); cell.setCellStyle(navStyle); cell = row.createCell((short) 11); cell.setCellValue("不規範數"); cell.setCellStyle(navStyle); //內容樣式 HSSFCellStyle contentStyle = wb.createCellStyle(); contentStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); titleStyle.setBorderBottom((short)50);// 下邊框 titleStyle.setBorderTop((short)50);// 上邊框 HSSFFont fontcontent = wb.createFont(); fontcontent.setFontName("宋體"); fontcontent.setFontHeightInPoints((short) 12); navStyle.setFont(fontcontent); for (int i = 1; i <= mes.size(); i++) { row = sheet.createRow((int) i + 1); Message rs = mes.get(i - 1); HSSFCell cellContent = row.createCell((short) 0); cellContent.setCellValue(DateUtil.toTimeString(rs.getSendTime())); cellContent.setCellStyle(contentStyle); cellContent = row.createCell((short) 1); cellContent.setCellValue(rs.getMsgTypeName()); cellContent.setCellStyle(contentStyle); cellContent = row.createCell((short) 2); cellContent.setCellValue(StringUtil.isNull(rs.getContent())?"":rs.getContent()); cellContent.setCellStyle(contentStyle); cellContent = row.createCell((short) 3); cellContent.setCellValue(rs.getUname()); cellContent.setCellStyle(contentStyle); cellContent = row.createCell((short) 4); cellContent.setCellValue(rs.getOrgId()); cellContent.setCellStyle(contentStyle); cellContent = row.createCell((short) 5); cellContent.setCellValue(rs.getOrgName()); cellContent.setCellStyle(contentStyle); cellContent = row.createCell((short) 6); int ancestors = rs.getAncestors().equals("") ? rs.getOrgId() : Integer.parseInt(rs.getAncestors()); cellContent.setCellValue(ancestors); cellContent.setCellStyle(contentStyle); } try { FileOutputStream fout = new FileOutputStream(exportPath); logger.debug("export excle end!"); wb.write(fout); fout.close(); } catch (Exception e) { result = 0; logger.error("export excle error!,{}",e.getLocalizedMessage()); } return result; }
其實導出是很簡單的,貼上代碼後基本上意思就出來了,無非就是經過使用XWPFDocument、HSSFWorkbook這兩個類,set相關屬性值,數據經過sql從數據庫裏讀取數據作一些相關的循環邏輯,再經過文檔流的形式反饋給客戶端。可能相對來講導入會比較麻煩,首先是從服務端下載一個模板,而後再根據模板填入數據上傳到服務器,這個時候須要作大量的驗證處理,再反饋給客戶有一個預覽界面等等,思路大體是這樣,後續再整理excel導入。shell
poi相關屬性參考:http://poi.apache.org/數據庫
各jar包做用參考:http://www.07net01.com/2014/09/63956.htmlapache