如何将JSP页面中带过滤的对象列表导出为Excel文件?
把JSP中过滤后的对象列表导出为Excel的方案
嘿,这个需求在Java Web开发里挺常见的,我给你分享两个实用的实现思路,都是经过大量项目验证的:
方案一:使用Apache POI生成标准Excel文件(推荐)
Apache POI是Java生态里处理Office文档的主流库,支持生成.xls(旧版)和.xlsx(新版)格式,能应对复杂的表格样式需求。
步骤1:添加依赖
如果用Maven,在pom.xml里加入:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.5</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.5</version> </dependency>
Gradle的话:
implementation 'org.apache.poi:poi:5.2.5' implementation 'org.apache.poi:poi-ooxml:5.2.5'
步骤2:编写下载处理逻辑(推荐用Servlet,避免JSP写过多Java代码)
假设你的对象是User,属性有id、username、email、createTime,过滤后的列表已经存在Session或者可以通过请求参数重新获取:
@WebServlet("/export-excel") public class ExcelExportServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 获取当前页面过滤后的对象列表(这里假设从Session取,也可以根据请求参数重新执行过滤逻辑) List<User> filteredUsers = (List<User>) request.getSession().getAttribute("filteredUsers"); // 2. 创建Excel工作簿(XSSFWorkbook对应.xlsx,HSSFWorkbook对应.xls) Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet("用户列表"); // 3. 创建表头行 Row headerRow = sheet.createRow(0); String[] headers = {"ID", "用户名", "邮箱", "创建时间"}; for (int i = 0; i < headers.length; i++) { Cell cell = headerRow.createCell(i); cell.setCellValue(headers[i]); // 可选:设置表头样式 CellStyle style = workbook.createCellStyle(); style.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex()); style.setFillPattern(FillPatternType.SOLID_FOREGROUND); cell.setCellStyle(style); } // 4. 填充数据行 int rowNum = 1; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for (User user : filteredUsers) { Row row = sheet.createRow(rowNum++); row.createCell(0).setCellValue(user.getId()); row.createCell(1).setCellValue(user.getUsername()); row.createCell(2).setCellValue(user.getEmail()); row.createCell(3).setCellValue(sdf.format(user.getCreateTime())); } // 5. 设置响应头,告诉浏览器下载文件 response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setHeader("Content-Disposition", "attachment; filename=\"用户列表_" + System.currentTimeMillis() + ".xlsx\""); response.setCharacterEncoding("UTF-8"); // 6. 写出文件到响应流 ServletOutputStream outputStream = response.getOutputStream(); workbook.write(outputStream); // 7. 关闭资源 workbook.close(); outputStream.flush(); outputStream.close(); } }
步骤3:在JSP页面添加下载按钮
<a href="${pageContext.request.contextPath}/export-excel" class="btn btn-primary">导出当前列表为Excel</a>
方案二:生成CSV文件(轻量无依赖)
如果不需要复杂的Excel样式,CSV是个更简单的选择——它是纯文本格式,Excel能直接打开,而且不需要额外引入库。
步骤1:编写CSV导出Servlet
@WebServlet("/export-csv") public class CsvExportServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<User> filteredUsers = (List<User>) request.getSession().getAttribute("filteredUsers"); // 设置响应头 response.setContentType("text/csv; charset=UTF-8"); response.setHeader("Content-Disposition", "attachment; filename=\"用户列表_" + System.currentTimeMillis() + ".csv\""); PrintWriter writer = response.getWriter(); // 写入表头 writer.write("ID,用户名,邮箱,创建时间\n"); // 写入数据,注意处理特殊字符(比如内容含逗号或引号时要包裹) SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for (User user : filteredUsers) { // 处理字段中的逗号和引号,用双引号包裹 String username = wrapSpecialChars(user.getUsername()); String email = wrapSpecialChars(user.getEmail()); writer.write(String.format("%d,%s,%s,%s\n", user.getId(), username, email, sdf.format(user.getCreateTime()))); } writer.flush(); writer.close(); } // 辅助方法:处理CSV中的特殊字符 private String wrapSpecialChars(String content) { if (content == null) return ""; // 如果包含逗号、双引号或换行,就用双引号包裹,并且内部的双引号要转成两个 if (content.contains(",") || content.contains("\"") || content.contains("\n")) { return "\"" + content.replace("\"", "\"\"") + "\""; } return content; } }
步骤2:页面添加CSV下载按钮
<a href="${pageContext.request.contextPath}/export-csv" class="btn btn-secondary">导出当前列表为CSV(Excel兼容)</a>
注意事项
- 确保数据一致性:导出的列表必须和页面当前展示的过滤后列表一致,建议把过滤后的列表存在Session中,或者在导出时传递所有过滤参数到Servlet,重新执行过滤逻辑。
- 中文乱码处理:无论哪种方案,都要明确设置响应的字符编码为UTF-8,CSV还要在Content-Type里指定charset。
- 资源释放:使用Apache POI时,一定要关闭Workbook和输出流,避免内存泄漏。
- 避免在JSP中写逻辑:尽量用Servlet或者MVC框架的Controller处理导出逻辑,JSP只负责渲染视图和提供下载入口。
内容的提问来源于stack exchange,提问作者Gayathri
相关产品推荐
相关产品推荐

