美文网首页
spring boot整合POI实现excel上传、解析并存贮

spring boot整合POI实现excel上传、解析并存贮

作者: 萍水相逢心愿一生 | 来源:发表于2019-05-09 15:19 被阅读0次

    spring boot整合POI实现excel上传、解析并存贮

    1、项目目录结构如下

    2019-05-09_140126_stitch.jpg

    2、spring boot pom.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.4.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.excel.poi</groupId>
        <artifactId>demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>demo</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <!-- Spring boot Web -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!-- spring boot 测试-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <!-- 数据库连接 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </dependency>
            <!-- mybaties 映射 -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.0.1</version>
            </dependency>
            <!-- Mysql连接驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <!--解析Excel-->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>3.14</version>
            </dependency>
            <!--导入excel-->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>3.14</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml-schemas</artifactId>
                <version>3.14</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
    

    3、spring boot 上传文件的配置项

    package com.excel.poi.demo.config;
    
    
    import org.springframework.boot.web.servlet.MultipartConfigFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    
    import javax.servlet.MultipartConfigElement;
    
    /**
     * @author hushixian
     * @date 2019-05-09 9:54
     */
    @Configuration
    public class UploadFileConfig extends WebMvcConfigurerAdapter {
    
        @Bean
        public MultipartConfigElement multipartConfigElement(){
            MultipartConfigFactory factory = new MultipartConfigFactory();
            // 设置文件大小限制 ,超出设置页面会抛出异常信息,
            // 这样在文件上传的地方就需要进行异常信息的处理了;
            factory.setMaxFileSize("128MB"); // KB,MB
            /// 设置总上传数据总大小
            factory.setMaxRequestSize("256MB");
            //设置文件路径
            //factory.setLocation("");
            return factory.createMultipartConfig();
        }
    }
    
    

    4、我们要建立一个实体类,用于接收从excel中解析出来列的数据(根据自己实际的业务功能来创建这个实体类,可自行修改)

    package com.excel.poi.demo.entity;
    
    import java.io.Serializable;
    
    /**
     * @author hushixian
     * @date 2019-05-09 10:01
     */
    public class ReqImportClient implements Serializable {
    
        private String id;
    
        private String userName;
    
        private String loginName;
    
        private String passWord;
    
        public ReqImportClient() {
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getLoginName() {
            return loginName;
        }
    
        public void setLoginName(String loginName) {
            this.loginName = loginName;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getPassWord() {
            return passWord;
        }
    
        public void setPassWord(String passWord) {
            this.passWord = passWord;
        }
    
        @Override
        public String toString() {
            return "id='" + id + '\'' +
                    ", loginName='" + loginName + '\'' +
                    ", userName='" + userName + '\'' +
                    ", passWord='" + passWord;
        }
    }
    
    

    5、三个工具类,用来辅助我们的返回值和自定义异常信息

    • 1、ApiResponse类,用来封装返回值
    package com.excel.poi.demo.response;
    
    
    /**
     * Created by guocai.zhang on 16/5/28.
     */
    public class ApiResponse {
    
        public static final ApiResponse SUC = new ApiResponse(ReturnCode.CODE_SUCCESS, "Success", null);
        public static final ApiResponse FAIL = new ApiResponse();
    
        private int status;
        private String info;
        private Object resultObject;
    
        public ApiResponse() {
            this.status = ReturnCode.CODE_FAIL;
        }
    
        public ApiResponse(int status, String info, Object resultObject) {
            this.status = status;
            this.info = info;
            this.resultObject = resultObject;
        }
    
    
        public static ApiResponse immediateOf(int status) {
            return new ApiResponse(status, "", null);
        }
    
        public static ApiResponse immediateOf(int status, String info) {
            return new ApiResponse(status, info, null);
        }
    
        public static ApiResponse failOf(Integer status, String info) {
            if (status == null) {
                status = ReturnCode.CODE_FAIL;
            }
            return new ApiResponse(status, info, null);
        }
    
        public static ApiResponse immediateOf(int status, String info, Object data) {
            return new ApiResponse(status, info, data);
        }
    
        public static ApiResponse successOf(Object data) {
            return immediateOf(200, "success", data);
        }
    
        public Object getResultObject() {
            return resultObject;
        }
    
        public void setResultObject(Object resultObject) {
            this.resultObject = resultObject;
        }
    
        public String getInfo() {
            return info;
        }
    
        public void setInfo(String info) {
            this.info = info;
        }
    
        public int getStatus() {
            return status;
        }
    
        public void setStatus(int status) {
            this.status = status;
        }
    
        public boolean hasError() {
            return getStatus() != ReturnCode.CODE_SUCCESS;
        }
    
    }
    
    
    • 2、BusinessException自定义异常信息
    package com.excel.poi.demo.response;
    
    /**
     * Created by guocai.zhang on 16/5/29.
     */
    public class BusinessException extends Exception {
    
        private int errCode;
        private String errMsg;
    
        public BusinessException() {
        }
    
        public BusinessException(int errCode, String errMsg) {
            super(errMsg);
            this.errCode = errCode;
            this.errMsg = errMsg;
        }
    
        public int getErrCode() {
            return errCode;
        }
    
        public String getErrMsg() {
            return errMsg;
        }
    }
    
    
    • 3、ReturnCode返回值编码类型
    package com.excel.poi.demo.response;
    
    public class ReturnCode {
        /**
         * 失败
         */
        public final static int CODE_FAIL = -1;
        /**
         * 成功
         */
        public final static int CODE_SUCCESS = 0;
    }
    
    

    6、mapper

    package com.excel.poi.demo.mapper;
    
    import com.excel.poi.demo.entity.ReqImportClient;
    
    /**
     * @author hushixian
     * @date 2019-05-09 10:23
     */
    public interface ReqImportClientMapper {
    
        /**
         * 添加方法
         * @param reqImportClient 实体类
         * @return int 返回值
         */
        int addReq(ReqImportClient reqImportClient);
    
    }
    
    

    7 、mapper.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.excel.poi.demo.mapper.ReqImportClientMapper">
        <resultMap id="BaseResultMap" type="com.excel.poi.demo.entity.ReqImportClient">
            <id column="Id" property="id" jdbcType="VARCHAR"></id>
            <result column="User_Name" property="userName" jdbcType="VARCHAR"></result>
            <result column="Login_Name" property="loginName" jdbcType="VARCHAR"></result>
            <result column="Pass_Word" property="passWord" jdbcType="VARCHAR"></result>
        </resultMap>
        <insert id="addReq" parameterType="com.excel.poi.demo.entity.ReqImportClient">
            insert into  ReqImportClient (Id,User_Name,Login_Name,Pass_Word)
            values ( #{id,jdbcType=VARCHAR},#{userName,jdbcType=VARCHAR},
            #{loginName,jdbcType=VARCHAR},#{passWord,jdbcType=VARCHAR}
            )
        </insert>
    </mapper>
    

    8、service

    package com.excel.poi.demo.service;
    
    import com.excel.poi.demo.entity.ReqImportClient;
    import com.excel.poi.demo.response.BusinessException;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.util.List;
    
    /**
     * @author hushixian
     * @date 2019-05-09 10:05
     */
    public interface ResolveExcelService {
    
        public List<ReqImportClient> resolveExcel(MultipartFile file) throws BusinessException;
    }
    
    

    9、serviceImpl

    package com.excel.poi.demo.service.impl;
    
    import com.excel.poi.demo.entity.ReqImportClient;
    import com.excel.poi.demo.mapper.ReqImportClientMapper;
    import com.excel.poi.demo.response.BusinessException;
    import com.excel.poi.demo.response.ReturnCode;
    import com.excel.poi.demo.service.ResolveExcelService;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    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.apache.poi.xssf.usermodel.XSSFWorkbook;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.regex.Pattern;
    
    /**
     * @author hushixian
     * @date 2019-05-09 10:07
     */
    @Service("resolveExcelServiceImpl")
    public class ResolveExcelServiceImpl implements ResolveExcelService {
    
        /**
         * 打印日志
         */
       private static final Logger logger = LoggerFactory.getLogger(ResolveExcelServiceImpl.class);
    
        /**
         * 上传文件后缀的地址
         */
       private static final String SUFFIX_2003 = ".xls";
       private static final String SUFFIX_2007 = ".xlsx";
        /**
         * 电话的正则
         */
        public static final String PHONE_NUMBER_REG = "^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[01356789]|18[0-9]|19[89])\\d{8}$";
    
        /**
         * 密码长度
         */
        public static final int passWardLength = 6;
    
        @Autowired
        private ReqImportClientMapper mapper;
    
        @Override
        public List<ReqImportClient> resolveExcel(MultipartFile file) throws BusinessException {
    
            List<ReqImportClient> list = new ArrayList<>();
            if(file==null){
                throw  new BusinessException(ReturnCode.CODE_FAIL,"对象不能为空");
            }
            // 获取文件的名字
            String originalFilename = file.getOriginalFilename();
            Workbook workbook = null;
            try {
                if (originalFilename.endsWith(SUFFIX_2003)) {
                    workbook = new HSSFWorkbook(file.getInputStream());
                } else if (originalFilename.endsWith(SUFFIX_2007)) {
                    workbook = new XSSFWorkbook(file.getInputStream());
                }
            } catch (Exception e) {
                logger.info(originalFilename);
                e.printStackTrace();
                throw new BusinessException(ReturnCode.CODE_FAIL, "格式错误");
            }
            if(workbook==null){
                logger.info(originalFilename);
                throw new BusinessException(ReturnCode.CODE_FAIL, "格式错误");
            }else{
                //获取所有的工作表的的数量
                int numOfSheet = workbook.getNumberOfSheets();
                //遍历这个这些表
                for (int i = 0; i < numOfSheet ; i++) {
                    //获取一个sheet也就是一个工作簿
                    Sheet sheet = workbook.getSheetAt(i);
                    int lastRowNum = sheet.getLastRowNum();
                    // 从第一行开始 第一行一般是标题
                    for (int j = 1; j <= lastRowNum; j++) {
                        Row row = sheet.getRow(j);
                        ReqImportClient reqImportClient = new ReqImportClient();
                        // 获取第一行id的值
                        if(row.getCell(0) !=null){
                            row.getCell(0).setCellType(Cell.CELL_TYPE_STRING);
                            String id = row.getCell(0).getStringCellValue();
                            reqImportClient.setId(id);
                        }
                        // 姓名
                        if(row.getCell(1) !=null){
                            row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
                            String userName = row.getCell(1).getStringCellValue();
                            reqImportClient.setUserName(userName);
                        }
                        // 手机号
                        if (row.getCell(2) !=null){
                            row.getCell(2).setCellType(Cell.CELL_TYPE_STRING);
                            String loginName = row.getCell(2).getStringCellValue();
                            // todo 正则对比
                            boolean matche = Pattern.matches(PHONE_NUMBER_REG,loginName);
                            if(!matche){
                                throw new BusinessException(ReturnCode.CODE_FAIL, "电话格式错误");
                            }
                            reqImportClient.setLoginName(loginName);
                        }
                        // 密码
                        if(row.getCell(3) !=null){
                            row.getCell(3).setCellType(Cell.CELL_TYPE_STRING);
                            String passWord = row.getCell(3).getStringCellValue();
                            if (passWord.replace("", "").length() < passWardLength) {
                                //校验密码长度
                                throw new BusinessException(ReturnCode.CODE_FAIL, "密码的格式有误");
                            }
                            reqImportClient.setPassWord(passWord);
                        }
                        // 添加方法
                        mapper.addReq(reqImportClient);
                        list.add(reqImportClient);
                    }
                }
            }
            return list;
        }
    }
    
    

    10、controller

    package com.excel.poi.demo.controller;
    
    import com.excel.poi.demo.response.ApiResponse;
    import com.excel.poi.demo.response.BusinessException;
    import com.excel.poi.demo.service.ResolveExcelService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    /**
     * @author hushixian
     * @date 2019-05-09 11:17
     */
    @RestController
    @RequestMapping("/resolve")
    public class ResolveExcelController {
    
        @Autowired
        private ResolveExcelService resolveExcelService;
    
        @RequestMapping(value = "/upload",method = RequestMethod.POST)
        public ApiResponse uploadExcel(@RequestParam("file") MultipartFile file){
            Object result;
            try {
                result = resolveExcelService.resolveExcel(file);
            }catch (BusinessException e){
                e.printStackTrace();
                return ApiResponse.failOf(-1, e.getErrMsg());
            }
            return ApiResponse.successOf(result);
        }
    
    }
    
    

    11、 yml文件的配置

    server:
      port: 9008
    spring:
      datasource:
        url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
        username: root
        password: root
        driver-class-name: com.mysql.cj.jdbc.Driver
        type: com.mysql.cj.jdbc.MysqlConnectionPoolDataSource
    
    mybatis:
        mapper-locations: classpath:mappers/*.xml
        # 虽然可以配置这项来进行pojo包扫描,但其实我更倾向于在mapper.xml写全类名
    #    type-aliases-package: com.spring.shiro.demo.entity
    
    

    12、spring boot 启动类

    package com.excel.poi.demo;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    @MapperScan("com.excel.poi.demo.mapper")
    public class DemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    
    }
    
    

    简单的html页面

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>文件上传示例</title>
    </head>
    <body>
        <h2>文件上传示例</h2>
        <hr/>
        <form method="post" enctype="multipart/form-data" action="/resolve/upload">
            <p>
                文件:<input type="file" name="file" />
            </p>
            <p>
                <input type="submit" value="上传" />
            </p>
        </form>
    </body>
    </html>
    
    希望对大家有所帮助,谢谢大家的观看

    相关文章

      网友评论

          本文标题:spring boot整合POI实现excel上传、解析并存贮

          本文链接:https://www.haomeiwen.com/subject/lndwoqtx.html