easypoi先介绍导入的pom文件的依赖版本:
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.1.0</version>
</dependency>
我们使用wps导入excel的时候,是没有这个错误的。但是当使用的是office excel的时候就会导致文件的格式会发生变化,如下图:
可以看到一行的数据,占了好多行。针对这种数据,使用
ExcelImportUtil.importExcelMore(inputStream, pojoClass, params);
是导入不进去的,会报错:Cannot add merged region T485:T499 to sheet because it overlaps with an existing merged region (T482:T485)."
那么应该咋修改呢?
ExcelImportUtil.importExcel(inputStream, pojoClass, params);
使用这个方法,就可以避免。但是我们又想保留导入的正确的数据和错误的数据,但是importExcel这个方法的返回值是List<T>
public static <T> List<T> importExcel(InputStream inputstream, Class<?> pojoClass, ImportParams params) throws Exception {
return (new ExcelImportService()).importExcelByIs(inputstream, pojoClass, params, false).getList();
}
public static <T> ExcelImportResult<T> importExcelMore(InputStream inputstream, Class<?> pojoClass, ImportParams params) throws Exception {
return (new ExcelImportService()).importExcelByIs(inputstream, pojoClass, params, true);
}
那么应该咋办呢?如下代码:
public static <T> ExcelImportResult<T> importExcel(InputStream inputStream, Integer titleRows, Integer headerRows, boolean needVerfiy, Class<T> pojoClass) throws IOException {
if (inputStream == null) {
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
// params.setSaveUrl("/excel/");
params.setNeedSave(false);
params.setNeedVerify(needVerfiy);
params.setStartSheetIndex(1);
try {
// return ExcelImportUtil.importExcelMore(inputStream, pojoClass, params);
return (new ExcelImportService()).importExcelByIs(inputStream, pojoClass, params, false);
} catch (NoSuchElementException e) {
throw new IOException("excel文件不能为空");
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
needMore设置为false即可。
源码:
while(true) {
if (i >= params.getStartSheetIndex() + params.getSheetNum()) {
if (params.isNeedSave()) {
this.saveThisExcel(params, pojoClass, isXSSFWorkbook, book);
}
importResult.setList(result);
if (!needMore) {
break;
}
ByteArrayInputStream successIs = new ByteArrayInputStream(baos.toByteArray());
try {
Workbook successBook = WorkbookFactory.create(successIs);
importResult.setWorkbook(this.removeSuperfluousRows(successBook, this.failRow, params));
importResult.setFailWorkbook(this.removeSuperfluousRows(book, this.successRow, params));
importResult.setFailList(this.failCollection);
importResult.setVerfiyFail(this.verifyFail);
break;
} finally {
successIs.close();
}
}
就到这吧。
我自己的代码,结合了导入正确的数据和错误的数据,并且报出来哪一行错误。记录一下,与人方便。
//easypoi解析excel得到成功的集合和失败的集合
Map<String, String> map = new HashMap<>();
ExcelImportResult<UploadDataVo> result = ExcelUtils.importExcel(file, 0, 1, true, UploadDataVo.class);
List<UploadDataVo> uploadDataVos = result.getList();
List<UploadDataVo> failList = result.getFailList()==null?new ArrayList<UploadDataVo>():result.getFailList();
ArrayList<Integer> objects = Lists.newArrayList();
if (CollectionUtil.isNotEmpty(failList)) {
failList.forEach(uploadDataVo -> {
objects.add(uploadDataVo.getRowNum());
});
String collect = failList.stream().map(x -> x.getErrorMsg()).collect(Collectors.joining(","));
map.put("message", "提示:" + collect);
map.put("fail", "异常数据行号:" + JSONUtil.toJsonStr(objects));
}
map.put("total", "本次导入共" + (uploadDataVos.size() + failList.size()) + "条数据");
map.put("success", "导入成功" + uploadDataVos.size() + "条数据");
@Data
@EqualsAndHashCode
public class UploadDataVo implements IExcelDataModel, IExcelModel , Serializable {
private static final long serialVersionUID = 1L;
/**
* 行号
*/
private int rowNum;
/**
* 错误消息
*/
private String errorMsg;
@Excel(name="产品编码")
@NotEmpty(message = "[产品编码]不能为空")
private String productCode;
}
工具类:
public class ExcelUtils {
/**
* excel 导出
*
* @param list 数据
* @param title 标题
* @param sheetName sheet名称
* @param pojoClass pojo类型
* @param fileName 文件名称
* @param isCreateHeader 是否创建表头
* @param response
*/
public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, boolean isCreateHeader, HttpServletResponse response) throws IOException {
ExportParams exportParams = new ExportParams(title, sheetName, ExcelType.XSSF);
exportParams.setCreateHeadRows(isCreateHeader);
defaultExport(list, pojoClass, fileName, response, exportParams);
}
/**
* excel 导出
*
* @param list 数据
* @param title 标题
* @param sheetName sheet名称
* @param pojoClass pojo类型
* @param fileName 文件名称
* @param response
*/
public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, HttpServletResponse response) throws IOException {
defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName, ExcelType.XSSF));
}
/**
* excel 导出
*
* @param list 数据
* @param pojoClass pojo类型
* @param fileName 文件名称
* @param response
* @param exportParams 导出参数
*/
public static void exportExcel(List<?> list, Class<?> pojoClass, String fileName, ExportParams exportParams, HttpServletResponse response) throws IOException {
defaultExport(list, pojoClass, fileName, response, exportParams);
}
/**
* excel 导出
*
* @param list 数据
* @param fileName 文件名称
* @param response
*/
public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response) throws IOException {
defaultExport(list, fileName, response);
}
/**
* 默认的 excel 导出
*
* @param list 数据
* @param pojoClass pojo类型
* @param fileName 文件名称
* @param response
* @param exportParams 导出参数
*/
private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) throws IOException {
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
downLoadExcel(fileName, response, workbook);
}
/**
* 默认的 excel 导出
*
* @param list 数据
* @param fileName 文件名称
* @param response
*/
private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response) throws IOException {
Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
downLoadExcel(fileName, response, workbook);
}
/**
* 下载
*
* @param fileName 文件名称
* @param response
* @param workbook excel数据
*/
private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) throws IOException {
try {
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + "." + ExcelTypeEnum.XLSX.getValue(), "UTF-8"));
workbook.write(response.getOutputStream());
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
/**
* excel 导入
*
* @param filePath excel文件路径
* @param titleRows 标题行
* @param headerRows 表头行
* @param pojoClass pojo类型
* @param <T>
* @return
*/
public static <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws IOException {
if (StringUtils.isBlank(filePath)) {
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
params.setNeedSave(true);
params.setSaveUrl("/excel/");
try {
return ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
} catch (NoSuchElementException e) {
throw new IOException("模板不能为空");
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
/**
* excel 导入
*
* @param file excel文件
* @param pojoClass pojo类型
* @param <T>
* @return
*/
public static <T> ExcelImportResult<T> importExcel(MultipartFile file, Class<T> pojoClass) throws IOException {
return importExcel(file, 1, 1, pojoClass);
}
/**
* excel 导入
*
* @param file excel文件
* @param titleRows 标题行
* @param headerRows 表头行
* @param pojoClass pojo类型
* @param <T>
* @return
*/
public static <T> ExcelImportResult<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws IOException {
return importExcel(file, titleRows, headerRows, false, pojoClass);
}
/**
* excel 导入
*
* @param file 上传的文件
* @param titleRows 标题行
* @param headerRows 表头行
* @param needVerfiy 是否检验excel内容
* @param pojoClass pojo类型
* @param <T>
* @return
*/
public static <T> ExcelImportResult<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, boolean needVerfiy, Class<T> pojoClass) throws IOException {
if (file == null) {
return null;
}
try {
return importExcel(file.getInputStream(), titleRows, headerRows, needVerfiy, pojoClass);
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
/**
* excel 导入
*
* @param inputStream 文件输入流
* @param titleRows 标题行
* @param headerRows 表头行
* @param needVerfiy 是否检验excel内容
* @param pojoClass pojo类型
* @param <T>
* @return
*/
public static <T> ExcelImportResult<T> importExcel(InputStream inputStream, Integer titleRows, Integer headerRows, boolean needVerfiy, Class<T> pojoClass) throws IOException {
if (inputStream == null) {
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
// params.setSaveUrl("/excel/");
params.setNeedSave(false);
params.setNeedVerify(needVerfiy);
params.setStartSheetIndex(1);
try {
// return ExcelImportUtil.importExcelMore(inputStream, pojoClass, params);
return (new ExcelImportService()).importExcelByIs(inputStream, pojoClass, params, false);
} catch (NoSuchElementException e) {
throw new IOException("excel文件不能为空");
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
/**
* Excel 类型枚举
*/
enum ExcelTypeEnum {
XLS("xls"), XLSX("xlsx");
private String value;
ExcelTypeEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}