jxl (Java Excel API) 是一个比较老牌的 Java 操作 Excel 的库,它支持 .xls 格式(即 Excel 97-2003 版本),对于新项目,更推荐使用 Apache POI,因为它功能更强大、社区更活跃,并且支持 .xlsx 格式,如果你需要维护旧项目或者对 .xls 格式有特定需求,jxl 仍然是一个简单易用的选择。

准备工作:添加 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
如果你不使用构建工具,可以 从官网下载 JAR 包,然后将其添加到你的项目类路径中。

JXL 核心概念
在开始编码前,先了解几个核心类:
WritableWorkbook: 代表一个可写入的 Excel 工作簿,在创建新 Excel 文件或修改现有文件时使用。WritableSheet: 代表WritableWorkbook中的一个工作表。Label: 代表 Excel 中的一个单元格,用于写入字符串类型的数据。Number: 代表 Excel 中的一个单元格,用于写入数字类型的数据。DateTime: 代表 Excel 中的一个单元格,用于写入日期类型的数据。WritableCellFormat: 用于设置单元格的样式,如字体、颜色、对齐方式、边框等。
完整示例:导出数据到 Excel
下面是一个完整的、可直接运行的 Java 示例,演示如何将一个用户列表数据导出到一个名为 users.xls 的文件中。
import jxl.*;
import jxl.write.*;
import jxl.write.Number;
import jxl.write.biff.RowsExceededException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class JxlExportExample {
public static void main(String[] args) {
// 1. 准备要导出的数据
List<User> userList = prepareData();
// 2. 定义要导出的文件路径
String filePath = "D:/temp/users.xls";
// 3. 调用导出方法
exportUsersToExcel(userList, filePath);
System.out.println("Excel 文件导出成功!路径: " + filePath);
}
/**
* 导出用户数据到 Excel 文件
* @param userList 用户数据列表
* @param filePath 导出文件路径
*/
public static void exportUsersToExcel(List<User> userList, String filePath) {
// 使用 try-with-resources 语句,确保资源被自动关闭
try (WritableWorkbook workbook = Workbook.createWorkbook(new File(filePath))) {
// 4. 创建一个工作表
WritableSheet sheet = workbook.createSheet("用户信息", 0); // "用户信息"是工作表名, 0是工作表索引
// 5. 设置表头(使用 Label 对象)
WritableCellFormat headerFormat = new WritableCellFormat();
// 设置字体为粗体
WritableFont headerFont = new WritableFont(WritableFont.ARIAL, 10, WritableFont.BOLD);
headerFormat.setFont(headerFont);
// 设置背景色(浅灰色)
jxl.format.Pattern headerPattern = new jxl.format.Pattern(jxl.format.Colour.GRAY_25);
headerFormat.setBackground(headerPattern);
// 添加表头单元格
sheet.addCell(new Label(0, 0, "ID", headerFormat));
sheet.addCell(new Label(1, 0, "姓名", headerFormat));
sheet.addCell(new Label(2, 0, "年龄", headerFormat));
sheet.addCell(new Label(3, 0, "创建日期", headerFormat));
// 6. 写入数据行
for (int i = 0; i < userList.size(); i++) {
User user = userList.get(i);
int rowNum = i + 1; // Excel 行号从 0 开始,数据行从 1 开始(因为第 0 行是表头)
// 写入ID (使用 Number 类型)
sheet.addCell(new Number(0, rowNum, user.getId()));
// 写入姓名 (使用 Label 类型)
sheet.addCell(new Label(1, rowNum, user.getName()));
// 写入年龄 (使用 Number 类型)
sheet.addCell(new Number(2, rowNum, user.getAge()));
// 写入创建日期 (使用 DateTime 类型)
sheet.addCell(new DateTime(3, rowNum, user.getCreateDate()));
}
// 7. 写入文件并关闭
// write() 方法会将所有在内存中的操作写入到指定的文件中
workbook.write();
} catch (IOException e) {
System.err.println("创建或写入文件时发生IO异常: " + e.getMessage());
e.printStackTrace();
} catch (WriteException e) {
System.err.println("写入Excel数据时发生异常: " + e.getMessage());
e.printStackTrace();
}
}
/**
* 模拟准备用户数据
*/
private static List<User> prepareData() {
List<User> users = new ArrayList<>();
users.add(new User(1L, "张三", 28, new Date()));
users.add(new User(2L, "李四", 32, new Date()));
users.add(new User(3L, "王五", 25, new Date()));
users.add(new User(4L, "赵六", 45, new Date()));
return users;
}
/**
* 用户实体类
*/
static class User {
private Long id;
private String name;
private int age;
private Date createDate;
public User(Long id, String name, int age, Date createDate) {
this.id = id;
this.name = name;
this.age = age;
this.createDate = createDate;
}
// Getters
public Long getId() { return id; }
public String getName() { return name; }
public int getAge() { return age; }
public Date getCreateDate() { return createDate; }
}
}
代码解析:
- 准备数据:创建一个
User对象列表,这是我们要导出的源数据。 - 创建
WritableWorkbook:Workbook.createWorkbook(new File(filePath))会创建一个新的、空的 Excel 工作簿,如果文件已存在,它将被覆盖。 - 创建
WritableSheet:workbook.createSheet()在工作簿中创建一个新的工作表。 - 设置表头:
- 创建
WritableCellFormat和WritableFont来定义表头的样式(粗体、灰色背景)。 - 使用
new Label(column, row, "内容", format)来创建表头单元格。Label用于文本。
- 创建
- 写入数据行:
- 遍历数据列表,为每个用户对象创建一行。
- 注意:Excel 的行列索引都是从
0开始的,表头在第0行,所以数据行从1开始。 - 根据数据类型选择合适的单元格对象:
- 数字用
Number(column, row, value)。 - 字符串用
Label(column, row, value)。 - 日期用
DateTime(column, row, value)。
- 数字用
- 写入并关闭:调用
workbook.write()将内存中的 Excel 对象持久化到磁盘文件。try-with-resources会自动调用workbook.close(),确保资源被正确释放。
常用功能与技巧
1 设置单元格样式
除了表头的样式,你还可以为数据单元格设置样式。
// 创建一个单元格格式 WritableCellFormat numberFormat = new WritableCellFormat(); // 设置字体 WritableFont font = new WritableFont(WritableFont.ARIAL, 10, WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE, jxl.format.Colour.BLACK); numberFormat.setFont(font); // 设置对齐方式(水平居中) numberFormat.setAlignment(jxl.format.Alignment.CENTRE); // 设置垂直居中 numberFormat.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE); // 设置边框 numberFormat.setBorder(Border.ALL, BorderLineStyle.THIN, Colour.BLACK); // 应用样式 sheet.addCell(new Number(0, 1, 100, numberFormat));
2 合并单元格
使用 WritableSheet.mergeCells() 方法。
// 合并从 (0, 0) 到 (2, 0) 的区域,即第 0 行,第 0 列到第 2 列 sheet.mergeCells(0, 0, 2, 0); // 在合并后的区域的左上角单元格写入内容 sheet.addCell(new Label(0, 0, "合并的标题"));
3 设置列宽
使用 WritableSheet.setColumnWidth() 方法。
// 设置第 1 列(索引为 1)的宽度,宽度是字符数 sheet.setColumnWidth(1, 20); // 设置姓名列宽度为 20 个字符 sheet.setColumnWidth(2, 5); // 设置年龄列宽度为 5 个字符
4 在 Web 应用中导出(Servlet 示例)
在 Web 应用中,通常需要将 Excel 文件作为附件直接提供给用户下载,而不是保存到服务器磁盘。
// 在 Servlet 的 doGet 或 doPost 方法中
response.setContentType("application/vnd.ms-excel"); // 设置正确的 MIME 类型
response.setHeader("Content-Disposition", "attachment; filename=user_list.xls"); // 设置下载文件名
// 获取输出流
OutputStream out = response.getOutputStream();
try (WritableWorkbook workbook = Workbook.createWorkbook(out)) {
// ... (和上面示例中一样,创建 sheet 和写入数据)
// 写入数据
workbook.write();
} catch (Exception e) {
// 处理异常
e.printStackTrace();
} finally {
// 确保输出流被关闭
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
JXL 的局限性
尽管 jxl 简单易用,但它也存在一些明显的缺点:
- 不支持
.xlsx格式:这是最致命的缺点。.xlsx是目前 Excel 的标准格式,而jxl只能处理旧版的.xls格式。 - 停止更新:
jxl项目已经很多年没有更新了,对于 Excel 的新特性(如复杂的图表、公式、数据透视表等)完全不支持。 - 功能有限:在样式、图片插入、复杂公式等方面的功能远不如 Apache POI 强大。
| 特性 | JXL | Apache POI |
|---|---|---|
| 格式支持 | 仅 .xls |
.xls 和 .xlsx |
| 社区活跃度 | 低,已停止更新 | 高,持续更新 |
| 功能丰富度 | 基础功能(读、写、简单样式) | 非常强大(样式、图表、公式、图片等) |
| API 易用性 | 简单直观 | 相对复杂,但功能更全面 |
| 推荐场景 | 旧项目维护、对 .xls 有简单需求的新项目 |
所有新项目,特别是需要 .xlsx 或复杂功能的场景 |
对于新项目,强烈建议直接使用 Apache POI,如果你正在维护一个旧的 jxl 项目,或者只需要做一个非常简单的 .xls 导出功能,jxl 仍然是一个可以快速完成任务的选择。
