POI 的 Excel 读写操作教程

ops/2025/2/22 5:14:37/

POI 的 Excel 读写操作教程

一、POI 简介

Apache POI 是一款在 Java 开发中广受欢迎的开源库,主要用于处理各种 Microsoft Office 文件格式,Excel 文件便是其中之一。凭借其功能强大的 API,POI 不仅支持对 Excel 文件的读取、写入和修改,还为 Java 开发者在处理 Excel 相关业务时提供了极大的便利。

二、POI 的 Excel 读写操作案例

(一)引入依赖

在 Maven 项目中使用 POI 时,需要在 pom.xml 文件中添加 POI 相关的依赖。以下是配置示例:

<dependencies><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.0.0</version></dependency>
</dependencies>

添加上述依赖后,Maven 会自动下载并管理 POI 及其相关依赖项,确保项目能够顺利使用 POI 的功能。

(二)写入 Excel 文件

以下是一个基础的示例,展示如何使用 POI 将数据写入 Excel 文件:

java">import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.FileOutputStream;
import java.io.IOException;public class ExcelWriteExample {public static void main(String[] args) {// 创建一个新的 Excel 工作簿,使用 XSSFWorkbook 表示 Excel 2007 及以上版本的 .xlsx 格式Workbook workbook = new XSSFWorkbook();// 在工作簿中创建一个名为 "Sheet1" 的工作表Sheet sheet = workbook.createSheet("Sheet1");// 定义要写入的数据,采用二维数组的形式String[][] data = {{"姓名", "年龄", "性别"},{"张三", "25", "男"},{"李四", "30", "女"}};// 遍历数据数组,逐行逐列将数据写入工作表for (int i = 0; i < data.length; i++) {Row row = sheet.createRow(i);for (int j = 0; j < data[i].length; j++) {Cell cell = row.createCell(j);cell.setCellValue(data[i][j]);}}// 将数据保存到文件系统中try (FileOutputStream fos = new FileOutputStream("example.xlsx")) {workbook.write(fos);System.out.println("文件写入成功!");} catch (IOException e) {e.printStackTrace();} finally {try {workbook.close();} catch (IOException e) {e.printStackTrace();}}}
}

运行该代码后,会在项目根目录下生成一个名为 example.xlsx 的 Excel 文件,文件中包含预定义的数据。

(三)读取 Excel 文件

以下是读取上述 Excel 文件内容的代码示例:

java">import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.FileInputStream;
import java.io.IOException;public class ExcelReadExample {public static void main(String[] args) {try (FileInputStream fis = new FileInputStream("example.xlsx")) {// 通过文件输入流创建工作簿对象Workbook workbook = new XSSFWorkbook(fis);// 获取工作簿中的第一个工作表Sheet sheet = workbook.getSheetAt(0);// 遍历工作表中的每一行for (Row row : sheet) {// 遍历当前行中的每一个单元格for (Cell cell : row) {switch (cell.getCellType()) {case STRING:System.out.print(cell.getStringCellValue() + "\t");break;case NUMERIC:if (DateUtil.isCellDateFormatted(cell)) {System.out.print(cell.getDateCellValue() + "\t");} else {System.out.print(cell.getNumericCellValue() + "\t");}break;case BOOLEAN:System.out.print(cell.getBooleanCellValue() + "\t");break;default:System.out.print("\t");}}System.out.println();}workbook.close();} catch (IOException e) {e.printStackTrace();}}
}

运行该代码,控制台将输出 Excel 文件中的所有数据,按行列顺序展示。

三、内存问题及优化

(一)内存问题示例

在处理大文件时,如果将整个 Excel 文件加载到内存中,可能会导致内存溢出。例如:

java">import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.FileInputStream;
import java.io.IOException;public class MemoryProblemExample {public static void main(String[] args) {try (FileInputStream fis = new FileInputStream("large_file.xlsx")) {Workbook workbook = new XSSFWorkbook(fis);Sheet sheet = workbook.getSheetAt(0);// 大文件加载到内存可能会导致 OutOfMemoryError} catch (IOException e) {e.printStackTrace();}}
}

当文件 large_file.xlsx 很大时,调用 XSSFWorkbook(fis) 可能会消耗大量内存,导致 OutOfMemoryError

(二)优化方法
  1. 使用 SXSSFWorkbook 写入大文件SXSSFWorkbookXSSFWorkbook 的流式写入版本,它采用了逐行写入的方式,避免将所有数据一次性加载到内存中。如下示例:
java">import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;import java.io.FileOutputStream;
import java.io.IOException;public class ExcelWriteLargeFileExample {public static void main(String[] args) {Workbook workbook = new SXSSFWorkbook(100);  // 设置内存中最多保留 100 行Sheet sheet = workbook.createSheet("Sheet1");for (int i = 0; i < 10000; i++) {Row row = sheet.createRow(i);for (int j = 0; j < 3; j++) {Cell cell = row.createCell(j);cell.setCellValue("数据" + i + "-" + j);}}try (FileOutputStream fos = new FileOutputStream("large_example.xlsx")) {workbook.write(fos);System.out.println("大文件写入成功!");} catch (IOException e) {e.printStackTrace();} finally {try {workbook.close();} catch (IOException e) {e.printStackTrace();}}}
}
  1. 分批读取大文件:对于大文件的读取,可以通过分批读取的方式逐步加载数据,降低内存压力。例如,可以设置每次读取固定数量的行,处理完成后再继续读取下一批数据。开发者可以根据实际需求灵活实现。

四、常见 Excel 操作工具

除了 POI,Java 生态中还有其他一些常用的 Excel 操作库,下面简要介绍几种:

  1. Hutool:Hutool 是一个功能丰富的 Java 工具包,提供了对 POI 的封装,简化了 Excel 文件的操作。示例代码如下:
java">import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;import java.util.List;
import java.util.Map;public class HutoolExcelExample {public static void main(String[] args) {ExcelReader reader = ExcelUtil.getReader("example.xlsx");List<Map<String, Object>> rows = reader.readAll();for (Map<String, Object> row : rows) {System.out.println(row);}}
}
  1. JXL:JXL 是一个较为简单的 Excel 操作库,适用于处理 .xls 格式的文件。由于对 .xlsx 格式支持较弱,它更适用于旧版 Excel 文件。

  2. EasyExcel:EasyExcel 是阿里巴巴开源的一个高效 Excel 处理工具,特别适用于大数据量的 Excel 文件,内存消耗较低。以下是使用 EasyExcel 写入文件的示例:

java">import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;import java.util.ArrayList;
import java.util.List;public class EasyExcelExample {public static void main(String[] args) {String fileName = "easyexcel_example.xlsx";List<Data> dataList = new ArrayList<>();for (int i = 0; i < 10; i++) {Data data = new Data("姓名" + i, i, "性别" + i);dataList.add(data);}EasyExcel.write(fileName, Data.class).sheet("Sheet1").doWrite(dataList);}public static class Data {private String name;private int age;private String gender;public Data(String name, int age, String gender) {this.name = name;this.age = age;this.gender =gender;}// Getters and Setters}
}

总结

本文详细介绍了如何使用 Apache POI 进行 Excel 文件的读写操作,包括常见的使用场景和一些优化建议。对于需要处理大数据量的 Excel 文件,介绍了 SXSSFWorkbook 的使用方法,避免内存溢出问题。此外,还简要介绍了其他流行的 Excel 操作工具,如 Hutool、JXL 和 EasyExcel,它们各具特色,适合不同的需求。

通过掌握这些工具和技巧,你可以在 Java 项目中高效地处理 Excel 文件,提升开发效率和应用性能。


http://www.ppmy.cn/ops/158588.html

相关文章

【centos7】安装redis

rpm链接&#xff1a;http://rpms.famillecollet.com/enterprise/remi-release-7.rpm 下载remi源 wget http://rpms.famillecollet.com/enterprise/remi-release-7.rpm 安装remi源 rpm -ivh remi-release-7.rpm 查找remi源中redis的版本 yum --enablereporemi list redis …

MyBatis拦截器终极指南:从原理到企业级实战

在本篇文章中&#xff0c;我们将深入了解如何编写一个 MyBatis 拦截器&#xff0c;并通过一个示例来展示如何在执行数据库操作&#xff08;如插入或更新&#xff09;时&#xff0c;自动填充某些字段&#xff08;例如 createdBy 和 updatedBy&#xff09;信息。本文将详细讲解拦…

Golang的并发编程案例详解

Golang的并发编程案例详解 一、并发编程概述 并发编程是指程序中有多个独立的执行线索&#xff0c;并且这些线索在时间上是重叠的。在 Golang 中&#xff0c;并发是其核心特性之一&#xff0c;通过 goroutine 和 channel 来支持并发编程&#xff0c;使得程序可以更高效地利用计…

前端包管理器的发展以及Npm、Yarn和Pnpm对比

在现代前端开发中&#xff0c;包管理器是不可或缺的核心工具。随着 JavaScript 生态的快速发展&#xff0c;开发者经历了从 npm 一统天下到 Yarn 挑战格局&#xff0c;再到 pnpm 创新突破的技术演进。这里将对三种主流包管理器&#xff08;npm/Yarn/pnpm&#xff09;进行全方位…

微信小程序地图标记点,安卓手机一次性渲染不出来的问题

问题描述&#xff1a; 如果微信小程序端&#xff0c;渲染的标记物太多&#xff0c;安卓手机存在标记物不显示的问题&#xff0c;原因初步判断是地图还没有渲染完&#xff0c;标记物数据已经加载完了&#xff0c;导致没有在地图上显示。 解决办法&#xff1a; 使用map组件的b…

DeepSeek4j 已开源,支持思维链,自定义参数,Spring Boot Starter 轻松集成,快速入门!建议收藏

DeepSeek4j Spring Boot Starter 快速入门 简介 DeepSeek4j 是一个专为 Spring Boot 设计的 AI 能力集成启动器&#xff0c;可快速接入 DeepSeek 大模型服务。通过简洁的配置和易用的 API&#xff0c;开发者可轻松实现对话交互功能。 环境要求 JDK 8Spring Boot 2.7Maven/Gr…

LeetCode《算法通关手册》 1.2 数组排序

Python强推&#xff1a;算法通关手册&#xff08;LeetCode&#xff09; | 算法通关手册&#xff08;LeetCode&#xff09; (itcharge.cn) 目录 文章目录 1.2 数组排序1.2.1 选择排序1.2.2 冒泡排序[283. 移动零 - 力扣&#xff08;LeetCode&#xff09;](https://leetcode.cn/p…

【网络安全 | 漏洞挖掘】跨子域账户合并导致的账户劫持与删除

未经许可,不得转载。 文章目录 概述正文漏洞成因概述 在对目标系统进行安全测试时,发现其运行着两个独立的域名——一个用于司机用户,一个用于开发者/企业用户。表面上看,这两个域名各自独立管理账户,但测试表明它们在处理电子邮件变更时存在严重的逻辑漏洞。该漏洞允许攻…