首先需要導入包 然後寫方法,由於我使用的框架全部是spring 此處我只寫入實現層和控制層代碼 其中有個selectMatYearPlan(MAT_NO_, MAT_DESC_, MAT_TYPE_, MAT_SPEC_CAT_CODE_, COM_CODE_, DEPT_CODE_, YEAR_, ...
首先需要導入包
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook;
然後寫方法,由於我使用的框架全部是spring
此處我只寫入實現層和控制層代碼
@Override public InputStream loadMatComYearPlanXls(String MAT_NO_, String MAT_DESC_, Integer MAT_TYPE_, String MAT_SPEC_CAT_CODE_, String COM_CODE_, String DEPT_CODE_, Integer YEAR_, Integer MONTH_, String MAT_BUDGET_CAT_ID_, String MAT_YEAR_PLN_BATCH_ID_, Map<String, Object> operator) { NPOIFSFileSystem fs = null; Workbook workbook = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { File file = new File(this.getClass().getResource("/../../resource/matComYearPlan.xls").getFile()); FileInputStream inputStream = new FileInputStream(file); fs = new NPOIFSFileSystem(inputStream); workbook = (Workbook) new HSSFWorkbook(fs.getRoot(), true); Sheet sheet = workbook.getSheetAt(0); List<Map<String, Object>> matYearPlanList = selectMatYearPlan(MAT_NO_, MAT_DESC_, MAT_TYPE_, MAT_SPEC_CAT_CODE_, COM_CODE_, DEPT_CODE_, YEAR_, MONTH_, MAT_BUDGET_CAT_ID_, MAT_YEAR_PLN_BATCH_ID_, 1, -1, operator); List<Map<String, Object>> matTypedmCodeList = dmCodeService.selectDmCodeByGroupName("MAT_TYPE_", operator); List<Map<String, Object>> processStatusTypedmCodeList = dmCodeService.selectDmCodeByGroupName("PROCESS_STATUS_TYPE_", operator); List<Map<String, Object>> matBudgetCatList = matBudgetCatService.selectMatBudgetCat(1, -1, operator); List<Map<String, Object>> matSpecCatList = matSpecCatService.selectMatSpecCat(1, -1, operator); Map<String, Object> matYearPlan; String MAT_BUDGET_CAT_NAME_ = ""; String PARENT_MAT_BUDGET_CAT_ID_; for (int i = 0; i < matYearPlanList.size(); i++) { matYearPlan = matYearPlanList.get(i); Row row = sheet.createRow(i + 1); row.createCell(0).setCellValue((String) matYearPlan.get("MAT_NO_")); row.createCell(1).setCellValue((String) matYearPlan.get("MAT_DESC_")); row.createCell(2).setCellValue((String) matYearPlan.get("LARGE_MAT_CAT_CODE_")); row.createCell(3).setCellValue((String) matYearPlan.get("UNIT_")); if (matYearPlan.get("PLANNED_PRICE_") != null) { row.createCell(4).setCellValue(((BigDecimal) matYearPlan.get("PLANNED_PRICE_")).doubleValue()); } if (matYearPlan.get("AMOUNT_") != null) { row.createCell(5).setCellValue(((BigDecimal) matYearPlan.get("AMOUNT_")).doubleValue()); } if (matYearPlan.get("PLANNED_PRICE_") != null && matYearPlan.get("AMOUNT_") != null) { row.createCell(6).setCellValue(((BigDecimal) matYearPlan.get("PLANNED_PRICE_")).doubleValue() * ((BigDecimal) matYearPlan.get("AMOUNT_")).doubleValue()); } if (matYearPlan.get("MAT_TYPE_") != null) { for (int j = 0; j < matTypedmCodeList.size(); j++) { Map<String, Object> matTypedmCode = matTypedmCodeList.get(j); if ((((BigDecimal) matYearPlan.get("MAT_TYPE_")).intValue()) == (((BigDecimal) matTypedmCode.get("CODE_"))).intValue()) { row.createCell(7).setCellValue((String) matTypedmCode.get("VALUE_")); break; } } } row.createCell(8).setCellValue((String) matYearPlan.get("DEPT_NAME_")); for (int j = 0; j < matBudgetCatList.size(); j++) { Map<String, Object> matBudgetCat = matBudgetCatList.get(j); if (((String) matYearPlan.get("MAT_BUDGET_CAT_ID_")).equals((String) matBudgetCat.get("MAT_BUDGET_CAT_ID_"))) { MAT_BUDGET_CAT_NAME_ = (String) matBudgetCat.get("MAT_BUDGET_CAT_NAME_"); PARENT_MAT_BUDGET_CAT_ID_ = (String) matBudgetCat.get("PARENT_MAT_BUDGET_CAT_ID_"); while (PARENT_MAT_BUDGET_CAT_ID_ != null) { for (int k = 0; k < matBudgetCatList.size(); k++) { matBudgetCat = matBudgetCatList.get(k); if (PARENT_MAT_BUDGET_CAT_ID_.equals((String) matBudgetCat.get("MAT_BUDGET_CAT_ID_"))) { MAT_BUDGET_CAT_NAME_ = (String) matBudgetCat.get("MAT_BUDGET_CAT_NAME_") + "/" + MAT_BUDGET_CAT_NAME_; PARENT_MAT_BUDGET_CAT_ID_ = (String) matBudgetCat.get("PARENT_MAT_BUDGET_CAT_ID_"); break; } } } row.createCell(9).setCellValue("/" + MAT_BUDGET_CAT_NAME_ + "/"); break; } } if (matYearPlan.get("MAT_SPEC_CAT_CODE_") != null) { for (int j = 0; j < matSpecCatList.size(); j++) { Map<String, Object> matSpecCat = matSpecCatList.get(j); if (((String) matYearPlan.get("MAT_SPEC_CAT_CODE_")).equals((String) matSpecCat.get("CODE_"))) { row.createCell(10).setCellValue((String) matSpecCat.get("VALUE_")); break; } } } if (matYearPlan.get("PROCESS_STATUS_") != null) { for (int j = 0; j < processStatusTypedmCodeList.size(); j++) { Map<String, Object> processStatusTypedmCode = processStatusTypedmCodeList.get(j); if ((((BigDecimal) matYearPlan.get("PROCESS_STATUS_")).intValue()) == (((BigDecimal) processStatusTypedmCode.get("CODE_")).intValue())) { row.createCell(11).setCellValue((String) processStatusTypedmCode.get("VALUE_")); break; } } } } workbook.write(baos); baos.flush(); byte[] bytes = baos.toByteArray(); return new ByteArrayInputStream(bytes, 0, bytes.length); } catch (Exception e) { e.printStackTrace(); return null; } finally { try { fs.close(); workbook.close(); baos.close(); } catch (IOException e) { } } }
其中有個selectMatYearPlan(MAT_NO_, MAT_DESC_, MAT_TYPE_, MAT_SPEC_CAT_CODE_, COM_CODE_, DEPT_CODE_, YEAR_, MONTH_, MAT_BUDGET_CAT_ID_, MAT_YEAR_PLN_BATCH_ID_, 1, -1, operator);方法是我的業務方法,可根據需要改變自己實際的參數,對自己的代碼進行修改
Row row = sheet.createRow(i + 1);
row.createCell(0).setCellValue((String) matYearPlan.get("MAT_NO_"));
這兩句代碼是與其他人不同的地方,有些人的代碼是getRow(),getCell()。那樣很可能會報空指針異常,如果以前有數據只是對其覆蓋可以使用,如果以前沒有數據,是動態生成的最後使用create方法
另外我在代碼中大量使用了String造型,而不是toString()方法,因為String相對於tostring()方法更安全,而其不會報空指針異常。而toString()方法有時會需要重寫,不是那麼安全。
=null.toString()會有空指針異常,而 =(String)null則不會。
//控制層代碼 @RequestMapping(value = "loadMatComYearPlanXls") public void loadMatComYearPlanXls(String MAT_NO_, String MAT_DESC_, Integer MAT_TYPE_, String MAT_SPEC_CAT_CODE_, String COM_CODE_, String DEPT_CODE_, Integer YEAR_, Integer MONTH_, String MAT_BUDGET_CAT_ID_, String MAT_YEAR_PLN_BATCH_ID_, HttpServletRequest request, HttpServletResponse response, HttpSession session) { try { Map<String, Object> operator = getOperator(session); InputStream inputStream = matYearPlanService.loadMatComYearPlanXls(MAT_NO_, MAT_DESC_, MAT_TYPE_, MAT_SPEC_CAT_CODE_, COM_CODE_, DEPT_CODE_, YEAR_, MONTH_, MAT_BUDGET_CAT_ID_, MAT_YEAR_PLN_BATCH_ID_, operator); response.reset(); String fileName = URLEncoder.encode("廠礦年計劃表.xls", "UTF-8"); response.setHeader("Content-Disposition", "attachment; filename=" + fileName); ServletOutputStream out = response.getOutputStream(); byte[] content = new byte[65535]; int length = 0; if (inputStream != null) { while ((length = inputStream.read(content)) != -1) { out.write(content, 0, length); } } out.flush(); out.close(); } catch (Exception e) { insertBizLog("業務", "MatYearPlanController.loadMatComYearPlanXls", null, null, null, null, null, 1, e.getMessage(), request, session); logger.error(e.getMessage(), e); } insertBizLog("業務", "MatYearPlanController.loadMatComYearPlanXls", null, null, null, null, null, 0, null, request, session); }
控制層主要是調用實現層代碼。主要的POI代碼在實現層,網上有很多這類代碼,只是我自己對空指針的處理做了自己的改變,網路上說的很多方法不全。
另外這這次的業務實現里,有個BigDecimal類型,http://baike.baidu.com/link?url=abJmNaoqJGE0RbYpjmOCB4otjPPqhpwYPSlMkVwPV6c_0V8I42VljBvaDtCI6h-xNIn5N5CFjrWPvvz4A132lK
由於將值放進map時都是Object類型,但在取出時,它的類型並沒有丟失,所以在.intValue(),和.doubleValue()取值時,與String不同,同時需要做空值處理
如果不想使用造型可以使用parse解析。
中間有段代碼是做的樹形的迴圈遞歸遍歷。
//在jsp頁面的調用 function _loadMatComYearPlanXls() { var MAT_BUDGET_CAT_ID_ = ''; var records = Ext.getCmp('matBudgetCatPanel').getSelectionModel().getSelection(); if (records.length != 0) { MAT_BUDGET_CAT_ID_ = records[0].get('MAT_BUDGET_CAT_ID_'); } window.open('loadMatComYearPlanXls.do?YEAR_=' + Ext.getCmp('YEAR_').getSubmitValue() + '&MONTH_=' + Ext.getCmp('MONTH_').getSubmitValue() + '&MAT_TYPE_=' + Ext.getCmp('MAT_TYPE_').getSubmitValue() + '&MAT_YEAR_PLN_BATCH_ID_=' + Ext.getCmp('MAT_YEAR_PLN_BATCH_ID_').getSubmitValue() + '&DEPT_CODE_=' + Ext.getCmp('DEPT_CODE_').getSubmitValue() + '&MAT_NO_=' + Ext.getCmp('MAT_NO_').getSubmitValue() + '&MAT_DESC_=' + Ext.getCmp('MAT_DESC_').getSubmitValue() + '&MAT_SPEC_CAT_CODE_=' + Ext.getCmp('MAT_SPEC_CAT_CODE_').getSubmitValue() + '&COM_CODE_=' + COM_CODE_ + '&MAT_BUDGET_CAT_ID_=' + MAT_BUDGET_CAT_ID_, '_blank', 'width=40,height=30,resizable=yes,scrollbars=yes'); }
JSP頁面只是調用控制層代碼,如果自己有需要,可以按自己的方法傳參調用。
poi的API文檔:http://poi.apache.org/apidocs/org/apache/poi/xssf/streaming/SXSSFWorkbook.html#SXSSFWorkbook(org.apache.poi.xssf.usermodel.XSSFWorkbook)
歡迎大家閱覽,多多評論其中的不足!!
為工程師之路添磚加瓦!!