Java POI Excel 下载指南
Apache POI 是一个强大的 Java 库,用于处理 Microsoft Office 格式文件,包括 Excel,下面我将介绍如何使用 POI 来生成并下载 Excel 文件。
基本步骤
- 添加 POI 依赖
- 创建 Excel 工作簿和工作表
- 填充数据
- 设置响应头
- 输出 Excel 文件到客户端
完整代码示例
添加 Maven 依赖
<dependencies>
<!-- POI 核心依赖 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
<!-- POI OOXML 支持 (用于 .xlsx 格式) -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
</dependencies>
控制器代码示例 (Spring Boot)
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
@RestController
@RequestMapping("/excel")
public class ExcelDownloadController {
@GetMapping("/download")
public ResponseEntity<byte[]> downloadExcel() throws IOException {
// 1. 创建工作簿
Workbook workbook = new XSSFWorkbook(); // 使用 .xlsx 格式
// 2. 创建工作表
Sheet sheet = workbook.createSheet("员工数据");
// 3. 创建标题行
Row headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("ID");
headerRow.createCell(1).setCellValue("姓名");
headerRow.createCell(2).setCellValue("年龄");
headerRow.createCell(3).setCellValue("部门");
// 4. 填充数据 (这里用模拟数据)
List<Employee> employees = getMockEmployees();
int rowNum = 1;
for (Employee employee : employees) {
Row row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(employee.getId());
row.createCell(1).setCellValue(employee.getName());
row.createCell(2).setCellValue(employee.getAge());
row.createCell(3).setCellValue(employee.getDepartment());
}
// 5. 自动调整列宽
for (int i = 0; i < 4; i++) {
sheet.autoSizeColumn(i);
}
// 6. 写入到输出流
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
workbook.close();
// 7. 设置响应头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", "员工数据.xlsx");
headers.setContentLength(outputStream.toByteArray().length);
return ResponseEntity.ok()
.headers(headers)
.body(outputStream.toByteArray());
}
// 模拟数据方法
private List<Employee> getMockEmployees() {
// 实际项目中可以从数据库或其他数据源获取
return List.of(
new Employee(1, "张三", 28, "技术部"),
new Employee(2, "李四", 32, "市场部"),
new Employee(3, "王五", 25, "人事部")
);
}
// 员工实体类
static class Employee {
private int id;
private String name;
private int age;
private String department;
// 构造方法、getter 和 setter
public Employee(int id, String name, int age, String department) {
this.id = id;
this.name = name;
this.age = age;
this.department = department;
}
// 省略 getter 和 setter...
}
}
关键点说明
-
工作簿类型选择:
HSSFWorkbook: 用于.xls格式 (Excel 2003 及以前)XSSFWorkbook: 用于.xlsx格式 (Excel 2007 及以后)
-
响应头设置:
Content-Type: 设置为application/octet-stream表示二进制流Content-Disposition: 设置为attachment表示下载,并指定文件名
-
性能考虑:
- 对于大数据量,考虑使用 SXSSF (流式 API) 来避免内存问题
- 及时关闭工作簿和流资源
使用 SXSSF 处理大数据量
// 使用 SXSSF 处理大数据量 Workbook workbook = new SXSSFWorkbook(100); // 在内存中保留100行,其余写入临时文件 // 其他操作与 XSSFWorkbook 相同 // 最后清理临时文件 ((SXSSFWorkbook) workbook).dispose();
前端调用示例
使用 JavaScript (Axios) 调用下载接口:
axios.get('/excel/download', {
responseType: 'blob'
}).then(response => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', '员工数据.xlsx');
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
注意事项
- 确保在服务器端正确处理异常和资源释放
- 对于大型 Excel 文件,考虑使用异步处理或任务队列
- 根据需求设置适当的响应头,如缓存控制
- 考虑添加进度反馈机制,特别是对于大文件
希望这个指南对你有所帮助!如果有任何具体问题或需要更详细的示例,请随时提问。
