excel解析依赖(springboot依赖自己添加)
<dependency>
<groupId>com.monitorjbl</groupId>
<artifactId>xlsx-streamer</artifactId>
<version>2.0.0</version>
</dependency>
后台解析有种方式:流同步解析(数据量小,花费时间少)和文件保存应用所在服务器,异步解析(数据量大,花费时间多)
第一种方式 流式同步解析:
Controller层
import com.tianshi.framework.web.domain.AjaxResult;
import com.tianshi.project.tdhy.service.UploadFileService;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
/**
* \* Date: 2020/9/7
* \*
* \* Desc:
*/
@RestController
@RequestMapping("/upload")
public class UploadFileController {
private static Logger logger = LoggerFactory.getLogger(UploadFileController.class);
@Autowired
private UploadFileService uploadFileService;
@PostMapping("/excel")
@ApiOperation(value = "excel上传解析")
public AjaxResult uploadEXC(@RequestParam(required = true) MultipartFile file){
try {
uploadFileService.uploadEXC(file);
logger.info("excel上传与解析成功");
return AjaxResult.success("ok");
}catch (Exception e){
e.printStackTrace();
logger.error("excel上传或解析失败");
return AjaxResult.error(e.toString());
}
}
}
Service层
import com.monitorjbl.xlsx.StreamingReader;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
@Service
public class UploadFileService{
//dataSource我使用配置的mybatis的driud连接池
@Autowired
@Qualifier("dataSource")
private DataSource dataSource;
public void uploadEXC(MultipartFile file) throws Exception {
//直接获取文件输入流
InputStream inputStream = file.getInputStream();
try (
//此处是解析excel的重点 WorkBook对象就是获取到的excel解析类
Workbook workbook = StreamingReader.builder()
.rowCacheSize(100) //一次读取多少行数据
.bufferSize(1024) // 内存大小(M)
.open(inputStream);
Connection connection = dataSource.getConnection();
PreparedStatement ps = connection.prepareStatement("insert into test.test values (?,?,?,?,?,?,?,?,?)")
) {
connection.setAutoCommit(false);
//根据sheet位置获取sheet,此处获取第一个sheet页
Sheet sheet = workbook.getSheetAt(0);
//根据sheet名字获取sheet
//Sheet sheet = workbook.getSheet("sheetName")
//遍历sheet中的每一行
for (Row row : sheet) {
//遍历一行中的每一个cell;也可以指定cell位置获取 Cell cell = row.getCell(0);
for (Cell cell : row) {
//获取cell的值
String cellValue = cell.getStringCellValue();
}
}
//此处省略数据处保存逻辑......
connection.commit();
}
}
}
第二种方式 保存应用所在服务器,异步解析
Controller层除了logger信息不需要变.
Service
@Service
public class UploadFileService{
public void uploadEXC(MultipartFile file) throws Exception {
//判断文件是否为空
if (file.isEmpty()) {
throw new Exception("文件为空,请检查!");
}
//获取上传时的文件名
String originalFileName= file.getOriginalFilename().trim();
//将文件名添加时间戳,防止前台一直上传相同文件名文件而导致覆盖
String fileName = System.currentTimeMillis() + "_" + originalFileName
//此处做配置,指定一个文件夹作为上传文件保存的文件夹
String fileDirPath = propertiesConfig.getFile_download_dir();
File destDir = new File(fileDirPath);
//判断上传的文件夹是否存在不存在就创建
if (!destDir.exists()) {
destDir.mkdirs();
}
//添加文件需要保存的全路径
File destFile = new File(fileDirPath + fileName);
try {
//将文件保存到服务器
file.transferTo(destFile);
} catch (IOException e) {
logger.error("文件上传失败:", e);
throw new Exception("文件上传失败!");
}
//此处省略逻辑,将文件名字,上传时间,等信息保存到数据库,供后台异步解析任务去获取文件解析
}
}
最后可以结合quartz或者@Schedule做定时任务,比如每1分钟去扫描数据库看是否有文件需要解析,有的话就解析,完成异步解析,至于springboot整合quartz,参考我另外一篇博文
springboot整合quartz