Java实现Excel导入(从oss中导入到数据库)
一、前言
Java实现数据的导入导出十分常见。实现的方法也是多种多样,本文记录了一个从oss导入数据的方法,记录下来给读者一些思路,也借此抛砖引玉,希望读者大大们可以在评论区留下一些好的方法。
[注]:在本文中我们只实现导入,性能优化再出一篇文章。
二、准备
1.导入maven依赖
使用easyExcel在处理较大的数据量的时候性能比较高,使用起来也很方便
<!--导入导出--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.3</version></dependency><!--OSS SDK--><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.10.2</version></dependency>
2. 创建承接模型
这里是我自己的模型,读者需要更改为自己的excel对应的模型!!
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;@NoArgsConstructor
@AllArgsConstructor
@Data
@ContentRowHeight(15)
@HeadRowHeight(15)
@ColumnWidth(25)
@HeadFontStyle(fontHeightInPoints = 10)
@ContentFontStyle(fontHeightInPoints = 10)
public class ImportProjectData {@ExcelProperty(value = "项目年份")private Integer projectYear;@ExcelProperty(value = "项目编码")private String projectCode;@ExcelProperty(value = "项目名称")private String projectName;@ExcelProperty(value = "项目简称")private String abbreviation;@ExcelProperty(value = "发行时间")private Date releaseTime;@ExcelProperty(value = "项目题材")private String theme;@ExcelProperty(value = "项目系列")private String series;@ExcelProperty(value = "项目公告内容")private String announceContent;@Overridepublic String toString() {return "ImportProjectData{" +"projectYear=" + projectYear +", projectCode='" + projectCode + '\'' +", projectName='" + projectName + '\'' +", abbreviation='" + abbreviation + '\'' +", releaseTime=" + releaseTime +", theme='" + theme + '\'' +", series='" + series + '\'' +", announceContent='" + announceContent + '\'' +'}';}
}
3.封装文件模型
为了能够区分不同类型的文件数据传输,封装了一个文件模型可作为导入的入参。Attachment对象存储url
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
@ApiModel(description = "导入")
public class ImportExcelRequest extends AbstractEnhanceRequest {private static final long serialVersionUID = -6779502052936927057L;@ApiModelProperty(value = "附件")private Attachment excelAttachment;@ApiModelProperty(value = "导入类型")private String excelImportType;@ApiModelProperty(value = "导出模版类型")private String excelExportType;}
自定义Attachment
package net.chngc.c2c.item.api.bean.common;import lombok.Data;import java.io.Serializable;@Data
public class Attachment implements Serializable {private String fileURL;private String path;//本地测试使用
}
三、实现
1.本地实现
我们先从本地模拟一下,先做一下本地的excel导入!!!! 实现中我们做了PIO和EasyExcel的比较
service层实现(该实现使用PIO)
public Boolean importProjectFromExcel(ImportExcelRequest request) {String filePath = request.getExcelAttachment().getPath();ArrayList<ImportProjectData> projects = new ArrayList<>();FileInputStream is = null;try {is = new FileInputStream(filePath);Workbook workbook = new XSSFWorkbook(is);Sheet sheet = workbook.getSheetAt(0); // 读取第一个sheetIterator<Row> rows = sheet.iterator();while (rows.hasNext()) {Row currentRow = rows.next();// 如果是表头行,跳过if (currentRow.getRowNum() == 0) {continue;}ImportProjectData project = new ImportProjectData();project.setYear((int) currentRow.getCell(0).getNumericCellValue()); // 第一列年份project.setCode(currentRow.getCell(1).getStringCellValue()); // 第二列编码project.setName(currentRow.getCell(2).getStringCellValue());project.setAbbreviation(currentRow.getCell(3).getStringCellValue());project.setReleaseTime(currentRow.getCell(4).getDateCellValue());project.setTheme(currentRow.getCell(5).getStringCellValue());project.setSeries(currentRow.getCell(6).getStringCellValue());project.setAnnounceContent(currentRow.getCell(7).getStringCellValue());projects.add(project);}System.out.println(projects);} catch (IOException e) {throw new ServiceException("Error importing projects from Excel", e);} finally {if (is != null) {try {is.close();} catch (IOException e) {log.error(e.getMessage());}}}return true;}
service层实现(该实现使用EasyExcel)
使用esayExcel会简便很多
public Response<Boolean> importProjectFromExcel(ImportExcelRequest request) {String filePath = request.getExcelAttachment().getPath();ArrayList<ImportProjectData> projects = new ArrayList<>();FileInputStream is = null;try {is = new FileInputStream(filePath);EasyExcel.read(is, ImportProjectData.class, new PageReadListener<ImportProjectData>(dataList-> {log.info("读取到数据:{}", JSON.toJSONString(dataList));projects.addAll(dataList);} )).sheet().headRowNumber(2).doRead();System.out.println(projects);} catch (IOException e) {throw new ServiceException("Error importing projects from Excel", e);} finally {if (is != null) {try {is.close();} catch (IOException e) {log.error(e.getMessage());}}}return null;}
测试输出
调用结果(先忽略数据格式问题,先拿到数据最重要嘛)

对比excel
OK!!!我们至此成功拿到了本地的数据
2.oss
多数情况下,我们的excel数据可能是存在于oss中的,当数据存在远端服务,那么我们首先要做的就是拿到我们的数据。oss不熟悉的可以先了解一下oss 对象存储(OSS)-阿里云帮助中心
思路:
现在公司要求我将上传到oss的数据导出,给了我一个存储地址。OK,拿到了地址,我们要的就是先连接到oss,找到存放的位置,然后根据存储地址获取咱们可用的URL,再利用我们的EasyExcel获取一下数据即可。
代码实现:实现很简单,利用oss的依赖包,解析一下传过来的文件path即可。最重要的是其中的数据处理。
public Response<Boolean> importProjectFromExcelFormal(ImportExcelRequest request) {String filePath = request.getExcelAttachment().getFileURL();ArrayList<ImportProjectData> projects = new ArrayList<>();InputStream is = null;try {FileObject fileObject = OssHelper.downloadFile(ossClient, filePath);is = fileObject.getInputStream();EasyExcel.read(is, ImportProjectData.class, new PageReadListener<ImportProjectData>(projects::addAll)).sheet().doRead();//处理数据 返回结果为错误未导入的集合List<ImportProjectData> importProjectData = itemProjectManager.importDataProcess(projects);} finally {if (is != null) {try {is.close();ossClient.shutdown();} catch (IOException e) {log.error(e.getMessage());}}}return null;}
