jxl 是一个非常经典和流行的 Java 操作 Excel 的库,它专门用于处理 .xls 格式的 Excel 文件(即 Office 2003 及更早版本),虽然它已经不再更新,不支持较新的 .xlsx 格式,但对于处理旧项目或简单的 .xls 它依然非常轻量、易用。

环境准备:添加 JXL 依赖
你需要在你的 Java 项目中添加 jxl 的依赖,根据你使用的构建工具,选择以下一种方式:
Maven 项目
在你的 pom.xml 文件中添加以下依赖:
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version> <!-- 这是最稳定和常用的版本 -->
</dependency>
Gradle 项目
在你的 build.gradle 文件中添加:
implementation 'net.sourceforge.jexcelapi:jxl:2.6.12'
手动下载 JAR
如果你不使用构建工具,可以手动下载 JAR 文件:

- 访问 Maven 中央仓库:https://mvnrepository.com/artifact/net.sourceforge.jexcelapi/jxl/2.6.12
- 下载
jxl-2.6.12.jar文件。 - 将下载的 JAR 文件添加到你的项目的类路径(Classpath)中。
JXL 读取 Excel 的核心步骤
使用 jxl 读取 Excel 文件通常遵循以下四个核心步骤:
- 获取工作簿对象 (
Workbook):通过Workbook.getWorkbook(File file)方法,打开并读取整个 Excel 文件。 - 获取工作表对象 (
Sheet):通过Workbook.getSheet(int index)或Workbook.getSheet(String name)方法,获取你想要读取的工作表。 - 获取单元格对象 (
Cell):通过Sheet.getCell(int column, int row)方法,获取指定行和列的单元格。 - 读取单元格内容:使用
Cell.getContents()方法获取单元格的字符串内容,并根据需要转换为其他数据类型(如数字、日期等)。
完整代码示例
假设我们有一个名为 data.xls 的 Excel 文件,内容如下:
| 姓名 | 年龄 | 入职日期 | 薪资 |
|---|---|---|---|
| 张三 | 28 | 2025-05-20 | 50 |
| 李四 | 32 | 2025-11-01 | 12000 |
| 王五 | 25 | 2025-03-15 | 00 |
我们将编写一个 Java 程序来读取这个文件,并将数据打印到控制台。
示例代码:
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import java.io.File;
import java.io.IOException;
public class JxlReadExcelExample {
public static void main(String[] args) {
// 1. 定义要读取的Excel文件路径
String excelFilePath = "data.xls";
try {
// 2. 获取工作簿对象
// 注意:jxl只能读取.xls文件,不能读取.xlsx文件
Workbook workbook = Workbook.getWorkbook(new File(excelFilePath));
// 3. 获取第一个工作表 (Sheet)
// 通过索引获取 (从0开始)
Sheet sheet = workbook.getSheet(0);
// 或者通过工作表名称获取
// Sheet sheet = workbook.getSheet("员工信息");
// 4. 获取工作表的行数和列数
int rows = sheet.getRows();
int cols = sheet.getColumns();
System.out.println("工作表 '" + sheet.getName() + "' 共有 " + rows + " 行, " + cols + " 列。");
System.out.println("------------------------------------------");
// 5. 遍历每一行和每一列,读取单元格内容
// 通常我们会跳过第一行(标题行),从第二行开始读取数据
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
// 获取单元格对象
Cell cell = sheet.getCell(j, i);
// 获取单元格内容
String content = cell.getContents();
System.out.print(String.format("%-15s", content)); // 左对齐,宽度15
}
System.out.println(); // 换行
}
// 6. 关闭工作簿对象,释放资源
// 这是一个好习惯,尽管在JVM退出时会自动关闭
workbook.close();
} catch (IOException e) {
System.err.println("文件读取错误,请检查文件路径或文件是否被占用!");
e.printStackTrace();
} catch (BiffException e) {
System.err.println("Excel文件格式错误,可能不是有效的.xls文件!");
e.printStackTrace();
}
}
}
代码解析:
Workbook.getWorkbook(new File(...)): 这是读取操作的入口,它会加载整个 Excel 文件到内存。sheet.getRows()和sheet.getColumns(): 获取工作表的物理行数和列数,注意,这包括所有空行和空列。sheet.getCell(column, row): 获取指定位置的单元格。注意参数顺序是列在前,行在后,这与 Excel 的A1表示法(列字母+行号)和数组的[row][col]习惯都不同,需要特别注意。cell.getContents(): 返回单元格的原始内容,始终是一个String类型,数字5会被读取为"8500.5"。workbook.close(): 关闭Workbook对象,释放与文件相关的资源,对于jxl这很重要。
处理不同类型的单元格
jxl 的 Cell 对象提供了 getType() 方法来判断单元格的数据类型,并提供了相应的 getXXXValue() 方法来获取特定类型的值。
修改后的代码,处理不同类型:
// ... (前面的代码相同) ...
for (int i = 1; i < rows; i++) { // 从第二行开始
// 获取姓名 (字符串)
Cell nameCell = sheet.getCell(0, i);
String name = nameCell.getContents();
// 获取年龄 (数字)
Cell ageCell = sheet.getCell(1, i);
// 先判断类型是否为数字
if (ageCell.getType() == CellType.NUMBER) {
jxl.Number ageNumberCell = (jxl.Number) ageCell;
int age = (int) ageNumberCell.getValue(); // 获取double值后转为int
System.out.println("姓名: " + name + ", 年龄: " + age);
}
// 获取入职日期 (日期)
Cell dateCell = sheet.getCell(2, i);
if (dateCell.getType() == CellType.DATE) {
jxl.Date dateCellObj = (jxl.Date) dateCell;
java.util.Date date = dateCellObj.getDate(); // 获取java.util.Date对象
System.out.println("入职日期: " + date);
}
// 获取薪资 (数字)
Cell salaryCell = sheet.getCell(3, i);
if (salaryCell.getType() == CellType.NUMBER) {
jxl.Number salaryNumberCell = (jxl.Number) salaryCell;
double salary = salaryNumberCell.getValue(); // 直接获取double值
System.out.println("薪资: " + salary);
}
System.out.println("---");
}
// ... (后面的代码相同) ...
关键点:
CellType:jxl提供了CellType枚举,包括LABEL(文本/字符串),NUMBER(数字),DATE(日期),BOOLEAN(布尔值),EMPTY(空单元格) 等。- 类型转换: 当你确定单元格类型后,需要将通用的
Cell对象强制转换为具体的子类,如jxl.Number或jxl.Date,然后才能调用getValue()或getDate()等方法获取实际值。
JXL 的优点和缺点
优点:
- 简单易用:API 非常直观,学习成本低。
- 轻量级:库本身很小,对项目性能影响小。
- 成熟稳定:经过长期使用,非常可靠。
缺点:
- 不支持
.xlsx格式:这是它最大的硬伤,现在基本所有新项目都是.xlsx格式。 - 不再更新:项目自2009年后就停止了更新,没有新功能和安全补丁。
- 功能有限:不支持样式、图表、公式等复杂操作。
- 性能问题:对于非常大的 Excel 文件,一次性加载整个
Workbook到内存可能会导致性能问题或OutOfMemoryError。
替代方案推荐
如果你需要处理 .xlsx 文件,或者需要更强大的功能,强烈推荐使用以下库:
| 库名称 | 支持格式 | 特点 | 推荐度 |
|---|---|---|---|
| Apache POI | .xls, .xlsx |
功能最强大,是业界标准,但 API 相对复杂。 | ⭐⭐⭐⭐⭐ |
| EasyExcel | .xls, .xlsx |
阿里巴巴开源,基于 POI,但 API 更简洁,性能更好,尤其适合大数据量读写。 | ⭐⭐⭐⭐⭐ |
| JXL | .xls |
API 简单,轻量,但已过时,仅适用于旧项目。 | ⭐⭐ |
对于新项目,请优先选择 Apache POI 或 EasyExcel,如果你维护的是一个老旧项目,且只需处理 .xls 文件,jxl 仍然是一个可行的选择。
