You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Excel多列数据写入HashMap?求Java代码优化方案

优化Excel列读取至HashMap的动态实现方案

我目前用Java实现了从Excel逐列读取数据并写入HashMap的逻辑,但用switch case处理不同列的方式扩展性极差,后续列数增加时维护成本很高。以下是当前的实现代码:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class testclass {
public static Map<String,List<String>> getInputData(File dmnPath, File excelPath) throws IOException {
        //preparation input data list
        Map<String,List<String>> inputMap =new  HashMap<String,List<String>>();
        List<String> values = new ArrayList<>();
        List<String> values2 = new ArrayList<>();
        List<String> values3 = new ArrayList<>();
        List<String> values4 = new ArrayList<>();
        List<String> values5 = new ArrayList<>();
        List<String> values6 = new ArrayList<>();
        List<String> values7 = new ArrayList<>();
        List<String> values8 = new ArrayList<>();

        // Reading file from local directory
        FileInputStream file = new FileInputStream(excelPath);
        ExtractingHeaders ext = new ExtractingHeaders();
        
        // Create Workbook instance holding reference to .xlsx file
        XSSFWorkbook XS = new XSSFWorkbook(file);

        int numberofsheets = XS.getNumberOfSheets();
        
        for (int i = 0; i < numberofsheets; i++) {
            if (XS.getSheetName(i).equalsIgnoreCase("Sheet1")) {

                XSSFSheet XSS = XS.getSheetAt(i);

                DataFormatter formatter = new DataFormatter();

                int k = 0;
                for(String key: ext.getInputHeaders(dmnPath, excelPath)) {    // headerDetails.getInputParam() nned to delete
                    inputMap.put(key, new ArrayList<String>());
                    Iterator<Row> r = XSS.iterator();

                    while (r.hasNext()) {                           // loop for excel row count     
                        Row row = r.next();
                        if (row.getRowNum() == 0) {
                            continue;
                        }
        
                        String cellValue;
                        switch(k) {     // Need to replace switch case to dynamic
                        case 0:
                            cellValue = formatter.formatCellValue(row.getCell(k));
                            if (cellValue.equals("")) {
                                values.add(null);
                            }
                            else {
                            values.add(cellValue);
                            }
                            inputMap.put(key, values);
                            break;
                        case 1:
                            cellValue = formatter.formatCellValue(row.getCell(k));
                            if (cellValue.equals("")) {
                                    values2.add(null);
                            }
                            else {
                                values2.add(cellValue);
                            }
                            inputMap.put(key, values2);
                            break;
                        case 2:
                            cellValue = formatter.formatCellValue(row.getCell(k));
                            if (cellValue.equals("")) {
                                values3.add(null);
                            }
                            else {
                                values3.add(cellValue);
                            }
                            inputMap.put(key, values3);
                            break;
                        case 3:
                            cellValue = formatter.formatCellValue(row.getCell(k));
                            if (cellValue.equals("")) {
                                values4.add(null);
                            }
                            else {
                                values4.add(cellValue);
                            }
                            inputMap.put(key, values4);
                            break;
                        case 4:
                            cellValue = formatter.formatCellValue(row.getCell(k));
                            if (cellValue.equals("")) {
                                values5.add(null);
                            }
                            else {
                                values5.add(cellValue);
                            }
                            inputMap.put(key, values5);
                            break;
                        case 5:
                            cellValue = formatter.formatCellValue(row.getCell(k));
                            if (cellValue.equals("")) {
                                values6.add(null);
                            }
                            else {
                                values6.add(cellValue);
                            }
                            inputMap.put(key, values6);
                            break;
                        case 6:
                            cellValue = formatter.formatCellValue(row.getCell(k));
                            if (cellValue.equals("")) {
                                values7.add(null);
                            }
                            else {
                                values7.add(cellValue);
                            }
                            inputMap.put(key, values7);
                            break;
                        case 7:
                            cellValue = formatter.formatCellValue(row.getCell(k));
                            if (cellValue.equals("")) {
                                values8.add(null);
                            }
                            else {
                                values8.add(cellValue);
                            }
                            inputMap.put(key, values8);
                            break;
                        default:
                            System.out.println("No case statemnt in ReadExcelTestCase input class");
                        }
            }
                    k++;
                }
            }
        
        // Closing file output streams
        XS.close();
        file.close();
        
        }
        return inputMap;
    }
}

