扫码关注官方订阅号
正文
0
碧海醫心
发布时间:2025-07-21 21:02:01
378人浏览过
来源于php中文网
原创
当使用 apache poi 等库读取 excel 文件,并将每一行数据转换为一个 map 对象时,通常会遇到一个问题:java 的 hashmap 默认不保证元素的插入顺序。这意味着,即使 excel 表格中的列是按特定顺序(例如,“列1”、“列2”)排列的,当这些列名及其对应的值被放入 hashmap 后,从 hashmap 中取出时的顺序可能与原始顺序不符。
例如,原始 Excel 数据如下:
column1 column2 value1 value2 value3 value4
如果使用 HashMap 存储,结果可能变为:
0 = "column2" -> value2 "column1" -> value1 1 = "column2" -> value4 "column1" -> value3
这种无序性在需要严格保持列顺序的场景(如重新写入 Excel、数据比对或特定业务逻辑处理)下,会带来极大的不便甚至错误。
为了解决 HashMap 的无序问题,Java 提供了 LinkedHashMap。LinkedHashMap 是 HashMap 的子类,它通过维护一个双向链表来记录元素的插入顺序。这意味着,当您向 LinkedHashMap 中添加键值对时,它们会按照添加的顺序被保留。当您遍历 LinkedHashMap 时,元素将按照它们被插入的顺序返回。
立即学习“Java免费学习笔记(深入)”;
根据文本生成多种逼真的语音
对于需要对键进行自然排序或自定义排序的场景,TreeMap 也是一个选择。TreeMap 会根据键的自然顺序或提供的 Comparator 进行排序。然而,对于保持原始的、非字母顺序的列顺序,LinkedHashMap 是更直接和高效的选择。
以下是如何修改现有的 Excel 读取方法,以使用 LinkedHashMap 来保持列的原始顺序:
import org.apache.poi.ss.usermodel.*; import java.util.*; import java.util.stream.Collectors; public class ExcelReader { /** * 从给定的 Excel Sheet 中读取数据,并将其存储为 List>。 * 每个 Map 保持原始列的插入顺序。 * * @param sheet 要读取的 Excel Sheet 对象。 * @return 包含所有行数据的 List,每行数据是一个保持列顺序的 Map。 * 如果 Sheet 为空,则返回一个空列表。 */ public static List> readExcelSheetOrdered(Sheet sheet) { Iterator rows = sheet.iterator(); // 检查 Sheet 是否为空 if (!rows.hasNext()) { return Collections.emptyList(); } // 读取标题行 Row header = rows.next(); List keys = new ArrayList<>(); // 遍历标题单元格,获取列名。 // 注意:这里假设列名是连续的,遇到空列名则停止。 for (Cell cell : header) { String value = cell.getStringCellValue().trim(); // 获取并修剪列名 if (!value.isEmpty()) { keys.add(value); } else { // 如果遇到空列名,则认为后续没有有效列,停止读取标题 break; } } // 存储所有行数据的列表 List> result = new ArrayList<>(); // 遍历数据行 while (rows.hasNext()) { Row row = rows.next(); // 使用 LinkedHashMap 替代 HashMap,以保持列的插入顺序 Map rowMap = new LinkedHashMap<>(); // 遍历每一列,根据标题行的顺序填充数据 for (int i = 0; i < keys.size(); ++i) { // 获取单元格,如果单元格不存在则创建为空白单元格 Cell cell = row.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); String value; // 将单元格内容转换为字符串 value = getCellValueAsString(cell); rowMap.put(keys.get(i), value); } // 仅添加非空行(即所有值不全为空的行) // 使用 stream() 和 allMatch() 检查所有值是否都为空字符串 if (!rowMap.values().stream().allMatch(String::isEmpty)) { result.add(rowMap); } } return result; } /** * 辅助方法:将单元格内容转换为字符串。 * 处理不同类型的单元格数据。 * * @param cell 单元格对象。 * @return 单元格内容的字符串表示。 */ private static String getCellValueAsString(Cell cell) { if (cell == null) { return ""; } CellType cellType = cell.getCellType(); switch (cellType) { case STRING: return cell.getStringCellValue().trim(); case NUMERIC: // 对于日期类型,需要特殊处理 if (DateUtil.isCellDateFormatted(cell)) { return cell.getDateCellValue().toString(); // 或者使用 SimpleDateFormat 格式化 } else { // 对于数字,避免科学计数法,转换为普通字符串 DataFormatter formatter = new DataFormatter(); return formatter.formatCellValue(cell); } case BOOLEAN: return String.valueOf(cell.getBooleanCellValue()); case FORMULA: // 尝试评估公式结果 try { return String.valueOf(cell.getNumericCellValue()); // 假设公式结果是数字 } catch (IllegalStateException e) { return cell.getStringCellValue().trim(); // 否则尝试作为字符串 } case BLANK: return ""; default: return cell.toString().trim(); } } // 示例用法 (假设您有一个 Workbook 对象) public static void main(String[] args) throws Exception { // 这是一个伪代码示例,实际使用需要加载 Excel 文件 // Workbook workbook = new XSSFWorkbook(new FileInputStream("your_excel_file.xlsx")); // Sheet sheet = workbook.getSheetAt(0); // List> orderedData = readExcelSheetOrdered(sheet); // 模拟一个 Sheet 对象进行测试 // 假设 sheet 已经包含数据 // ... (省略创建模拟 Sheet 的复杂代码,实际项目中通过文件读取) // 例如: // Sheet mockSheet = new XSSFWorkbook().createSheet("Test Sheet"); // Row headerRow = mockSheet.createRow(0); // headerRow.createCell(0).setCellValue("column1"); // headerRow.createCell(1).setCellValue("column2"); // // Row dataRow1 = mockSheet.createRow(1); // dataRow1.createCell(0).setCellValue("value1"); // dataRow1.createCell(1).setCellValue("value2"); // // Row dataRow2 = mockSheet.createRow(2); // dataRow2.createCell(0).setCellValue("value3"); // dataRow2.createCell(1).setCellValue("value4"); // // List> orderedData = readExcelSheetOrdered(mockSheet); // orderedData.forEach(map -> { // map.entrySet().forEach(entry -> System.out.println(entry.getKey() + " -> " + entry.getValue())); // System.out.println("---"); // }); // workbook.close(); } }
代码改动点说明:
通过将 HashMap 替换为 LinkedHashMap,可以有效地解决在 Java 中读取 Excel 数据时列顺序混乱的问题。LinkedHashMap 保证了元素的插入顺序,使得从 Excel 读取的数据能够精确地反映源文件的列布局。这对于后续的数据处理、数据验证以及将数据回写到 Excel 等操作至关重要,确保了数据流的完整性和可预测性。结合健壮的单元格类型处理,您可以构建一个可靠且高效的 Excel 数据读取模块。
相关文章
Java常用文件上传下载类库与Apache Commons
如何在 Apache Camel 中解组后保留并访问原始输入消息
Apache Camel 中如何在反序列化后保留并访问原始输入消息
如何为 Apache ActiveMQ Artemis 指定专用 JDK
如何为 Apache ActiveMQ Artemis 配置专用 JDK
相关标签:
本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
如何在URL中动态拼接多个商品ID与数量参数
2026-01-18 15:34
如何在 Go 项目中正确构建可执行二进制文件
2026-01-18 15:42
Notepad如何设置UTF
2026-01-18 15:43
OctoberCMS 静态页面不显示在后台的解决方法
2026-01-18 15:48
vegas pro如何创建子剪辑
2026-01-18 15:53
不再挤牙膏!Intel Ultra 9 290HX Plus跑分性能曝光:x86单核之王 秒杀桌面
2026-01-18 16:00
Bandizip怎么修改解压文件存放路径
2026-01-18 16:07
使用 AmpPHP 在 Magento 中实现并行处理的正确实践
2026-01-18 16:08
哇叽壁纸如何下载到本地
如何下载安装腾讯手游助手
热门AI工具
DeepSeek
幻方量化公司旗下的开源大模型平台
AI大模型
开放平台
豆包大模型
字节跳动自主研发的一系列大型语言模型
通义千问
阿里巴巴推出的全能AI助手
腾讯元宝
腾讯混元平台推出的AI助手
文档处理
Excel 表格
文心一言
文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。
中文写作
讯飞写作
基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿
写作工具
即梦AI
一站式AI创作平台,免费AI图片和视频生成。
图片拼接
图画生成
ChatGPT
最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。
智谱清言 - 免费全能的AI助手
PDF 文档
相关专题
Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。
837
2023.06.15
java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。
741
2023.07.05
Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。
736
2023.07.31
Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。
397
2023.08.01
Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。
399
2023.08.02
java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。
446
java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。
430
Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。
16926
2023.08.03
本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。
72
2026.01.16
热门下载
相关下载
精品课程
共22课时 | 1.7万人学习
共18课时 | 3.2万人学习
共14课时 | 3.1万人学习
共6课时 | 7.9万人学习
共79课时 | 151.3万人学习
共6课时 | 53.4万人学习
共4课时 | 4.3万人学习
共13课时 | 0.9万人学习
最新文章
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部