1. 模板标题头,例如
班级名称, 学员名称, 证件号码, 学员状态
2.获取文件 MultipartFile file,校验文件的大小,格式等
public Result<?> importStu(HttpServletRequest request, MultipartFile file, Integer type, HttpSession session, HttpServletResponse response) throws Exception {
if (file == null || file.isEmpty()) {
return ResultEx.error(Constant.ERROR_CODE, "请选择导入文件;", "");
}
long fileSize = file.getSize();
if (fileSize > Constant.FILE_MAX_SIZE) {
return ResultEx.error(Constant.ERROR_CODE, "上传文件超过最大限制,文件最大为" + fileSize +"个字节;10485760=10M", "");
}
String fileName = file.getOriginalFilename();
String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
if (!"xls".equals(suffix) && !"xlsx".equals(suffix)) {
return ResultEx.error(Constant.ERROR_CODE, "上传文件只支持xls和xlsx文件后缀;", "");
}
InputStream fin = file.getInputStream();
Workbook wb=null;
if ("xls".equals(suffix)) {
wb = new HSSFWorkbook(fin);
} else if ("xlsx".equals(suffix)) {
wb = new XSSFWorkbook(fin);
}
Map returnMap = new HashMap<>();
try {
if (null != type ) {
if (type == 1) {//导入学生
//验证导入学员的标题头是否合法
String[] columnName = {"班级名称", "学员名称", "证件号码", "学员状态"};
String result = ExcelUtil.verificationStudentExcelHeadLine(wb, columnName);
if (result != null) {
return ResultEx.error(Constant.ERROR_CODE, result, "");
}
returnMap = classService.importStudent(wb, session, fin);
if (returnMap != null) {
String code = (String) returnMap.get("code");
if (code != null) {
if (code.equals(Consts.REQUEST_SUCCESS)) {
return ResultEx.success(returnMap);
} else if (code.equals(Consts.REQUEST_EXCEPTION)) {
return ResultEx.error(Constant.ERROR_CODE, "导入文件与导出学员的表格表头不一致,无法导入。", "");
}
}
}
//return ReturnResult.success(-1, "导入学员成功数" + returnMap.get("sucNum") + ",错误数" + returnMap.get("errNum") + ",请下载错误文件进行修改再次上传");
}
}
} catch (Exception e) {
e.printStackTrace();
return ResultEx.error(Constant.ERROR_CODE, Constant.ERROR_MSG, "");
}
return ResultEx.success(returnMap);
}
3.校验上传标题行,代碼中的“4”可以用 columnName.length
/***
* 校验导入的学员列表Excel文件标题行是否为标准行
*/
public static String verificationStudentExcelHeadLine(Workbook wb, String[] columnName) throws Exception {
String result = null;
try {
Sheet sheet = wb.getSheetAt(0);
Row row = sheet.getRow(0);
if (row != null && row.getLastCellNum() >= columnName.length) {
int lastCellNum = row.getLastCellNum();
for (int idx = 0; idx < lastCellNum; idx++) {
String value = getCellValue(row.getCell(idx));
if (idx < 4) {
if (StringUtils.isBlank(value) || !columnName[idx].equals(value)) {
result = "标题行第" + (idx + 1) + "列名称错误!";
throw new Exception();
}
} else {
if (idx == 4) {
if (StringUtils.isBlank(value)) {
result = "标题与导出学员的表格表头不一致";
throw new Exception();
}
}
}
}
} else {
result = "上传文件首行不能为空或与导出学员的表格表头不一致!";
}
} catch (Exception ex) {
}
return result;
}
4.导入内容,将合法数据添加到数据库,非法数据写入错误的集合中。添加数据需手动事务,添加出现异常,需手动事务回滚,部分代码如下
List<Student> errorList = new ArrayList<Student>();
if (数据校验通过) {
try {
// 手动控制事务
HibernateTransactionManager txManager = (HibernateTransactionManager) ctx.getBean("transactionManager");
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);// 事物隔离级别,开启新事务
TransactionStatus txStatus = txManager.getTransaction(def);// 获得事务状态
baseDao.saveOne(entity);
// 所有处理完成后,提交事务
txManager.commit(txStatus);
} catch (Exception e){
//异常回滚
txManager.rollback(txStatus);
stu.setErr_msg("数据库服务异常;");
errorList.add(stu);
errCount++;
}
} else {
stu.setErr_msg(errorBuffer.toString());
errorList.add(stu);
errCount++;
}
5.将校验错误数写入,用于下载错误文件
session.setAttribute("errNum", errCount);
session.setAttribute("sucNum", ctList.size()-errCount);
session.setAttribute("total", ctList.size());
//将学员错误列表转json
String studentJson = JsonUtil.toJson(errorList, Include.ALWAYS);
session.setAttribute("studentExcel", studentJson);
注:校验不合法的,将不合法信息写入errorList的最后一列