后端使用POI解析.xlsx文件(附源码)

Apache POI 作为老牌文件处理工具,无需多言,直接上代码。

一、引入依赖

XML 复制代码
<groupId>org.apache.poi</groupId> 
<artifactId>poi-ooxml</artifactId> 
<version>5.2.3</version>

二、工具类实现

java 复制代码
import cn.hutool.core.date.DatePattern;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
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.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;

public class ExcelUtil {
    private static final Logger logger = LoggerFactory.getLogger(ExcelUtil.class);

    private static final String EXCEL_FORMART_XLS = ".xls";
    private static final String EXCEL_FORMART_XLSX = ".xlsx";

    public static Workbook getWorkbook(InputStream fileInputStream, String fileName) {
        Workbook wb = null;
        if (ObjectUtils.isEmpty(fileInputStream)) {
            return wb;
        }
        try {
            if (!StringUtils.isEmpty(fileName) && fileName.endsWith(EXCEL_FORMART_XLS)) {
                // .xls为office2003之前(包含2003)的版本
                wb = new HSSFWorkbook(fileInputStream);
            } else if (!StringUtils.isEmpty(fileName) && fileName.endsWith(EXCEL_FORMART_XLSX)) {
                // .xlsx为office2007之后(包含2007)的版本
                wb = new XSSFWorkbook(fileInputStream);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            return wb;
        }
    }

    public static Workbook getWorkbook(File file) {
        Workbook wb = null;
        try {
            String fileName = file.getName();
            wb = getWorkbook(new FileInputStream(file), fileName);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            return wb;
        }
    }

    public static Workbook getWorkbook(MultipartFile file) {
        Workbook wb = null;
        try {
            String fileName = file.getOriginalFilename();
            wb = getWorkbook(file.getInputStream(), fileName);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            return wb;
        }
    }

    /**
     * 获取sheet页
     *
     * @param file
     * @param hasHiddern 是否包含隐藏列
     * @return
     */
    public static List<Sheet> getSheetsByFile(MultipartFile file, Boolean hasHiddern) {
        List<Sheet> sheets = new ArrayList<>();
        Workbook wb = getWorkbook(file);
        if (ObjectUtils.isEmpty(wb)) {
            return sheets;
        }
        sheets = getSheets(wb, hasHiddern);
        return sheets;
    }

    /**
     * @param workbook
     * @param hasHiddern 包含隐藏列
     * @return
     */
    public static List<Sheet> getSheets(Workbook workbook, Boolean hasHiddern) {
        List<Sheet> sheets = new ArrayList<>();
        if (ObjectUtils.isEmpty(workbook)) {
            return sheets;
        }
        int sheetNum = workbook.getNumberOfSheets();
        for (int i = 0; i < sheetNum; i++) {
            if (!hasHiddern && workbook.isSheetHidden(i)) {
                continue;
            }
            sheets.add(workbook.getSheetAt(i));
        }
        return sheets;
    }

    /**
     * 取得所有sheet
     *
     * @param workbook
     * @return
     */
    public static List<Sheet> getSheets(Workbook workbook) {
        return getSheets(workbook, false);
    }

    public static Sheet getSheet(Workbook workbook, String sheetName) {
        Sheet sheet = null;
        if (ObjectUtils.isEmpty(workbook)) {
            return sheet;
        }
        sheet = workbook.getSheet(sheetName);
        return sheet;
    }

    /**
     * 从sheet页内获取数据
     *
     * @param sheet    sheet页
     * @param startRow 开始行 index索引
     * @param endRow   结束行  index索引
     * @param startCol 开始列 index索引
     * @param endCol   结束列 index索引
     * @return
     */
    public static LinkedHashMap<Integer, List<String>> getSheetData(Sheet sheet, int startRow, int endRow, int startCol, int endCol) {
        if (ObjectUtils.isEmpty(sheet)) {
            return null;
        }
        int totalRow = sheet.getPhysicalNumberOfRows();
        if (startRow > totalRow) {
            return null;
        }
        LinkedHashMap<Integer, List<String>> map = new LinkedHashMap<Integer, List<String>>();
        endRow = (endRow > totalRow) ? totalRow : endRow;
        for (int rowNum = startRow; rowNum < endRow; rowNum++) {
            Row row = sheet.getRow(rowNum);
            List<String> stringList = getRowData(row, startCol, endCol);
            if (CollectionUtils.isEmpty(stringList) || isNullRow(stringList)) {
                continue;
            }
            map.put(rowNum + 1, stringList);
        }
        return map;
    }

    /**
     * 判断是否是空行
     *
     * @param rowDatas
     * @return
     */
    public static Boolean isNullRow(List<String> rowDatas) {
        boolean isNull = true;
        if (!CollectionUtils.isEmpty(rowDatas)) {
            String value = String.join("", rowDatas).trim();
            if (!StringUtils.isEmpty(value)) {
                isNull = false;
            }
        }
        return isNull;
    }

    public static List<String> getRowData(Row row, int startCol, int endCol) {
        List<String> list = new ArrayList<>();
        if (ObjectUtils.isEmpty(row)) {
            return list;
        }
        int totalCol = row.getPhysicalNumberOfCells();
        if (startCol > totalCol) {
            return list;
        }
        for (int num = startCol; num < endCol; num++) {
            String value = (num < totalCol) ? getStringValue(row.getCell(num)) : "";
            list.add(value);
        }
        return list;
    }

}

三、具体使用

java 复制代码
 private Object dealImportExcel(MultipartFile file) {
       // 1、获取Workbook
        Workbook wb = ExcelUtil.getWorkbook(file);
        if (ObjectUtils.isEmpty(wb)) {
            return ResultMsg.fail("解析Excel文件失败");
        }
        // 2、获取sheets
        List<Sheet> sheets = ExcelUtil.getSheets(wb, false);
        if (CollectionUtils.isEmpty(sheets)) {
            return ResultMsg.fail("导入文件中不存在sheet页");
        }
        // 保存数据的集合
        List<SmartEnergyStatisticsLs1M5Charging> list = new ArrayList<>();
        for (Sheet sheet : sheets) {
            String sheetName = sheet.getSheetName();
            int rows = sheet.getPhysicalNumberOfRows();
            if (rows <= 1) {
                logger.info("Sheet[{}]页行数不足2行,不处理该Sheet", sheetName);
                continue;
            }
            Row row = sheet.getRow(1);
            int cellCount = row.getPhysicalNumberOfCells();
            if (cellCount != 5) {
                logger.info("Sheet[{}]列数不是8列,不是标准数据,不处理该Sheet", sheetName);
                continue;
            }
            logger.info("开始处理Sheet:{}", sheetName);
            for (int i = 1; i < rows; i++) {
                row = sheet.getRow(i);
                Cell cell = row.getCell(0);
                // 获取表格中时间
                String month = handleTimeCell(cell);
                if (Objects.isNull(month)) {
                    logger.error("第{}行未提取到首列日期值", (i + 1));
                    continue;
                }

               
                BigDecimal chargeQuantity = getBigDecimalCell(row.getCell(1));

               
                Integer chargeTime = Integer.valueOf(row.getCell(2).getStringCellValue());

                
                BigDecimal dischargeQuantity = getBigDecimalCell(row.getCell(3));
                
                Integer dischargeTime = Integer.valueOf(row.getCell(4).getStringCellValue());


                SmartEnergyStatisticsLs1M5Charging smartEnergyStatisticsLs1M5Charging = SmartEnergyStatisticsLs1M5Charging.builder()
                        .month(month)
                        .chargeQuantity(chargeQuantity)
                        .chargeTime(chargeTime)
                        .dischargeQuantity(dischargeQuantity)
                        .dischargeTime(dischargeTime)
                        .build();
                list.add(smartEnergyStatisticsLs1M5Charging);

            }
        }
        return batchAdd(list);
    }
相关推荐
亓才孓1 天前
多态:编译时看左边,运行时看右边
java·开发语言
2501_941802481 天前
从缓存更新到数据一致性的互联网工程语法实践与多语言探索
java·后端·spring
拆房老料1 天前
文档预览开源选型对比:BaseMetas FileView 与 KK FileView,谁更适合你的系统?
java·开源·java-rocketmq·开源软件
Frank_refuel1 天前
C++之内存管理
java·数据结构·c++
钱多多_qdd1 天前
springboot注解(五)
java·spring boot·后端
2501_941822751 天前
面向灰度发布与风险隔离的互联网系统演进策略与多语言工程实践分享方法论记录思考汇总稿件
android·java·人工智能
@小码农1 天前
6547网:202512 GESP认证 C++编程 一级真题题库(附答案)
java·c++·算法
秋91 天前
idea中使用AI编程助手Cursor详解
java·intellij-idea·ai编程
q行1 天前
java学习日志--IO流(使用)
java·学习·io流