jxl 是一个比较老牌但依然在许多项目中使用的 Java 库,专门用于操作 Excel 97-2003 格式的文件(即 .xls 文件),它轻量级、简单易用。

准备工作:添加 JXL 依赖
你需要在你的项目中添加 jxl 的依赖,如果你使用 Maven,可以在 pom.xml 文件中添加以下依赖:
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version> <!-- 这是最常用和稳定的版本 -->
</dependency>
如果你不使用 Maven,可以从 Maven 中央仓库下载 jxl-2.6.12.jar 文件,并将其添加到你的项目的 classpath 中。
JXL 读取 Excel 的核心步骤
使用 jxl 读取 Excel 文件的基本流程如下:
- 获取工作簿对象 (
Workbook):通过Workbook.getWorkbook()方法,传入 Excel 文件的输入流,来打开一个.xls文件。 - 获取工作表对象 (
Sheet):通过Workbook.getSheet()方法,根据工作表的名称或索引来获取你想要读取的工作表。 - 获取单元格对象 (
Cell):通过Sheet.getCell()方法,根据单元格的列索引和行索引来获取具体的单元格。 - 读取单元格内容:使用
Cell.getContents()方法获取单元格的字符串内容。 - 关闭资源 (
Workbook):一定要调用Workbook.close()方法来关闭工作簿,释放系统资源。
完整代码示例
假设我们有一个名为 test_data.xls 的 Excel 文件,内容如下:

