springboot后台上传与解析excel(同步解析与异步解析)

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

你可能感兴趣的:(spring,boot,java,excel,spring,boot)