需求:http://blog.csdn.net/u013036274/article/details/51848592继上次的导入Excel数据实现,但是导入的太慢。因为保存数据库之前需要查重,查询数据库的次数太多,有多少条数据就查询多少次数据库,导致导入数据越多,导入速度越慢,性能有待提高,于是乎,先从代码优化做起吧。
思路:由于是学生信息的导入,学生的学号就是主键,而且学生的学号也是根据年份、学院、专业、班级等有规律的,所以如果要查询某学号是否存在,可以缩小范围到在一个班级内查重即可。所以先根据班级名称查询,合格的班级名称才可以进行下一步验证,再根据正确的班级名称查出对应的学号,对学号进行查重。合格的学号的学生信息则可以保存到数据库中。具体实现如下:
【controller】
/** * @author -徐志鹏、郑艳霞 * @MethodName : importStudent * @Description : 导入 * @throws Exception */ @RequestMapping(value = "/student/importStudent", method = RequestMethod.POST) public void importStudent(HttpServletResponse response, HttpServletRequest request) { // 动态获取数据库名称 String dataBaseName = (String) request.getSession().getAttribute( CloudContext.DatabaseName) + "_basic"; // 创建一个通用的多部分解析器 CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver( request.getSession().getServletContext()); InputStream inExcelFile = null; // 判断 request 是否有文件上传,即多部分请求importDailyResult if (multipartResolver.isMultipart(request)) { // 转换成多部分request MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request; // 取得request中的所有文件名 Iterator<String> iter = multiRequest.getFileNames(); while (iter.hasNext()) { // 记录上传过程起始时的时间,用来计算上传时间 int pre = (int) System.currentTimeMillis(); // 取得上传文件 MultipartFile file = multiRequest.getFile(iter.next()); try { inExcelFile = file.getInputStream(); } catch (IOException e) { e.printStackTrace(); } } } // 创建一个list 用来存储读取的Excel的内容 List<Student> excelStudentList = new ArrayList<Student>(); // 创建一个list集合,保存无法导入的数据 List<Student> errorStudentList = new ArrayList<Student>(); String result = "error"; try { excelStudentList = this.getExcelData(inExcelFile); if (excelStudentList == null && excelStudentList.size() < 0) { result = "error"; } else { errorStudentList = studentBean.importExcel(dataBaseName, excelStudentList); if (errorStudentList == null) { result = "success"; } else { result = "error"; this.ExportExcel(errorStudentList); } } } catch (Exception e) { result = "error"; } jacksonJsonUntil.beanToJson(response, result); }
/** * 把输入流文件转变成list集合 * * @param inExcelFile * @return */ public List<Student> getExcelData(InputStream inExcelFile) { // 创建一个list 用来存储读取的内容 List<Student> list = new ArrayList<>(1); Workbook rwb = null; // 获取Excel文件对象 try { rwb = Workbook.getWorkbook(inExcelFile); } catch (BiffException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // 获取文件的指定工作表 默认的第一个 Sheet sheet = rwb.getSheet(0); // 行数(表头的目录不需要,从1开始) System.out.println(sheet.getRows()); for (int i = 1; i < sheet.getRows(); i++) { Student model = new Student(); model.setCode(sheet.getCell(0, i).getContents()); // 第一列:学号 model.setName(sheet.getCell(1, i).getContents()); // 第二列:姓名 model.setSex(sheet.getCell(2, i).getContents()); // 第三列:性别 model.setClassName(sheet.getCell(3, i).getContents()); // 第四列:班级名称 model.setEntranceDate(sheet.getCell(4, i).getContents()); // 第五列:入学日期 model.setIdentityCardID(sheet.getCell(5, i).getContents()); // 第六列:身份证号 model.setNativePlaceNativePlace(sheet.getCell(6, i).getContents()); // 第七列:籍贯 model.setNation(sheet.getCell(7, i).getContents()); // 第八列:民族 model.setPoliticalStatus(sheet.getCell(8, i).getContents()); // 第九列:政治面貌 model.setAccountAddress(sheet.getCell(9, i).getContents()); // 第十列:户口所在地 model.setOriginalPlace(sheet.getCell(10, i).getContents()); // 第十一列:生源地 model.setGraduatedSchool(sheet.getCell(11, i).getContents()); // 第十二列:毕业院校 model.setEmail(sheet.getCell(12, i).getContents()); // 第十二列:电子邮箱 model.setTelNum(sheet.getCell(13, i).getContents()); // 第十二列:手机 // 把刚获取的列存入list list.add(model); } return list; }
/** * 将导入失败的数据导出至Excel表--郑艳霞--2016年8月2日16:22:38-v5.0 * * @param studentList */ @SuppressWarnings("deprecation") public void ExportExcel(List<Student> studentList) { // 第一步,创建一个webbook,对应一个Excel文件 @SuppressWarnings("resource") HSSFWorkbook wb = new HSSFWorkbook(); // 第二步,在webbook中添加一个sheet,对应Excel文件中的sheet HSSFSheet sheet = wb.createSheet("导入失败的学生"); // 第三步,在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short HSSFRow row = sheet.createRow((int) 0); // 第四步,创建单元格,并设置值表头 设置表头居中 HSSFCellStyle style = wb.createCellStyle(); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式 HSSFCell cell = row.createCell((short) 0); cell.setCellValue("学号"); cell.setCellStyle(style); cell = row.createCell((short) 1); cell.setCellValue("姓名"); cell.setCellStyle(style); cell = row.createCell((short) 2); cell.setCellValue("性别"); cell.setCellStyle(style); cell = row.createCell((short) 3); cell.setCellValue("所属班级"); cell.setCellStyle(style); cell = row.createCell((short) 4); cell.setCellValue("入学日期"); cell.setCellStyle(style); cell = row.createCell((short) 5); cell.setCellValue("身份证号"); cell.setCellStyle(style); cell = row.createCell((short) 6); cell.setCellValue("籍贯"); cell.setCellStyle(style); cell = row.createCell((short) 7); cell.setCellValue("民族"); cell.setCellStyle(style); cell = row.createCell((short) 8); cell.setCellValue("政治面貌"); cell.setCellStyle(style); cell = row.createCell((short) 9); cell.setCellValue("户口所在地"); cell.setCellStyle(style); cell = row.createCell((short) 10); cell.setCellValue("生源地"); cell.setCellStyle(style); cell = row.createCell((short) 11); cell.setCellValue("毕业学校"); cell.setCellStyle(style); cell = row.createCell((short) 12); cell.setCellValue("电子邮箱"); cell.setCellStyle(style); cell = row.createCell((short) 13); cell.setCellValue("手机"); cell.setCellStyle(style); // 第五步,写入实体数据 实际应用中这些数据从数据库得到, for (int i = 0; i < studentList.size(); i++) { row = sheet.createRow((int) i + 1); Student student = (Student) studentList.get(i); // 第四步,创建单元格,并设置值 row.createCell((short) 0).setCellValue(student.getCode()); row.createCell((short) 1).setCellValue(student.getName()); row.createCell((short) 2).setCellValue(student.getSex()); row.createCell((short) 3).setCellValue(student.getClassName()); row.createCell((short) 4).setCellValue(student.getEntranceDate()); row.createCell((short) 5).setCellValue(student.getIdentityCardID()); row.createCell((short) 6).setCellValue( student.getNativePlaceNativePlace()); row.createCell((short) 7).setCellValue(student.getNation()); row.createCell((short) 8) .setCellValue(student.getPoliticalStatus()); row.createCell((short) 9).setCellValue(student.getAccountAddress()); row.createCell((short) 10).setCellValue(student.getOriginalPlace()); row.createCell((short) 11).setCellValue( student.getGraduatedSchool()); row.createCell((short) 12).setCellValue(student.getEmail()); row.createCell((short) 13).setCellValue(student.getTelNum()); } // 第六步,将文件存到指定位置 try { FileSystemView fsv = FileSystemView.getFileSystemView(); Date currentTime = new Date(); SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddhhmmss"); String dateString = formatter.format(currentTime); String deskPath = fsv.getHomeDirectory().toString() + "/导入失败的学生数据" + dateString + ".xls"; FileOutputStream fout = new FileOutputStream(deskPath); wb.write(fout); fout.close(); } catch (Exception e) { e.printStackTrace(); } }
【StudentBeanImpl】
/** * 导入学生--郑艳霞-2016年8月2日15:44:48-v5.0 * * @param dataBaseName * @param studentList * @return */ @Override public List<Student> importExcel(String dataBaseName, List<Student> excelList) { // 创建一个list集合,保存无法导入的数据 List<Student> errorStudentList = new ArrayList<Student>(); // 创建一个list集合,保存可以导入的数据 List<Student> studentList = new ArrayList<Student>(); List<Student> Nonlist = new ArrayList<Student>(); Nonlist.add(null); // 创建一个集合,保存班级名称 List<Classes> classNameList = new ArrayList<Classes>(); Classes classes = new Classes(); // for循环获取班级名称,存入List<Classes> classNameList for (int i = 0; i < excelList.size(); i++) { classes.setClassName(excelList.get(i).getClassName()); classNameList.add(classes); } // 根据班级名称查询班级信息(classId和className) List<Classes> classIdAndNameList = studentEao .queryClassInfoByClassNameList(classNameList, dataBaseName); // 创建一个集合,保存classId List<Student> classIdsList = new ArrayList<Student>(); Classes classEntity = new Classes(); // 6.判断查询出来班级名称classidList和导入的班级名称是否有相同, // 如果有再进行第7步,没有则将对应信息添加到errorList for (int j = 0; j < excelList.size(); j++) { for (int s = 0; s < classIdAndNameList.size(); s++) { if (excelList .get(j) .getClassName() .toString() .equals(classIdAndNameList.get(s).getClassName() .toString())) { // 如果班级名称相同,则从查出来的数据中取出班级Id放入excelList中的classesId中 excelList.get(j).setClassesId( classIdAndNameList.get(s).getId().toString()); break; } } // 7.如果导入数据的班级名称与查询出来的班级名称没有相同的,则将数据加入到errorStudentList中 if (excelList.get(j).getClassesId() == null) { errorStudentList.add(excelList.get(j)); excelList.remove(j); excelList.removeAll(Nonlist); j = j - 1; } } // 9.根据班级Id的list查询班级Id和学生code List<Student> studentCodeAndClassIdList = studentEao .queryStudentCodeByClassesIdList(excelList, dataBaseName); for (int j = 0; j < excelList.size(); j++) { for (int s = 0; s < studentCodeAndClassIdList.size(); s++) { System.out.println(excelList.get(j).getCode().toString()); System.out.println(studentCodeAndClassIdList.get(s).getCode() .toString()); if (excelList .get(j) .getCode() .toString() .equals(studentCodeAndClassIdList.get(s).getCode() .toString())) { errorStudentList.add(excelList.get(j)); excelList.remove(j); excelList.removeAll(Nonlist); break; } } j = j - 1; } // 10.遍历要导入的数据,并将数据add到studentlist中 Student student = new Student(); for (int i = 0; i < excelList.size(); i++) { String classesId = excelList.get(i).getClassesId(); // 3.将该条信息添加到学生实体中 // 将学生信息添加进studentList中--start String id = CreateUUID22.getUUID22(); student.setId(id); student.setCode(excelList.get(i).getCode()); student.setName(excelList.get(i).getName()); student.setSex(excelList.get(i).getSex()); student.setClassesId(classesId); student.setEntranceDate(excelList.get(i).getEntranceDate()); student.setIdentityCardID(excelList.get(i).getIdentityCardID()); student.setNativePlaceNativePlace(excelList.get(i) .getNativePlaceNativePlace()); student.setNation(excelList.get(i).getNation()); student.setPoliticalStatus(excelList.get(i).getPoliticalStatus()); student.setAccountAddress(excelList.get(i).getAccountAddress()); student.setOriginalPlace(excelList.get(i).getOriginalPlace()); student.setGraduatedSchool(excelList.get(i).getGraduatedSchool()); student.setEmail(excelList.get(i).getEmail()); student.setTelNum(excelList.get(i).getTelNum()); student.setDataBaseName(dataBaseName); studentList.add(student); // 将学生信息添加进studentList中--end } // 将学生信息导入到数据库-start if (studentList.size() > 0) { this.saveEntitys(studentList); } // 将学生信息导入到数据库-end return errorStudentList; }
其他代码不在赘述。感谢红霞霞的指导O(∩_∩)O哈哈~
功能的实现肯定小菜一碟,只要思路清晰每个开发都可以实现,但是我们要做的是高效简便的实现,性能就是第一要解决的问题,从代码上进行优化,让我们的程序简洁明了高效。做一个高效的人,从代码开始!