概述
需求: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哈哈~
功能的实现肯定小菜一碟,只要思路清晰每个开发都可以实现,但是我们要做的是高效简便的实现,性能就是第一要解决的问题,从代码上进行优化,让我们的程序简洁明了高效。做一个高效的人,从代码开始!
最后
以上就是轻松蜜粉为你收集整理的Excel导入性能优化的全部内容,希望文章能够帮你解决Excel导入性能优化所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复