zoukankan      html  css  js  c++  java
  • Apache POI 4.0.1版本读取普通Excel文件(兼容 xls 和 xlsx)(二)

    一般在公司写项目,会有这样的应用场景,即:在前台页面的文件上传入口上传本地的Excel文件到后台,后台收到Excel文件后进行解析并做对应的业务操作;

    我们现在以  Apache POI 4.0.1版本读取普通Excel文件(兼容 xls 和 xlsx)(一) https://www.cnblogs.com/weigy/p/12905857.html  做一些修改。

    代码编写前准备-》

    添加POI 4.0.1 maven依赖:

    <?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>
        <groupId>com.springbootemaildemo</groupId>
        <artifactId>springboot-email-demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
        <name>springboot-email-demo</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.6.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <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-mail</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>2.7.0</version>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>2.7.0</version>
            </dependency>
    
            <dependency>
                <groupId>org.jsoup</groupId>
                <artifactId>jsoup</artifactId>
                <version>1.11.3</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.41</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.10</version>
            </dependency>
    
            <dependency>
                <groupId>commons-beanutils</groupId>
                <artifactId>commons-beanutils</artifactId>
                <version>1.8.3</version>
            </dependency>
            <dependency>
                <groupId>javax.persistence</groupId>
                <artifactId>persistence-api</artifactId>
                <version>1.0</version>
            </dependency>
    
    <!--poi -->
         <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>4.0.1</version>
            </dependency>
          <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>4.0.1</version>
            </dependency>
    
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    example-01.xlsx 文件 ,excel数据准备:

    上代码:

    DataVo(封装数据VO类)

    复制代码
    package com.springbootemaildemo.excel.b;
    
    /**
     * 读取Excel时,封装读取的每一行的数据
     */
    public class DataVo {
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 年龄
         */
        private Integer age;
    
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
    }
    复制代码

    ExcelReader(主要读取excel文件代码类)

    修改部分加了红色字体

    package com.springbootemaildemo.excel.b;
    
    import org.apache.commons.lang3.StringUtils;
    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.web.multipart.MultipartFile;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.text.DecimalFormat;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 读取Excel内容
     */
    public class ExcelReader {
        private static final Logger logger = LoggerFactory.getLogger(ExcelReader.class);
        private static final String XLS = "xls";
        private static final String XLSX = "xlsx";
    
        /**
         * 根据文件后缀名类型获取对应的工作簿对象
         *
         * @param inputStream 读取文件的输入流
         * @param fileType    文件后缀名类型(xls或xlsx)
         * @return 包含文件数据的工作簿对象
         * @throws IOException
         */
        public static Workbook getWorkbook(InputStream inputStream, String fileType) throws IOException {
            Workbook workbook = null;
            if (fileType.equalsIgnoreCase(XLS)) {
                workbook = new HSSFWorkbook(inputStream);
            } else if (fileType.equalsIgnoreCase(XLSX)) {
                workbook = new XSSFWorkbook(inputStream);
            }
            return workbook;
        }
    
        /**
         * 读取Excel文件内容
         *
         * @param file 上传的Excel文件
         * @return 读取结果列表,读取失败时返回null
         */
        public static List<DataVo> readExcel(MultipartFile file) {
            Workbook workbook = null;
            try {
                // 获取Excel后缀名
                String fileName = file.getOriginalFilename();
                if (fileName == null || fileName.isEmpty() || fileName.lastIndexOf(".") < 0) {
                    logger.warn("解析Excel失败,因为获取到的Excel文件名非法!");
                    return null;
                }
                String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
                // 获取Excel工作簿
                workbook = getWorkbook(file.getInputStream(), fileType);
                // 读取excel中的数据
                List<DataVo> resultDataList = parseExcel(workbook);
                return resultDataList;
            } catch (Exception e) {
                logger.warn("解析Excel失败,文件名:" + file.getOriginalFilename() + " 错误信息:" + e.getMessage());
                return null;
            } finally {
                try {
                    if (null != workbook) {
                        workbook.close();
                    }
                } catch (Exception e) {
                    logger.warn("关闭数据流出错!错误信息:" + e.getMessage());
                    return null;
                }
            }
        }
    
        /**
         * 解析Excel数据
         *
         * @param workbook Excel工作簿对象
         * @return 解析结果
         */
        private static List<DataVo> parseExcel(Workbook workbook) {
            List<DataVo> resultDataList = new ArrayList<>();
            // 解析sheet
            int numberOfSheets = workbook.getNumberOfSheets();
            for (int sheetNum = 0; sheetNum < numberOfSheets; sheetNum++) {
                Sheet sheet = workbook.getSheetAt(sheetNum);
    
                // 校验sheet是否合法
                if (sheet == null) {
                    continue;
                }
                // 获取第一行数据
                int firstRowNum = sheet.getFirstRowNum();
                Row firstRow = sheet.getRow(firstRowNum);
                if (null == firstRow) {
                    logger.warn("解析Excel失败,在第一行没有读取到任何数据!");
                }
                // 解析每一行的数据,构造数据对象
                int rowStart = firstRowNum + 1;
                int rowEnd = sheet.getPhysicalNumberOfRows();
                for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) {
                    Row row = sheet.getRow(rowNum);
                    if (null == row) {
                        continue;
                    }
                    DataVo resultData = convertRowToData(row);
                    if (null == resultData) {
                        logger.warn("第 " + row.getRowNum() + "行数据不合法,已忽略!");
                        continue;
                    }
                    resultDataList.add(resultData);
                }
            }
            return resultDataList;
        }
    
        /**
         * 将单元格内容转换为字符串
         *
         * @param cell
         * @return
         */
        private static String convertCellValueToString(Cell cell) {
            if (cell == null) {
                return null;
            }
            String returnValue = null;
            switch (cell.getCellType()) {
                case NUMERIC:   //数字
                    Double doubleValue = cell.getNumericCellValue();
                    // 格式化科学计数法,取一位整数
                    DecimalFormat df = new DecimalFormat("0");
                    returnValue = df.format(doubleValue);
                    break;
                case STRING:    //字符串
                    returnValue = cell.getStringCellValue();
                    break;
                case BOOLEAN:   //布尔
                    Boolean booleanValue = cell.getBooleanCellValue();
                    returnValue = booleanValue.toString();
                    break;
                case BLANK:     // 空值
                    break;
                case FORMULA:   // 公式
                    returnValue = cell.getCellFormula();
                    break;
                case ERROR:     // 故障
                    break;
                default:
                    break;
            }
            return returnValue;
        }
    
        /**
         * 提取每一行中需要的数据,构造成为一个结果数据对象
         * <p>
         * 当该行中有单元格的数据为空或不合法时,忽略该行的数据
         *
         * @param row 行数据
         * @return 解析后的行数据对象,行数据错误时返回null
         */
        private static DataVo convertRowToData(Row row) {
            DataVo resultData = new DataVo();
            Cell cell;
            int cellNum = 0;
            // 获取姓名
            cell = row.getCell(cellNum++);
            String name = convertCellValueToString(cell);
            resultData.setName(name);
            // 获取年龄
            cell = row.getCell(cellNum++);
            String ageStr = convertCellValueToString(cell);
            if (StringUtils.isEmpty(ageStr)) {
                // 年龄为空
                resultData.setAge(null);
            } else {
                resultData.setAge(Integer.parseInt(ageStr));
            }
            return resultData;
        }
    }

    Controller类,请求接口

    package com.springbootemaildemo.excel.b;
    
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.collections4.CollectionUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.util.Date;
    import java.util.List;
    
    @Slf4j
    @RestController
    @RequestMapping("/excel/b")
    @Api("读取Excel")
    public class ExcelFileController {
        private static final Logger logger = LoggerFactory.getLogger(ExcelFileController.class);
    
        @PostMapping("/uploadExcel")
        @ApiOperation("uploadFile")
        public ResponseEntity<?> uploadFile(MultipartFile file) {
            // 检查前台数据合法性
            if (null == file || file.isEmpty()) {
                logger.warn("上传的Excel商品数据文件为空!上传时间:" + new Date());
                return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
            }
            try {
                // 解析Excel
                List<DataVo> readResult = ExcelReader.readExcel(file);
                //TODO 可以写相应的业务
                if (CollectionUtils.isNotEmpty(readResult)) {
                    readResult.stream().forEach(dataVo -> {
                        System.out.println(dataVo.getName() + "-" + dataVo.getAge());
                    });
                }
                return new ResponseEntity<>(HttpStatus.OK);
            } catch (Exception e) {
                logger.warn("上传的Excel商品数据文件为空!上传时间:" + new Date());
                return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
            }
    
        }
    }

    结果:

  • 相关阅读:
    JAVA 高级特性 JDBC
    C3P0 连接池
    JAVA WEB Servlet
    JAVAWEB JSP
    sed 命令
    shell 简单脚本编程
    从首页问答标题到问答详情页
    首页列表显示全部问答,完成问答详情页布局
    制作首页的显示列表
    发布功能完成
  • 原文地址:https://www.cnblogs.com/weigy/p/12906029.html
Copyright © 2011-2022 走看看