1. 导入依赖
xml
复制代码
<dependency>
<groupId>com.alibaba.easyexcel</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
2. 定义实体类
java
复制代码
@Data
@ColumnWidth(25)
@HeadRowHeight(20)
@ContentRowHeight(18)
public class ImportConfigDTO {
@ExcelProperty("类型")
@ColumnWidth(15)
private String type;
@ExcelProperty("故障名")
@ColumnWidth(15)
private String name;
@ExcelProperty("故障码")
@ColumnWidth(15)
private String faultCode;
@ExcelProperty("描述")
@ColumnWidth(15)
private String description;
}
3. Controller类
java
复制代码
@Slf4j
@RestController
public class ExportConfigController {
@Autowired
private ImportConfigService importConfigService;
@PostMapping("/api/v1/importConfigTemplate")
public ResponseEntity<String> importConfigTemplate(MultipartFile file) {
importDtcConfigService.importDtoConfigTemplate(file);
return ResponseEntity.ok("success");
}
@PostMapping("/api/v1/import-config")
public ResponseEntity<String> importConfig(MultipartFile file) {
String filename = file.getOriginalFilename();
if (StringUtil.isBlank(filename)) {
throw new RuntimeException("请上传文件!");
}
if ((!StringUtils.endsWithIgnoreCase(filename, ".xls") && !StringUtils.endsWithIgnoreCase(filename, ".xlsx"))) {
throw new RuntimeException("请上传正确的excel文件!");
}
InputStream inputStream;
try {
ConfigImportListener importListener = new ConfigImportListener(importConfigService);
inputStream = new BufferedInputStream(file.getInputStream());
ExcelReaderBuilder builder = EasyExcel.read(inputStream, ImportConfigDTO.class, importListener);
builder.doReadAll();
} catch (IOException e) {
throw new RuntimeException("excel文件上传出现错误" + e.getMessage());
}
return ResponseEntity.ok("操作成功");
}
@SneakyThrows
@GetMapping("/api/v1/export-config")
public void exportConfig(HttpServletResponse response) {
List<ImportConfigDTO> list = importConfigService.findAll();
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
String fileName = URLEncoder.encode("配置数据导出", StandardCharsets.UTF_8);
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), ImportConfigDTO.class).sheet("配置数据表").doWrite(list);
}
@SneakyThrows
@GetMapping("/api/v1/export-template")
public void exportTemplate(HttpServletResponse response) {
List<ImportConfigDTO> list = new ArrayList<>();
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
String fileName = URLEncoder.encode("配置数据模板", StandardCharsets.UTF_8);
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), ImportConfigDTO.class).sheet("配置数据表").doWrite(list);
}
}
4. 两种监听类定义方式
java
复制代码
@Data
@RequiredArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class ConfigImportListener extends AnalysisEventListener<ImportConfigDTO> {
/**
* 默认每隔3000条存储数据库
*/
private int batchCount = 3000;
/**
* 缓存的数据列表
*/
private List<ImportConfigDTO> list = new ArrayList<>();
private final ImportConfigService importConfigService;
@Override
public void invoke(ImportConfigDTO data, AnalysisContext context) {
list.add(data);
// 达到BATCH_COUNT,则调用importer方法入库,防止数据几万条数据在内存,容易OOM
if (list.size() >= batchCount) {
// 调用importer方法
importConfigService.uploadExcelDtoConfig(list);
// 存储完成清理list
list.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
// 调用importer方法
importConfigService.uploadExcelDtoConfig(list);
// 存储完成清理list
list.clear();
}
}
java
复制代码
@Data
@EqualsAndHashCode(callSuper = true)
public class ConfigListener extends AnalysisEventListener<ImportConfigDTO> {
List<ImportConfigDTO> list = Lists.newLinkedList();
List<ExcelDataConvertException> listException = new ArrayList<>();
Map<Integer, String> excelHeadMap = new HashMap<>(10);
@Override
public void invoke(ImportConfigDTO data, AnalysisContext analysisContext) {
list.add(data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
excelHeadMap = headMap;
}
@Override
public void onException(Exception exception, AnalysisContext context) {
}
}
5. Excel工具类
java
复制代码
@Slf4j
public class ExcelUtils {
public static final long MAX_SIZE = 10 * 1024 * 1024;
/**
* 用于读取excel
* @param file 文件参数
* @param importClass 导入对象class
* @param analysisEventListener 分析事件监听器
*/
public static void readExcel(MultipartFile file, Class<?> importClass, AnalysisEventListener<?> analysisEventListener) {
// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
try(InputStream inputStream = file.getInputStream()) {
if (file.getSize() > MAX_SIZE) {
throw new RuntimeException("The maximum file size allowed for upload is 10MB 上传文件最大允许上传10MB");
}
String fileName = file.getOriginalFilename();
if (fileName == null || !(fileName.endsWith(".xls") || fileName.endsWith(".xlsx"))) {
throw new RuntimeException("The uploaded file format is incorrect, it must be in. xls or. xlsx format 上传文件格式不正确,必须是.xls或.xlsx格式");
}
EasyExcel.read(inputStream, importClass, analysisEventListener).sheet().doRead();
} catch (IOException e) {
throw new RuntimeException("excel文件上传出现错误" + e.getMessage());
}
}
}
6. Service类
java
复制代码
@Slf4j
@Service
public class ImportConfigService {
@Autowired
private ConfigMapper configMapper;
public void importDtoConfigTemplate(MultipartFile multipartFile) {
ConfigListener configListener = new ConfigListener();
//读取excel
ExcelUtils.readExcel(multipartFile, ImportConfigDTO.class, configListener);
List<ImportConfigDTO> configImportList = configListener.getList();
if (CollectionUtil.isEmpty(configImportList)) {
throw new RuntimeException("Upload file is empty 上传文件为空");
}
List<ExcelDataConvertException> listException = configListener.getListException();
Set<String> infoSet = listException.stream()
.map(e -> "第" + (e.getRowIndex() + 1) + "行,第" + (e.getColumnIndex() + 1) + "列")
.collect(Collectors.toSet());
if (CollectionUtil.isEmpty(infoSet)) {
uploadExcelDtoConfig(configImportList);
} else {
throw new RuntimeException(String.join(";", infoSet));
}
}
public void uploadExcelDtoConfig(List<ImportConfigDTO> importConfigDTOList) {
List<ConfigPO> configPOList = new ArrayList<>();
for (ImportConfigDTO importConfigDTO : importConfigDTOList) {
ConfigPO configPO = new ConfigPO();
configPO.setId(IdWorker.nextId());
configPO.setType(importConfigDTO.getType());
configPO.setName(importConfigDTO.getName());
configPO.setFaultCode(importConfigDTO.getFaultCode());
configPO.setDescription(importConfigDTO.getDescription());
configPO.setCreatedAt(LocalDateTime.now());
configPO.setCreatedBy("system");
configPO.setUpdatedAt(LocalDateTime.now());
configPO.setUpdatedBy("system");
configPOList.add(configPO);
}
if (CollectionUtil.isNotEmpty(configPOList)) {
configMapper.batchInsert(configPOList);
}
}
public List<ImportConfigDTO> findAll() {
return configMapper.findAll();
}
}