| A | B | C | |
|---|---|---|---|
| 1 | 姓名 | 年龄 | 城市 |
| 2 | 张三 | 25 | 北京 |
| 3 | 李四 | 30 | 上海 |
| 4 | 王五 | 28 | 广州 |
下面是一个完整的 Java 程序,用于读取这个 Excel 文件并打印内容。
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 文件路径
File excelFile = new File("test_data.xls");
try {
// 2. 获取工作簿对象
// 注意:这里需要处理可能抛出的 BiffException 和 IOException
Workbook workbook = Workbook.getWorkbook(excelFile);
// 3. 获取第一个工作表 (Sheet),索引从 0 开始
Sheet sheet = workbook.getSheet(0);
// 4. 获取工作表的行数和列数
int rows = sheet.getRows();
int columns = sheet.getColumns();
System.out.println("工作表 '" + sheet.getName() + "' 有 " + rows + " 行, " + columns + " 列。");
System.out.println("------------------------------------");
// 5. 遍历工作表中的每一个单元格
// 通常我们会跳过第一行(表头),直接从数据开始读
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
// 获取单元格对象
jxl.Cell cell = sheet.getCell(j, i);
// 获取单元格内容
String content = cell.getContents();
// 打印内容,并用制表符 \t 对齐
System.out.print(content + "\t");
}
// 每行打印完后换行
System.out.println();
}
// 6. 关闭工作簿,释放资源
workbook.close();
} catch (IOException e) {
System.err.println("文件读取错误,请检查文件路径或文件是否被占用!");
e.printStackTrace();
} catch (BiffException e) {
System.err.println("文件格式错误,或者文件已损坏!");
e.printStackTrace();
}
}
}
代码解释:
-
File excelFile = new File("test_data.xls");创建一个File对象,指向你的 Excel 文件,请确保该文件存在于项目根目录或提供正确的绝对路径。 -
Workbook workbook = Workbook.getWorkbook(excelFile);这是核心步骤,它打开.xls文件并返回一个Workbook对象,如果文件不存在、格式不对或已损坏,会抛出IOException或BiffException。 -
Sheet sheet = workbook.getSheet(0);通过索引0获取第一个工作表,你也可以使用workbook.getSheet("Sheet1")通过名称获取。
(图片来源网络,侵删) -
sheet.getRows()和sheet.getColumns()获取工作表的行数和列数,方便我们使用循环遍历。 -
双层
for循环 外层循环遍历行 (i),内层循环遍历列 (j)。sheet.getCell(j, i)中的j是列索引,i是行索引。 -
cell.getContents()获取单元格的原始内容,无论单元格是数字、日期还是字符串,它都会返回一个String。 -
workbook.close()非常重要! 必须关闭Workbook对象,否则可能会导致文件句柄泄露。
更高级的读取:获取特定类型的数据
jxl 的 Cell 对象提供了 getType() 方法,可以判断单元格的数据类型(如字符串、数字、日期等),然后可以将其强制转换为对应的子类对象来获取更精确的值。
jxl.Cell 的主要子类有:
jxl.Label: 字符串类型jxl.Number: 数字类型jxl.Date: 日期类型
示例:读取数字和日期
假设 Excel 中有如下数据:
| A | B | |
|---|---|---|
| 1 | 产品名称 | 价格 |
| 2 | 笔记本电脑 | 0 |
| 3 | 发布日期 | 2025-10-27 |
import jxl.Cell;
import jxl.DateCell;
import jxl.LabelCell;
import jxl.NumberCell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class JxlAdvancedReadExample {
public static void main(String[] args) {
File excelFile = new File("advanced_data.xls");
try {
Workbook workbook = Workbook.getWorkbook(excelFile);
Sheet sheet = workbook.getSheet(0);
// 假设数据在第2行 (索引为1)
int rowIndex = 1;
// 读取产品名称 (字符串)
Cell productNameCell = sheet.getCell(0, rowIndex);
if (productNameCell.getType() == Cell.LABEL) {
LabelCell labelCell = (LabelCell) productNameCell;
String productName = labelCell.getString();
System.out.println("产品名称: " + productName);
}
// 读取价格 (数字)
Cell priceCell = sheet.getCell(1, rowIndex);
if (priceCell.getType() == Cell.NUMBER) {
NumberCell numberCell = (NumberCell) priceCell;
double price = numberCell.getValue(); // 获取 double 类型的值
System.out.println("产品价格: " + price);
}
// 读取日期 (日期)
rowIndex++; // 移动到下一行
Cell dateCell = sheet.getCell(1, rowIndex);
if (dateCell.getType() == Cell.DATE) {
DateCell dateCellObj = (DateCell) dateCell;
Date date = dateCellObj.getDate(); // 获取 Date 对象
// 格式化日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
String formattedDate = sdf.format(date);
System.out.println("发布日期: " + formattedDate);
}
workbook.close();
} catch (IOException | BiffException e) {
e.printStackTrace();
}
}
}
重要注意事项和局限性
-
只支持
.xls格式:jxl不支持 新版本的.xlsx(Excel 2007及以上) 格式,如果你尝试读取.xlsx文件,会抛出异常,对于.xlsx文件,你应该使用更现代的库,如 Apache POI。 -
已停止维护:
jxl项目已经很久没有更新了,官方不再提供维护和技术支持,对于新项目,强烈推荐使用 Apache POI,它功能更强大、支持格式更多、社区也更活跃。 -
内存消耗:
jxl在读取整个 Excel 文件时,会将所有数据都加载到内存中,如果处理非常大的 Excel 文件(例如几十万行),可能会导致内存溢出(OutOfMemoryError),而 Apache POI 提供了 SXSSF (Streaming Usermodel) API 可以处理超大文件,它采用流式读取,内存占用非常小。
| 特性 | JXL | Apache POI |
|---|---|---|
| 支持格式 | 仅 .xls |
.xls, .xlsx, .xlsm 等 |
| 维护状态 | 已停止维护 | 活跃维护,持续更新 |
| API 复杂度 | 简单,易于上手 | 相对复杂,但功能强大 |
| 大数据处理 | 不支持,全量加载 | 支持 (SXSSF 模式) |
| 推荐场景 | 旧项目维护、简单 .xls 读取 |
所有新项目,特别是需要处理 .xlsx 或大数据量时 |
如果你的项目只需要读取简单的 .xls 文件,并且不想引入复杂的依赖,jxl 仍然是一个不错的选择,但如果你的项目有任何长远性或扩展性的考虑,请直接选择 Apache POI。
