摘要:基于編程思想,在框架下,將邏輯復雜的代碼放在層下,層只負責調用。
基于MVC編程思想,在springMVC框架下,將邏輯復雜的代碼放在manager層下,controller層只負責調用manager。
(注:前端使用jQuery-file-upload插件)
controller層
@RequestMapping(value = "import_cust_user") @ResponseBody public String importCustUser(HttpSession session, @RequestParam("uploadFiles") MultipartFile excelFile, String brandCode) { //uploadFiles:應與前端jsp中 LOG.info("開始導入用戶信息:brandCode={}", brandCode); JSONObject result = null; try { result = custUserManager.ImportCustUser(excelFile, brandCode, loginName); } catch (Exception e) { LOG.error("導入用戶失敗", e); result.put("result", "failed"); } return result.toJSONString(); }
manager層
//電話號碼為空 private static final String IMPORT_NO_CONTENT = "電話號碼為空"; //電話號已存在 private static final String IMPORT_EXISTED_DATA = "電話號碼已存在"; //無效信息(手機號不滿足11位、手機號不為阿拉伯數字) private static final String IMPORT_INVALID_DATA = "電話號碼必須為11位阿拉伯數字"; /**導入的定制用戶的列*/ private static final String[] importCustUserColumns = {"電話", "姓名", "備注"}; /**導出的定制用戶的列*/ private static final String[] exportCustUserColumns = {"電話", "姓名", "備注", "失敗原因"}; @Override public JSONObject ImportCustUser(MultipartFile excelFile, String brandCode, String loginName) throws Exception { LOG.info("進入導入用戶信息:brandCode={}", brandCode); // 獲取解析excel的wb XSSFWorkbook wb = new XSSFWorkbook(excelFile.getInputStream()); // 返回json JSONObject result = new JSONObject(); // 校驗文件頭部信息是否匹配 if (checkExcelTitles(wb,importCustUserColumns,result)) { // 校驗文件內容是否有錯誤內容 Mapmap = checkExcel(wb, brandCode, loginName); //分別獲取正確和錯誤的的用戶對象list @SuppressWarnings("unchecked") List importCustUserList = (List ) map.get("importCustUserList"); @SuppressWarnings("unchecked") List errorUserList = (List ) map.get("errorUserList"); // 不為空則批量導入 if (!CollectionUtil.isEmpty(importCustUserList)) { custUserInfoService.importUserInfo(importCustUserList); result.put("successCount", importCustUserList.size()); //成功導入的條數 } else { result.put("successCount", 0); } // 不為空則創建導入失敗的文件 if (!CollectionUtil.isEmpty(errorUserList)) { //創建導入失敗的excel對象 XSSFWorkbook errorWb = createExportContent(errorUserList); //創建字節流 ByteArrayOutputStream bos = new ByteArrayOutputStream(); //將excel對象寫入字節流 errorWb.write(bos); //設置文件后綴,將文件上傳至服務器并返回鏈接(有待學習!!這里用的公司寫好的工具類) String suffix = ".xlsx"; String errorUrl = fileUploadService.toUpFile(bos.toByteArray(), FileUpLoadEnum.file, suffix); result.put("errorCount", errorUserList.size()); //導入失敗的條數 result.put("errorUrl", errorUrl); //下載鏈接 } else { result.put("errorCount", 0); } result.put("result", "success"); } else { result.put("result", "failed"); } return result; } //校驗文件頭部信息是否匹配 private boolean checkExcelTitles(XSSFWorkbook wb, String[] titles , JSONObject result) { if (null == wb.getSheetAt(0).getRow(0) || ExcelUtil.isExistTitles(wb, titles)) { result.put("failMsg", "請使用模版進行導入!"); return false; } else { XSSFRow row = wb.getSheetAt(0).getRow(1); //判斷第一行是否有數據 if (row == null) { result.put("failMsg", "導入表格為空,請填寫完信息后重新導入!"); return false; } //有空格的空白行也視為表格為空 boolean flag = false; for (int i = 0; i < importCustUserColumns.length; i++) { if (row.getCell(i) != null && StringUtils.isNotEmpty(ExcelUtil.getStringCellValue(row.getCell(i)))) { flag = true; break; } } if (!flag) { // 判斷第一行是否有數據 result.put("failMsg", "導入表格為空,請填寫完信息后重新導入!"); return false; } //大于5000條不允許導入 int rowSum = wb.getSheetAt(0).getLastRowNum(); if (rowSum > 5000) { // 判斷數據是否大于5000條 result.put("failMsg", "電話信息條數超過5000條,請刪減后重新導入!"); return false; } return true; } } //檢查文件內容是否有誤 private Map checkExcel(XSSFWorkbook wb, String brandCode, String loginName) throws Exception { Map map = new HashMap (); // 不可導入的List List errorUserList = new ArrayList (); // 可成功導入的List List importCustUserList = new ArrayList (); // 獲得第一張表單 XSSFSheet sheet = wb.getSheetAt(0); // 獲得總行數 int rowSum = sheet.getLastRowNum(); // 獲得該品牌下所有用戶信息 List custUserList = custUserInfoService.getCustUserByBrandCode(brandCode); // 手機號List(用于判斷本表單手機號是否重復) List mobileList = new ArrayList (); for (int i = 1; i <= rowSum; i++) { if (null == sheet.getRow(i)) { continue; } // 獲取電話 String mobileNo = null; if (null != sheet.getRow(i).getCell((short) 0)) { mobileNo = ExcelUtil.getStringCellValue(sheet.getRow(i).getCell((short) 0)); if (mobileNo.contains("E")) { //當cell不是文本格式時,手機號會被會被轉換成科學計數,需要用以下方法轉回為手機號 DecimalFormat df = new DecimalFormat("0"); mobileNo = df.format(sheet.getRow(i).getCell((short) 0).getNumericCellValue()); } } //獲取姓名 ... //獲取備注 ... // 校驗數據 String errorReason = ""; if (StringUtils.isEmpty(mobileNo)) { //判斷手機號是否為空 errorReason = IMPORT_NO_CONTENT + ";"; } else if (mobileNo.length() != 11 || !isNotNumeric(mobileNo)) { //判斷手機號是否輸入合法 errorReason += IMPORT_INVALID_DATA + ";"; } if (mobileList.contains(mobileNo) || custUserList.contains(mobileNo)) { //判斷是否與已存在的用戶電話重復 errorReason += IMPORT_EXISTED_DATA + ";"; } else { if (null != mobileNo){ mobileList.add(mobileNo); } } // 創建可導入的list和不可導入的list if (!StringUtils.isEmpty(errorReason)) { errorUserList.add(buildErrorUser(userName, mobileNo, remark, errorReason)); } else { importCustUserList.add(buildUser(brandCode, userName, mobileNo, remark, loginName)); } } map.put("errorUserList", errorUserList); map.put("importCustUserList", importCustUserList); return map; } //創建導入失敗的excel文件 private XSSFWorkbook createExportContent(List errorUserList) { // 創建XSSFWorkbook XSSFWorkbook wb = new XSSFWorkbook(); // 創建表單并設置cell寬度 XSSFSheet currentSheet = wb.createSheet("Sheet1"); currentSheet.setDefaultColumnWidth(20); // 創建表頭 createTitle(currentSheet,exportCustUserColumns); // 創建cellStyle XSSFCellStyle style = wb.createCellStyle(); style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND); //設置cell底色 style.setFillForegroundColor(new XSSFColor(Color.red)); // 插入表內容 int currentRow = 1; Row row = currentSheet.getRow(0); Cell cell = null; for (CustUserImportError errorUser : errorUserList) { int cellIndex = 0; // 行 row = currentSheet.createRow(currentRow); // 列 cell = row.createCell(cellIndex++); cell.setCellValue(errorUser.getMobileNo()); cell = row.createCell(cellIndex++); cell.setCellValue(errorUser.getUserName()); cell = row.createCell(cellIndex++); cell.setCellValue(errorUser.getRemark()); cell = row.createCell(cellIndex++); cell.setCellValue(errorUser.getErrorReason()); // 最后一個單元格設置樣式 cell.setCellStyle(style); currentRow += 1; } return wb; } //創建導入失敗的表頭 private void createTitle(XSSFSheet sheet, String[] titles) { Row row = sheet.createRow(0); for (int i = 0; i < titles.length; i++) { Cell cell = row.createCell(i); cell.setCellValue(titles[i]); } }
到這里基本完成了導入工作,導出失敗的excel文件如下:
因為在做導入工作時,已經將失敗的文件上傳至服務器并返回了鏈接,所以這里只要寫如何將文件寫到本地
同樣式剛才的controller層
@RequestMapping(value = "download_excel") public void downloadExcel(String downloadUrl, HttpServletRequest request, HttpServletResponse response) throws IOException { LOG.info("開始下載導入失敗的用戶信息:downloadUrl={}", downloadUrl); InputStream in = null; //輸入流 OutputStream out = null; //輸出流 try { //需要下載的文件鏈接 URL url = new URL(downloadUrl); //建立連接 URLConnection conn = url.openConnection(); //根據鏈接獲得輸入流 in = conn.getInputStream(); //文件名 String fileName = FAILED_FILE_NAME; //設置響應 response.setContentType("application/x-excel"); response.setCharacterEncoding("UTF-8"); response.setHeader("Content-Disposition", "attachment; filename=" + new String(fileName.getBytes("GB2312"), "ISO-8859-1")); //獲得輸出流 out = response.getOutputStream(); byte[] data = new byte[1024]; int len = 0; while ((len = in.read(data, 0, data.length)) != -1) { out.write(data, 0, len); } } catch (Exception e) { LOG.error("下載文件異常", e); } finally { if (in != null) { in.close(); } if (out != null) { out.close(); } } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76394.html
摘要:我想能不能像配置文件一樣可配置的導入導出,那樣使用起來就方便許多。配置和使用下面是員工信息模型。支持多種映射,使用英文逗號進行分割。導入時它會以分割前面的作為導入時使用的值,后面的作為導出時使用的值后面值進行逆推導出時同理。 1.前言 在工作時,遇到過這樣的需求,需要靈活的對工單進行導入或導出,以前自己也做過,但使用不靈活繁瑣。我想能不能像配置文件一樣可配置的導入導出,那樣使用起來就方...
摘要:雖然我們可以在網上參照各種模板項目文章博客等創建一個數據科學項目,但是目前也沒有教科書對這些知識做一個統一的回答。舉個例子來說,數據科學分析項目通常就不需要部署和監控這兩個過程。創建文件描述源數據及位置。進一步探索和報告在整個數據科學項目中 摘要:?在一個新的數據科學項目,你應該如何組織你的項目流程?數據和代碼要放在那里?應該使用什么工具?在對數據處理之前,需要考慮哪些方面?讀完本文...
摘要:導入信息反饋成功條,失敗條導出失敗原因總結現在這種實現,比之前好了一些,但感覺有些地方實現還是不好,歡迎大家提出改進意見。 問題描述 之前excel導入的時候,當發生錯誤的我們只是提供一個導入失敗的錯誤提示很不友好,為此為導入增加錯誤信息的反饋,設計方案是在導入之后,將導入的結果返回回來,由于可能涉及到大量的數據導入所以將錯誤信息放在原導入excle的后面,導入完成后重新下載含有反饋信...
摘要:之后因為身份證中也可能含有字母所以解決方法改為將單元格的類型設置為文本類型。解決報錯固定保存的長度時,就不會產生第一個異常了。身份證長度為十八位返回前臺僅支持寫入輸出時,將忽略掉該字段并不存在數據表中只用于前臺使用 問題描述 在導入學生信息的時候發現導入成功之后結果顯示是錯誤的,錯誤如下所示 showImg(https://segmentfault.com/img/bVbri3M?w=...
閱讀 638·2021-11-25 09:43
閱讀 1906·2021-11-17 09:33
閱讀 824·2021-09-07 09:58
閱讀 2062·2021-08-16 10:52
閱讀 482·2019-08-30 15:52
閱讀 1722·2019-08-30 15:43
閱讀 974·2019-08-30 15:43
閱讀 2924·2019-08-29 16:41