Java中使用Excel导入导出,POI与EasyExcel的使用方法与区别

Excel版本区别

03版07版
存储数量最多只能存储65536行数据没有限制数据行数
文件后缀xlsxlsx
读写速度

POI

写入Excel

// 创建工作簿
Workbook workbook = new HSSFWorkbook();
// 创建工作表
Sheet sheet = workbook.createSheet("工作表1");
for (int i = 0; i < 9; i++) {
    // 创建行
    Row row = sheet.createRow(i);
    for (int j = i; j < 9; j++) {
        // 创建列
        Cell cell = row.createCell(j);
        cell.setCellValue((i+1)+"*"+(j+1)+"="+((i+1)*(j+1)));
    }
}
// 输出
FileOutputStream fileOutputStream = new FileOutputStream(path + "/九九乘法表.xls");
workbook.write(fileOutputStream);
fileOutputStream.close();

HSSFWorkbook为03版本excel,XSSFWorkbook为07版本excel

SXSSFWorkbook为07版加速版,可以更快的读写excel,不过会生成临时文件,需要清理临时文件

// 清理临时文件
((SXSSFWorkbook)workbook).dispose();

读取Excel

FileInputStream fileInputStream = new FileInputStream(path);
// 读取工作簿
Workbook workbook = new HSSFWorkbook(fileInputStream);
// 读取工作表
Sheet sheet = workbook.getSheet("工作表1");
for (int i = 0; i < sheet.getLastRowNum(); i++) {
    System.out.println(sheet.getLastRowNum());
    Row row = sheet.getRow(i);
    for (int j = 0; j < row.getLastCellNum();j++){
        System.out.println(row.getLastCellNum());
        Cell cell = row.getCell(j);
        String stringCellValue = cell.getStringCellValue();
        if (StringUtils.isNotBlank(stringCellValue)){
            System.out.println(stringCellValue);
        }
    }
}
fileInputStream.close();

读取的时候需要注意数据类型,否则会读取失败

EasyExcel

导入

实体类处理

在实体类增加注解@ExcelProperty(value = “XXXX”),在导入excel的时候会根据表头查找对应列

枚举值处理

枚举值转换,导入的数据是中文,数据库存储为对应数字时,可以使用自定义Converter类,例:

public class IntegerDataConverter implements Converter<Integer> {
    // 其他未用到重写方法省略
    @Override
    public Integer convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        String fieldName = excelContentProperty.getField().getName().trim();
        String stringValue = cellData.getStringValue().trim();
        // 获取枚举值对应结果
        String resStr = ConverterUtils.getDictValue(stringValue, fieldName);
        return Integer.valueOf(resStr);
    }
}

需要继承Converter类并重写convertToJavaData方法,并在@ExcelProperty注解中增加参数,例:

@ExcelProperty(value = "XXXX",converter = IntegerDataConverter.class)
自定义Listener
public class ExcelDataListener<T> extends AnalysisEventListener<T> {
    // 省略其他未用到重写方法
	/**
	 * 自定义用于暂时存储data
	 * 可以通过实例获取该值
	 */
	private List<T> datas = new ArrayList<>();

	@Override
	public void invoke(T t, AnalysisContext analysisContext) {
        // 每条数据解析都会调用这个方法
		// 数据存储到list,供批量处理,或后续自己业务逻辑处理。
		datas.add(t);
	}
    
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 全部数据解析完成会调用这个方法
        saveData();
    }
}

如果导入接口不需要返回值,可直接在Listener中调用service的保存方法

如果需要返回值,可以在Listener中增加自定义方法,返回解析完成的数据

解析数据
public <T,E extends BatchSaveService<T>> List<ImportFailVo<T>> uploadByReturn(MultipartFile file,E service, Class<T> clazz) throws IOException {
    ExcelDataListener<T> listener = new ExcelDataListener<>();
    EasyExcel.read(file.getInputStream(), clazz, listener).sheet(0).doRead();
    // excel数据解析结果
    List<T> list = listener.getDatas();
    return service.batchSaveByReturn(list);
}

导出

String filename = URLEncoder.encode("企业导出信息", "UTF-8");
response.setCharacterEncoding("utf-8");
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + filename + ".xlsx");
EasyExcel.write(response.getOutputStream(), EntExportDTO.class).sheet("企业信息")
    .doWrite(resList);

导出中用到的注解与Listener与导入一致

踩坑

EasyExcel导出文件格式问题

问题:“XXX"的文件格式和扩展名不匹配。文件可能已损坏或不安全。除非您信任其来源,否则请勿打开。是否仍要打开它?

解决:数据转换过程中因为LocalDateTime导致后台报错,导出文件出错

导出无数据

实体类未加@Data注解


👍 欢迎前往博客主页查看更多内容

👍 如果觉得不错,期待您的点赞、收藏、评论、关注

👍 ​ 如有错误欢迎指正!

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值