import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import com.wondertek.pis.bean.vo.UserTemplateVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import com.wondertek.pis.config.CodeEnum;
import com.wondertek.pis.constant.ExcelErrorConstant;
import com.wondertek.pis.constant.ExcelExportTypeEnum;
import com.wondertek.pis.constant.ExcelImportTypeEnum;
/**
* Excel导入和导出工具类
*
* @author zy
* 2019年12月2日09:22:44
*/
@Slf4j
public class ExcelUtil {
/**
* 导出到excel
* 只负责将传来的字符串数组集合写入到excel
* 一个字符串数组代表一行的数据(数组里数据顺序要跟导出模板一一对应)
*
* @param type 导出模板类型
* @param dataList 导出数据字符串集合
* @param response
* @param
* @return HttpServletResponse
*/
public static ResultBean exportExcel(ExcelExportTypeEnum type, List<String[]> dataList, HttpServletResponse response) throws IOException {
if (CollectionUtils.isEmpty(dataList)) {
return ResultBean.error(CodeEnum.EXPORT_ERROR, ExcelErrorConstant.DATA_EMPTY);
}
//获取模板文件
InputStream template = ExcelUtil.class.getResourceAsStream("/template/" + type.toString() + ".xlsx");
if (ObjectUtils.isEmpty(template)) {
return ResultBean.error(CodeEnum.EXPORT_ERROR, ExcelErrorConstant.TEMP_ERROR);
}
//开始导出
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(template);
XSSFSheet sheetAt = xssfWorkbook.getSheetAt(0);
for (int i = 0; i < dataList.size(); i++) {
XSSFRow row = sheetAt.createRow(i + 1);
String[] data = dataList.get(i);
for (int j = 0; j < data.length; j++) {
row.createCell(j).setCellValue(data[j]);
}
}
String fileName = TimeUtil.localDateFormat(LocalDateTime.now(), "yyyyMMddHHmmss") + ".xlsx";
//设置文件下载头
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
//设置文件ContentType类型,这样设置,会自动判断下载文件类型
response.setContentType("application/octet-stream;charset=UTF-8");
try {
xssfWorkbook.write(response.getOutputStream());
xssfWorkbook.close();
} catch (IOException e) {
return ResultBean.error(CodeEnum.EXPORT_ERROR);
}
/*
导出成功writer已经关闭了 不用再返回
要不然会报Cannotcall sendError() after the response has been committed错误
*/
return null;
}
/**
* 从Excel导入数据
*
* @param importType 导入模板类型
* @param importFileStream 导入文件输入流
* @return 如果成功,resultbean里放着List<String[]>(只是原样读取了上传文件里的数据,接收后需自行转换为数据表中相应的数据类型)
* 如果失败,可直接返回这个resultbean给前端,里面包含错误信息
*/
public static ResultBean importExcel(ExcelImportTypeEnum importType, InputStream importFileStream) {
if (ObjectUtils.isEmpty(importFileStream)) {
return ResultBean.error(CodeEnum.IMPORT_ERROR, "File stream is empty!");
}
ResultBean resultBean = null;
try {
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(importFileStream);
switch (importType) {
case USER:
resultBean = startUserImport(xssfWorkbook);
break;
case CLOCK:
resultBean = startClockImport(xssfWorkbook);
break;
case ABSENCE:
resultBean = startAbsenceImport(xssfWorkbook);
break;
case FINANCE:
resultBean = startFinanceImport(xssfWorkbook);
break;
default:
resultBean = ResultBean.error(CodeEnum.CUSTON_ERROR, ExcelErrorConstant.FILE_NOT_EXIST);
}
} catch (IOException e) {
ResultBean.error(CodeEnum.UNKNOW_ERROR);
}
return resultBean;
}
/**
* 用户信息导入
*
* @param xssfWorkbook
* @return
*/
private static ResultBean startUserImport(XSSFWorkbook xssfWorkbook) {
// XSSFSheet sheetAt = xssfWorkbook.getSheetAt(0);
// int rows = sheetAt.getLastRowNum();
// List<String[]> dataList = new ArrayList<>();
// List<String> userCodeList = new ArrayList<>();
// int rowNum = 0;
// try {
// for (int j = 0; j < rows; j++) {
// Row row = sheetAt.getRow(j);
// if(row == null || row.getRowNum() == 0){
// continue;
// }
// //创建一个跟导入模板列数相同的数组
// //用户工号 用户姓名 邮箱 入职日期 离职日期 就职状态 所属公司 所属部门 岗位名称 评定人 部门领导
// String[] data = new String[11];
// for (int i = 0; i < data.length; i++) {
// data[i] = row.getCell(i).toString();
// //工号校验是否重复
// if (i == 0) {
// if (userCodeList.contains(data[i])) {
// return ResultBean.error(CodeEnum.IMPORT_ERROR, String.format(ExcelErrorConstant.USERCODE_TWO, rowNum + 1, i + 1, data[i]));
// } else {
// userCodeList.add(data[i]);
// }
// //校验入职时间和离职日期
// if (i == 3 || i == 4) {
// try {
// //对转换日期错误的列做失败处理
// TimeUtil.stringToLocalDate(data[i], TimeUtil.YEAR_MONTH_DAY);
// } catch (Exception e) {
// return ResultBean.error(CodeEnum.IMPORT_ERROR, String.format(ExcelErrorConstant.DATE_ERROR,
// rowNum + 1, i + 1, data[i], TimeUtil.DATE_TIME));
// }
// }
// }
// }
// rowNum++;
// dataList.add(data);
// }
// } catch (Exception e) {
// log.error(e.getMessage(), e);
// return ResultBean.error(CodeEnum.IMPORT_ERROR,String.format(ExcelErrorConstant.DATE_ERROR,
// rowNum + 1, e.getMessage()));
// }
// return ResultBean.ok(dataList);
XSSFSheet sheetAt = xssfWorkbook.getSheetAt(0);
//获取sheet页签的最后一行数据的行号
int lastRowNum = sheetAt.getLastRowNum();
ArrayList<UserTemplateVo> arrayList = new ArrayList<>();
//获取每一条数据
for(int i=1;i<=lastRowNum;i++){
UserTemplateVo vo = new UserTemplateVo();
//遍历每一条数据封装到XSSFRow
XSSFRow row = sheetAt.getRow(i);
vo.setUserCode(row.getCell(0).toString());
vo.setUserName(row.getCell(1).toString());
vo.setEmail(row.getCell(2).toString());
vo.setEntryTime(row.getCell(3).toString());
if (StringUtil.isNullStr(row.getCell(4))) {
vo.setLeaveTime(null);
} else {
vo.setLeaveTime(row.getCell(4).toString());
}
vo.setEntranceStatus(row.getCell(5).toString());
vo.setCompany(row.getCell(6).toString());
vo.setDepartmentName(row.getCell(7).toString());
vo.setStation(row.getCell(8).toString());
vo.setAssess(row.getCell(9).toString());
vo.setLeader(row.getCell(10).toString());
//把赋值的对象放入集合
arrayList.add(vo);
}
return ResultBean.ok(arrayList);
}
/**
* 考勤信息导入
*
* @param xssfWorkbook
* @return
*/
private static ResultBean startClockImport(XSSFWorkbook xssfWorkbook) {
XSSFSheet sheetAt = xssfWorkbook.getSheetAt(0);
int rows = sheetAt.getLastRowNum();
List<String[]> dataList = new ArrayList<>();
Map<String, List<String>> dateMap = new HashMap<>();
int rowNum = 0;
try {
for (int j = 0; j < rows; j++) {
Row row = sheetAt.getRow(j);
if(row == null || row.getRowNum() == 0){
continue;
}
//创建一个跟导入模板列数相同的数组
//日期 用户工号 用户姓名 所属部门 签到时间 签退时间 加班时间 出勤类型
String[] data = new String[8];
for (int i = 0; i < data.length; i++) {
data[i] = row.getCell(i).toString();
if (i == 0) {
//校验日期格式
try {
TimeUtil.stringToLocalDate(data[i], TimeUtil.YEAR_MONTH_DAY);
//将数据放入map,用于校验
if (!dateMap.containsKey(data[i])) {
dateMap.put(data[i], new ArrayList<String>());
}
} catch (Exception e) {
return ResultBean.error(CodeEnum.IMPORT_ERROR, String.format(ExcelErrorConstant.DATE_ERROR,
rowNum + 1, i + 1, data[i], TimeUtil.YEAR_MONTH_DAY));
}
}
//校验同一时间是否有多次出勤记录
if (i == 1) {
List<String> userCodeList = dateMap.get(data[0]);
if (userCodeList.contains(data[i])) {
return ResultBean.error(CodeEnum.IMPORT_ERROR, String.format(ExcelErrorConstant.CLOCK_TWO, rowNum + 1, i + 1, data[i]));
} else {
userCodeList.add(data[i]);
dateMap.put(data[0], userCodeList);
}
}
//校验签到时间和签退时间和加班时间格式
if (i == 4 || i == 5 || i == 6) {
try {
//对转换日期错误的列做失败处理
TimeUtil.stringToLocalTime(data[i], TimeUtil.HOUR_MINUTE);
} catch (Exception e) {
return ResultBean.error(CodeEnum.IMPORT_ERROR, String.format(ExcelErrorConstant.DATE_ERROR,
rowNum + 1, i + 1, data[i], TimeUtil.HOUR_MINUTE));
}
}
}
rowNum++;
dataList.add(data);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
return ResultBean.error(CodeEnum.IMPORT_ERROR,String.format(ExcelErrorConstant.DATE_ERROR,
rowNum + 1, e.getMessage()));
}
return ResultBean.ok(dataList);
}
/**
* 请假信息导入
*
* @param xssfWorkbook
* @return
*/
private static ResultBean startAbsenceImport(XSSFWorkbook xssfWorkbook) {
XSSFSheet sheetAt = xssfWorkbook.getSheetAt(0);
int rows = sheetAt.getLastRowNum();
List<String[]> dataList = new ArrayList<>();
Map<String, List<String[]>> absenceMap = new HashMap<>();
int rowNum = 0;
try {
for (int j = 0; j < rows; j++) {
Row row = sheetAt.getRow(j);
if(row == null || row.getRowNum() == 0){
continue;
}
//创建一个跟导入模板列数相同的数组
//用户工号 用户姓名 所属部门 请假类型 请假工时(H) 请假开始时间 请假结束时间
String[] data = new String[7];
for (int i = 0; i < data.length; i++) {
data[i] = row.getCell(i).toString();
if (i == 0) {
//将工号放入map用于校验请假时间
if (!absenceMap.containsKey(data[i])) {
absenceMap.put(data[i], new ArrayList<String[]>());
}
}
//校验请假工时是否整数
if (i == 4) {
try {
Double.parseDouble(data[i]);
} catch (Exception e) {
return ResultBean.error(CodeEnum.IMPORT_ERROR, String.format(ExcelErrorConstant.NOT_DOUBLE, rowNum + 1, i + 1, data[i]));
}
}
//校验请假开始时间和结束时间是否符合日期格式
if (i == 5 || i == 6) {
try {
TimeUtil.stringToLocalDateTime(data[i], TimeUtil.EXCEL_DATE_FORMAT);
} catch (Exception e) {
return ResultBean.error(CodeEnum.IMPORT_ERROR, String.format(ExcelErrorConstant.DATE_ERROR,
rowNum + 1, i + 1, data[i], TimeUtil.EXCEL_DATE_FORMAT));
}
}
}
//进行请假时间是否冲突的校验
List<String[]> list = absenceMap.get(data[0]);
if (CollectionUtils.isEmpty(list)) {
String[] absence = new String[]{data[5], data[6]};
List<String[]> absenceList = new ArrayList<>();
absenceList.add(absence);
absenceMap.put(data[0], absenceList);
} else {
Long newStart = TimeUtil.getMillisecond(data[5], TimeUtil.EXCEL_DATE_FORMAT);
Long newEnd = TimeUtil.getMillisecond(data[6], TimeUtil.EXCEL_DATE_FORMAT);
if (!CollectionUtils.isEmpty(list)) {
for (String[] absence : list) {
boolean flag = false;
Long oldStart = TimeUtil.getMillisecond(absence[0], TimeUtil.EXCEL_DATE_FORMAT);
Long oldEnd = TimeUtil.getMillisecond(absence[1], TimeUtil.EXCEL_DATE_FORMAT);
if (newStart < oldStart && newEnd < oldStart) {
flag = true;
} else if (newStart > oldEnd && newEnd > oldEnd) {
flag = true;
}
if (!flag) {
return ResultBean.error(CodeEnum.IMPORT_ERROR, ExcelErrorConstant.ABSENCE_REPETITION + (rowNum + 1));
}
}
}
String[] absence = new String[]{data[5], data[6]};
list.add(absence);
absenceMap.put(data[0], list);
}
rowNum++;
dataList.add(data);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
return ResultBean.error(CodeEnum.IMPORT_ERROR,String.format(ExcelErrorConstant.DATE_ERROR,
rowNum + 1, e.getMessage()));
}
return ResultBean.ok(dataList);
}
/**
* 财务信息导入
*
* @param xssfWorkbook
* @return
*/
private static ResultBean startFinanceImport(XSSFWorkbook xssfWorkbook) {
XSSFSheet sheetAt = xssfWorkbook.getSheetAt(0);
int rows = sheetAt.getLastRowNum();
List<String[]> dataList = new ArrayList<>();
int rowNum = 0;
try {
for (int j = 0; j < rows; j++) {
Row row = sheetAt.getRow(j);
if(row == null || row.getRowNum() == 0){
continue;
}
//创建一个跟导入模板列数相同的数组
String[] data = new String[6];
for (int i = 0; i < data.length; i++) {
data[i] = row.getCell(i).toString();
//校验入职时间和离职日期
if (i == 5) {
try {
//对转换日期错误的列做失败处理
TimeUtil.stringToLocalDate(data[i], TimeUtil.DATE_TIME);
} catch (Exception e) {
return ResultBean.error(CodeEnum.IMPORT_ERROR, String.format(ExcelErrorConstant.DATE_ERROR,
rowNum + 1, i + 1, data[i], TimeUtil.DATE_TIME));
}
}
}
rowNum++;
dataList.add(data);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
return ResultBean.error(CodeEnum.IMPORT_ERROR,String.format(ExcelErrorConstant.DATE_ERROR,
rowNum + 1, e.getMessage()));
}
return ResultBean.ok(dataList);
}
}
数据写入excel模板
猜你喜欢
转载自blog.csdn.net/qq_28461661/article/details/103785466
今日推荐
周排行