1.Excel 导出
entity:
@Getter
@Setter
@EqualsAndHashCode
public class DemoData {
@ExcelProperty("字符串标题")
private String string;
@ExcelProperty("日期标题")
private Date date;
@ExcelProperty("数字标题")
private Double doubleData;
/**
* 忽略这个字段
*/
@ExcelIgnore
private String ignore;
}Controller:
@ApiOperation("导出")
@PostMapping("/export")
@PreAuthorize("@ss.hasPermission('demo:demo:export')")
public void export(HttpServletResponse response) {
String fileName = "文件名称" + ".xlsx";
String encodeName;
try {
encodeName = URLEncoder.encode(fileName, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new CustomException("导出失败");
}
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-disposition", "attachment;filename=" + encodeName);
response.setCharacterEncoding("utf-8");
opsContactsService.export(response);
}service:
@Override
@Transactional(rollbackFor = Exception.class)
public void export(HttpServletResponse response) {
//获取所有通讯录信息
List<OpsContacts> list = demoMapper.selectList();
if (ObjectUtils.isEmpty(list)) {
throw new RuntimeException("list 信息为空");
}
WriteCellStyle cellStyle = new WriteCellStyle();
cellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); // 设置水平居中对齐
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 设置垂直居中对齐
//头策略使用默认 设置字体大小
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontHeightInPoints((short) 12);
headWriteCellStyle.setWriteFont(headWriteFont);
HorizontalCellStyleStrategy styleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, cellStyle);
try {
EasyExcel.write(response.getOutputStream(), OpsContactsVo.class)
.registerWriteHandler(styleStrategy)
.sheet("sheet名称")
.doWrite(list);
} catch (IOException e) {
throw new RuntimeException(e);
}
}2.Excel 导入
controller:
@ApiOperation("导入excel")
@PostMapping("/import")
@PreAuthorize("@ss.hasPermission('demo:demo:import')")
public Result<Void> importExcel(MultipartFile file) {
if (file.getSize() > 30 * 1024 * 1024) {
return Result.error("文件大小不能超过30M");
}
if (!isExcelFile(file)) {
return Result.error("文件格式错误");
}
Service.importExcel(file);
return Result.ok();
}service:
@Override
@Transactional(rollbackFor = Exception.class)
public void importExcel(MultipartFile file) {
log.info("=====开始读取数据=====");
try {
EasyExcel.read(file.getInputStream(), DemoExportDto.class, new ReadListener<DemoExportDto>() {
/**
* 单次缓存的数据量
*/
public static final int BATCH_COUNT = 100;
/**
*临时存储
*/
private List<DemoExportDto> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
@Override
public void invoke(DemoExportDto data, AnalysisContext context) {
cachedDataList.add(data);
if (cachedDataList.size() >= BATCH_COUNT) {
//单次入库
try {
saveData();
} catch (ParseException e) {
throw new RuntimeException(e);
}
// 存储完成清理 list
cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
try {
saveData();
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
/**
* 加上存储数据库
*/
private void saveData() throws ParseException {
log.info("{}条数据,开始存储数据库!", cachedDataList.size());
List<Demo> demoList = new ArrayList<>();
for (DemoExportDto demoData : cachedDataList) {
log.info("读取到一条数据{}", JSON.toJSONString(demoData));
//数据处理入库
Demo demo= toDemo(demoData);
demoList.add(demo);
}
log.info("清理后数据{}", JSON.toJSONString(opsContactsList));
demoMapper.batchInsert(demoList);
}
}).sheet().doRead();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}EasyExcel.read(...):使用 EasyExcel 进行 Excel 文件的读取。file.getInputStream()获取上传的文件流,DemoExportDto.class 表示 Excel 中的每一行数据将会被转换成 DemoExportDto 类型的对象。
new ReadListener<DemoExportDto>():定义了一个读取监听器 ReadListener,用于处理读取到的数据。
BATCH_COUNT:定义了每次批处理的数量为 100。当缓存的 DemoExportDto 数据达到 100 条时,就会触发一次批量插入操作。
invoke(DemoExportDto data, AnalysisContext context):每读取一条数据(即一行 Excel 数据),就会调用这个方法。data是当前读取到的DemoExportDto类型的数据,AnalysisContext是上下文对象。将读取到的数据添加到
cachedDataList中。如果缓存的大小达到了
BATCH_COUNT(100条),就会调用saveData()方法进行数据存储。存储后,重新初始化
cachedDataList,为下一批数据做准备doAfterAllAnalysed:该方法在所有数据都读取完毕后调用。这里仍然会调用saveData()方法将剩余的数据存入数据库。
这个方法的主要目的是从上传的 Excel 文件中读取数据,并将其批量插入到数据库中。为了避免内存溢出,使用了 EasyExcel 的 ReadListener 来分批读取和处理数据。每读取 100 条数据就会批量存入数据库,直到所有数据都处理完成。