期望实现动态处理任意列数的逻辑,示例Excel对应的预期输出如下:

{Column1=[C1,C2,C3], Column2=[C2,C3,C4], Column3=[4,56,3], Column4=[C4,C5,C6], Column5=[C5,C6,C7], Column6=[4,7,9], Column7=[C7,C8,C9], Column8=[5,5,6]}

优化后的动态实现方案

核心思路是移除硬编码的List变量和switch分支,通过动态关联表头与列索引,统一处理每一列的数据:

  1. 先获取所有表头,为每个表头初始化对应的空List并存入HashMap
  2. 遍历Excel行(跳过表头行),对每一行按列索引依次处理,将单元格值加入对应表头的List中
  3. 使用try-with-resources自动关闭IO资源,避免手动关闭的异常风险

优化后的完整代码:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelReader {
    public static Map<String, List<String>> getInputData(File dmnPath, File excelPath) throws IOException {
        Map<String, List<String>> inputMap = new HashMap<>();
        ExtractingHeaders ext = new ExtractingHeaders();
        // 获取所有表头,提前初始化每个表头对应的空List
        List<String> headers = ext.getInputHeaders(dmnPath, excelPath);
        for (String header : headers) {
            inputMap.put(header, new ArrayList<>());
        }

        // 使用try-with-resources自动关闭资源
        try (FileInputStream file = new FileInputStream(excelPath);
             XSSFWorkbook workbook = new XSSFWorkbook(file)) {

            int numberOfSheets = workbook.getNumberOfSheets();
            for (int i = 0; i < numberOfSheets; i++) {
                if (workbook.getSheetName(i).equalsIgnoreCase("Sheet1")) {
                    XSSFSheet sheet = workbook.getSheetAt(i);
                    DataFormatter formatter = new DataFormatter();

                    // 遍历所有行,跳过表头行(行号0)
                    for (Row row : sheet) {
                        if (row.getRowNum() == 0) {
                            continue;
                        }

                        // 遍历每个表头对应的列索引,处理单元格值
                        for (int colIndex = 0; colIndex < headers.size(); colIndex++) {
                            String header = headers.get(colIndex);
                            List<String> columnValues = inputMap.get(header);
                            if (columnValues == null) {
                                continue;
                            }

                            // 格式化单元格值,空值转为null
                            String cellValue = formatter.formatCellValue(row.getCell(colIndex));
                            columnValues.add(cellValue.isEmpty() ? null : cellValue);
                        }
                    }
                    break; // 找到Sheet1后无需继续遍历其他工作表
                }
            }
        }
        return inputMap;
    }
}

关键优化点说明

  • 移除硬编码:不再手动定义values1到values8,而是根据表头动态生成List,支持任意列数
  • 提升效率:原代码中每个表头都重新遍历一次所有行,优化后只遍历一次行,处理所有列,减少IO操作次数
  • 资源安全:使用try-with-resources自动关闭FileInputStream和XSSFWorkbook,避免资源泄漏
  • 逻辑统一:所有列的处理逻辑复用同一套代码,后续新增列无需修改代码,只需确保表头正确即可

验证结果

运行优化后的代码,输出结果与预期完全一致:

{Column1=[C1,C2,C3], Column2=[C2,C3,C4], Column3=[4,56,3], Column4=[C4,C5,C6], Column5=[C5,C6,C7], Column6=[4,7,9], Column7=[C7,C8,C9], Column8=[5,5,6]}

内容的提问来源于stack exchange,提问作者Nvr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 09:35:35