jxl 是一个比较老牌但非常轻量级的 Java 操作 Excel 的库,主要支持 .xls 格式(Excel 97-2003),虽然现在有更现代的库(如 Apache POI),但如果你只需要处理简单的 .xls 文件,jxl 是一个非常不错的选择。

环境准备
你需要在你的项目中添加 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 包的方式,请从 Maven 中央仓库 下载 jxl-2.6.12.jar 并将其添加到你的项目类路径中。

核心概念和常用 API
在开始编码前,了解 jxl 的核心类非常重要:
WritableWorkbook: 代表一个可写入的 Excel 工作簿,这是你创建新 Excel 文件的起点。WritableSheet: 代表工作簿中的一个工作表,你可以创建多个工作表。Label: 代表工作表中的一个字符串单元格。Number: 代表工作表中的一个数字单元格。DateTime: 代表工作表中的一个日期时间单元格。WritableCellFormat: 用于设置单元格的格式(如字体、颜色、对齐方式、边框等)。jxl.write.WritableFont: 用于设置字体样式(如大小、粗体、斜体等)。
完整代码示例:导出简单的 Excel 文件
下面是一个完整的、可运行的示例,它将创建一个名为 student_list.xls 的文件,并写入一些学生数据。
import jxl.Workbook;
import jxl.write.*;
import jxl.write.Number;
import jxl.write.biff.RowsExceededException;
import java.io.File;
import java.io.IOException;
public class JxlExportExample {
public static void main(String[] args) {
// 1. 定义要导出的文件路径
String filePath = "D:/temp/student_list.xls";
try {
// 2. 创建或打开一个可写入的工作簿
// 如果文件已存在,它会覆盖,如果不存在,它会创建。
WritableWorkbook writableWorkbook = Workbook.createWorkbook(new File(filePath));
// 3. 创建一个名为 "学生信息" 的工作表
// 0 表示第一个工作表
WritableSheet writableSheet = writableWorkbook.createSheet("学生信息", 0);
// 4. 设置单元格格式(可选,但推荐)
// 创建一个标题行的格式:加粗、居中
WritableFont titleFont = new WritableFont(WritableFont.ARIAL, 12, WritableFont.BOLD);
WritableCellFormat titleFormat = new WritableCellFormat(titleFont);
titleFormat.setAlignment(jxl.format.Alignment.CENTRE); // 水平居中
titleFormat.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE); // 垂直居中
// 创建一个普通数据行的格式
WritableCellFormat dataFormat = new WritableCellFormat();
// 5. 向工作表中写入数据
// 写入表头
writableSheet.addCell(new Label(0, 0, "学号", titleFormat));
writableSheet.addCell(new Label(1, 0, "姓名", titleFormat));
writableSheet.addCell(new Label(2, 0, "年龄", titleFormat));
writableSheet.addCell(new Label(3, 0, "成绩", titleFormat));
// 写入数据行
// 第一行数据
writableSheet.addCell(new Label(0, 1, "1001", dataFormat));
writableSheet.addCell(new Label(1, 1, "张三", dataFormat));
writableSheet.addCell(new Number(2, 1, 20, dataFormat)); // 数字类型用 Number
writableSheet.addCell(new Number(3, 1, 95.5, dataFormat));
// 第二行数据
writableSheet.addCell(new Label(0, 2, "1002", dataFormat));
writableSheet.addCell(new Label(1, 2, "李四", dataFormat));
writableSheet.addCell(new Number(2, 2, 21, dataFormat));
writableSheet.addCell(new Number(3, 2, 88.0, dataFormat));
// 第三行数据
writableSheet.addCell(new Label(0, 3, "1003", dataFormat));
writableSheet.addCell(new Label(1, 3, "王五", dataFormat));
writableSheet.addCell(new Number(2, 3, 19, dataFormat));
writableSheet.addCell(new Number(3, 3, 92.5, dataFormat));
// 6. 自动调整列宽(jxl 本身不提供直接方法,这里简单演示手动设置)
// 设置第一列宽度
writableSheet.setColumnView(0, 10); // 列索引0,宽度为10个字符
writableSheet.setColumnView(1, 15); // 列索引1,宽度为15个字符
writableSheet.setColumnView(2, 8); // 列索引2,宽度为8个字符
writableSheet.setColumnView(3, 10); // 列索引3,宽度为10个字符
// 7. 写入文件并关闭工作簿
// 这一步非常重要,会将所有写入操作从内存保存到磁盘
writableWorkbook.write();
writableWorkbook.close();
System.out.println("Excel 文件导出成功!路径: " + filePath);
} catch (IOException e) {
System.err.println("文件操作错误: " + e.getMessage());
e.printStackTrace();
} catch (RowsExceededException e) {
System.err.println("行数超出限制: " + e.getMessage());
e.printStackTrace();
} catch (WriteException e) {
System.err.println("写入Excel错误: " + e.getMessage());
e.printStackTrace();
}
}
}
代码解释:
Workbook.createWorkbook(new File(filePath)): 创建一个新的WritableWorkbook对象,关联到指定的文件,如果文件存在,其内容将被覆盖。writableWorkbook.createSheet("学生信息", 0): 在工作簿中创建一个名为 "学生信息" 的工作表,0是工作表的索引。new Label(column, row, content, format): 用于写入字符串。column和row是从 0 开始的索引。new Number(column, row, value, format): 用于写入数字。WritableCellFormat: 创建一个格式对象,并将其应用到Label或Number上,以统一设置样式。writableSheet.setColumnView(column, width): 设置指定列的宽度。writableWorkbook.write()和writableWorkbook.close(): 必须执行。write()方法将内存中的数据写入到文件流中,close()方法会关闭文件流并释放资源。最佳实践是使用try-finally或try-with-resources确保其总能被关闭。
更复杂的示例:合并单元格、添加日期
下面我们来看一个更高级的例子,演示如何合并单元格和写入日期。
import jxl.*;
import jxl.format.*;
import jxl.write.*;
import jxl.write.biff.RowsExceededException;
import java.io.File;
import java.io.IOException;
import java.util.Date;
public class JxlAdvancedExample {
public static void main(String[] args) {
String filePath = "D:/temp/advanced_report.xls";
try {
WritableWorkbook workbook = Workbook.createWorkbook(new File(filePath));
WritableSheet sheet = workbook.createSheet("月度报告", 0);
// 1. 合并单元格 (从第0列第0行 到 第2列第0行)
sheet.mergeCells(0, 0, 2, 0);
// 2. 创建大标题的格式
WritableFont titleFont = new WritableFont(WritableFont.TIMES, 16, WritableFont.BOLD);
WritableCellFormat titleFormat = new WritableCellFormat(titleFont);
titleFormat.setAlignment(Alignment.CENTRE);
titleFormat.setBackground(Colour.GRAY_25); // 设置背景色
// 3. 创建副标题和日期的格式
WritableFont subtitleFont = new WritableFont(WritableFont.ARIAL, 10);
WritableCellFormat subtitleFormat = new WritableCellFormat(subtitleFont);
subtitleFormat.setAlignment(Alignment.RIGHT);
// 4. 创建数据行的格式
WritableCellFormat dataFormat = new WritableCellFormat();
dataFormat.setBorder(Border.ALL, BorderLineStyle.THIN); // 添加所有边框
// 5. 写入合并后的标题
sheet.addCell(new Label(0, 0, "2025年12月销售报告", titleFormat));
// 6. 写入副标题和日期
sheet.addCell(new Label(0, 1, "报告日期:", subtitleFormat));
// 写入日期,使用 DateTime 类
sheet.addCell(new DateTime(1, 1, new Date(), subtitleFormat));
// 7. 写入表头
sheet.addCell(new Label(0, 3, "产品名称", dataFormat));
sheet.addCell(new Label(1, 3, "销售数量", dataFormat));
sheet.addCell(new Label(2, 3, "销售额", dataFormat));
// 8. 写入数据
sheet.addCell(new Label(0, 4, "笔记本电脑", dataFormat));
sheet.addCell(new Number(1, 4, 120, dataFormat));
sheet.addCell(new Number(2, 4, 960000.00, dataFormat));
sheet.addCell(new Label(0, 5, "智能手机", dataFormat));
sheet.addCell(new Number(1, 5, 350, dataFormat));
sheet.addCell(new Number(2, 5, 525000.00, dataFormat));
// 9. 自动调整行高和列宽 (jxl没有直接API,这里手动设置列宽)
sheet.setColumnView(0, 20);
sheet.setColumnView(1, 15);
sheet.setColumnView(2, 20);
// 10. 写入并关闭
workbook.write();
workbook.close();
System.out.println("高级Excel文件导出成功!");
} catch (WriteException | IOException e) {
e.printStackTrace();
}
}
}
重要注意事项
-
.xls格式限制:
(图片来源网络,侵删)jxl不支持.xlsx(Excel 2007+) 格式,如果你的用户需要新格式的 Excel 文件,请使用 Apache POI 库。- 它支持的最大行数和列数受限于
.xls格式本身(65536行,256列)。
-
异常处理:
jxl的写入操作会抛出IOException和WriteException。WriteException通常是格式错误或写入内容不符合规则导致的,建议将它们都捕获并处理。
-
资源关闭:
- 务必调用
writableWorkbook.close(),如果忘记关闭,文件可能会损坏或内容不完整,使用try-finally块可以确保即使发生异常,资源也能被正确释放。
- 务必调用
-
性能:
- 对于导出海量数据(例如几十万行),
jxl的性能可能不是最优的,因为它会将所有数据都加载到内存中,对于大数据量导出,可以考虑使用 SXSSF (Streaming Usermodel API) 模式的 Apache POI,它采用流式处理,内存占用非常低。
- 对于导出海量数据(例如几十万行),
替代方案:Apache POI
虽然 jxl 很简单,但 Apache POI 是目前 Java 操作 Excel 的事实标准,它功能更强大,支持 .xls 和 .xlsx,社区更活跃。
如果你需要新功能或处理更复杂的场景,强烈建议学习 POI,下面是使用 POI 实现上述第一个简单示例的对比:
// Apache POI (简化版)
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
// ... (省略依赖和main方法)
try (Workbook workbook = new HSSFWorkbook()) { // try-with-resources 自动关闭
Sheet sheet = workbook.createSheet("学生信息");
// 创建样式
CellStyle titleStyle = workbook.createCellStyle();
Font titleFont = workbook.createFont();Font.setBold(true);Style.setFont(titleFont);
// 写入表头
Row headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("学号");
headerRow.createCell(1).setCellValue("姓名");
// ... 应用样式等
// 写入数据
Row dataRow = sheet.createRow(1);
dataRow.createCell(0).setCellValue("1001");
dataRow.createCell(1).setCellValue("张三");
dataRow.createCell(2).setCellValue(20); // 数字直接setCellValue
// 写入文件
try (FileOutputStream out = new FileOutputStream("D:/temp/poi_student_list.xls")) {
workbook.write(out);
}
}
可以看到,POI 的 API 设计更贴近 Excel 对象模型(Workbook -> Sheet -> Row -> Cell),非常直观。
| 特性 | jxl (Java Excel API) | Apache POI |
|---|---|---|
| 优点 | 轻量级、API 简单、上手快 | 功能强大、社区活跃、支持 .xlsx |
| 缺点 | 功能有限、不支持 .xlsx、已停止更新 |
API 相对复杂、JAR 包较大 |
| 适用场景 | 简单的 .xls 文件导出,项目依赖要求轻量 |
复杂的 Excel 操作,必须支持新格式,大数据量 |
对于新的项目,除非有特殊原因,否则推荐直接使用 Apache POI,但如果你只是需要快速实现一个简单的 .xls 导出功能,jxl 仍然是一个可靠的选择。
