在使用easypoi的时候发现一个问题:
出现这种情况的时候,后面的数据不会读取到,(导入数据的时候)
从源码中,看到,会跳过后面的行,有兴趣的,可以分析一下,
ExcelImportServer 这个类的代码。
解决方式,除了通过自定义函数的校验外setVerifyHanlder ,还需要手动的去去获取数据进行数据的校验操作。
下面在自定义函数校验之外,我又手动的从excel 表中获得数据去进行校验操作,在进行手动操作的时候,可以通过断点的方式看看 sheetAt 获得的时候是否是该工作表的全部数据。
//获得失败的 excle 工作表,第一个工作表 Sheet sheetAt = excelImportResult.getFailWorkbook().getSheetAt(0);
获得是该页工作表的全部数据(我记得应该是获得全部数据)
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.afterturn.easypoi.excel.entity.result.ExcelVerifyHanlderResult;
import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler;
import com.gree.first.service.StudentService;
import com.gree.first.user.daomain.Student;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.thymeleaf.util.StringUtils;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
/**
* Create by yang_zzu on 2020/7/8 on 11:02
*/
public class StudentServiceImpl implements StudentService {
@Override
public List<Student> importAll(InputStream inputStream) throws Exception {
ImportParams importParams = new ImportParams();
importParams.setHeadRows(1);
importParams.setTitleRows(1);
//是否需要基础校验
importParams.setNeedVerfiy(true);
//自定义函数校验
importParams.setVerifyHanlder(new IExcelVerifyHandler<Student>() {
@Override
public ExcelVerifyHanlderResult verifyHandler(Student student) {
//保存提示信息
StringBuilder res = new StringBuilder();
try {
//做一些字段的验证判断内容
if (!"China".equals(student.getAddress())) {
res.append("输入的地址有误!!!");
}
//.......等其他的判断操作
} catch (Exception e) {
res.append(e.getMessage());
}
return new ExcelVerifyHanlderResult(StringUtils.isEmpty(String.valueOf(res)), res.toString());
}
});
ExcelImportResult<Student> excelImportResult = ExcelImportUtil.importExcelMore(inputStream, Student.class, importParams);
//异常数据
List<Student> failList = excelImportResult.getFailList();
//需要导入的数据,这些是正常的数据
List<Student> list = excelImportResult.getList();
/**
* 下面的操作是,获得,后面没有读取到的数据
*/
//获得失败的 excle 工作表,第一个工作表
Sheet sheetAt = excelImportResult.getFailWorkbook().getSheetAt(0);
//获得最后一行的行号
int lastRowNum = sheetAt.getLastRowNum();
//列
String cell0_value;
double cell1_value;
Date cell2_value;
String cell3_value;
//保存异常信息
StringBuffer stringBuffer;
//保存异常的对象信息
Student studentFail;
for (int i = 0; i < lastRowNum; i++) {
studentFail = new Student();
stringBuffer = new StringBuffer();
Student student = new Student();
Row row = sheetAt.getRow(i);
Cell cell = row.getCell(0);
Cell cell1 = row.getCell(1);
Cell cell2 = row.getCell(2);
Cell cell3 = row.getCell(3);
//根据excel 该列设置的数据类型,进行不同数据的获取
cell0_value = cell.getStringCellValue();
cell1_value = cell.getNumericCellValue();
cell2_value = cell.getDateCellValue();
cell3_value = cell.getStringCellValue();
//现在已经获得 第 i 行的,每个单元格的数据
if ("XiaoMing".equals(cell0_value)) {
stringBuffer.append("XiaoMing 已经存在!!!!");
}
studentFail.setName(cell0_value);
studentFail.setAge((int) cell1_value);
//......
//将错误信息放到对象里面
studentFail.setErrorMsg(stringBuffer.toString());
//将 有问题的数据,加入到 链表中
failList.add(studentFail);
}
if (failList.isEmpty()) {
//如果 异常数据的链表为空,则说明 excel 表格中的数据全部符合导入的需求,进行正常的保存操作就可以了
//...................
}
return excelImportResult.getFailList();
}
}
这个跳过第一个单元格为空的行的方式,不能说是该框架的bug,只是说是框架解决问题的一个比较好的方法,没有那个框架是没有一点缺陷的,他们只能是以一种较好的方式去解决遇到的大部分问题。这样才比较有通用性。
这种情况,会正常的返回第一行的数据有问题,并且后面的数据也都会读取到。