Apache POI - 使用 XSSFWorkbok + servlet 响应
Posted
技术标签:
【中文标题】Apache POI - 使用 XSSFWorkbok + servlet 响应【英文标题】:Apache POI - Working with XSSFWorkbok + servlet response 【发布时间】:2013-03-01 12:02:27 【问题描述】:我的 java 应用程序无法下载 XLSX 文件。
按照此链接中显示的示例:Create an excel file for users to download using Apache POI,我尝试了两种配置来下载/保存电子表格。
首先使用 .XLS 文件:
response.setContentType("application/ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=testxls.xls");
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell(0);
cell.setCellValue("Some text");
ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
wb.write(outByteStream);
byte[] outArray = outByteStream.toByteArray();
OutputStream outStream = response.getOutputStream();
outStream.write(outArray);
outStream.flush();
这行得通。
然后我尝试使用 XLSX 文件:
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=testxls.xlsx");
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet();
XSSFRow row = sheet.createRow(0);
XSSFCell cell = row.createCell(0);
cell.setCellValue("Some text");
ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
wb.write(outByteStream);
byte[] outArray = outByteStream.toByteArray();
OutputStream outStream = response.getOutputStream();
outStream.write(outArray);
outStream.flush();
当我尝试此操作时,我收到消息:“Excel 在 'testxls.xlsx' 中发现了不可读的内容。是否要恢复此工作簿的内容?....” p>
尽管有此消息,电子表格仍可正常打开,但我真的想删除此消息。
有什么想法吗?
【问题讨论】:
outByteStream
是什么类型?
为什么需要ByteArrayOutputStream
?你不能简单地改用wb.write(response.getOutputStream())
吗?
我试过org.apache.commons.io.output.ByteArrayOutputStream
和java.io.ByteArrayOutputStream
尝试使用wb.write(response.getOutputStream())
,但消息仍然存在。
如果您将 XSSFWorkbook 写入文件而不是 servlet,Excel 是否可以正确打开该文件?如果您有 servlet 输出问题或 XSSF 问题,这会让您解决问题
【参考方案1】:
使用这个JSP代码,成功生成excel文件。我已经通过数据库给excel文件输入了,你也可以手动输入。
<%HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
try
java.sql.Connection con;
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/custinfo","root","abc");
Statement st= con.createStatement();
out.println("hello world");
ResultSet rs=st.executeQuery("select name ,state ,balance,description from customerdata where customerid='"+Id+"'");
HSSFRow row = sheet.createRow((short)0);
row.createCell((short)0).setCellValue("NAME");
row.createCell((short)1).setCellValue("STATE");
row.createCell((short)2).setCellValue("BALANCE");
row.createCell((short)3).setCellValue("DESCRIPTION");
while(rs.next())
out.println("hello world data");
HSSFRow row1 = sheet.createRow((short)i);
row1.createCell((short)0).setCellValue(rs.getString("name"));
row1.createCell((short)1).setCellValue(rs.getString("state"));
row1.createCell((short)2).setCellValue(rs.getString(3));
row1.createCell((short)3).setCellValue(rs.getString(4));
i=i+1;
sheet.autoSizeColumn((short)1);
catch(SQLException e)
out.println("SQLException caught: " +e.getMessage());
%>
// create a small spreadsheet
<%
%>
<%
ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
wb.write(outByteStream);
byte [] outArray = outByteStream.toByteArray();
response.setContentType("application/ms-excel");
response.setContentLength(outArray.length);
response.setHeader("Expires:", "0"); // eliminates browser caching
response.setHeader("Content-Disposition", "attachment; filename=testxls.xls");
OutputStream outStream = response.getOutputStream();
outStream.write(outArray);
outStream.flush();
%>
【讨论】:
但是这个例子仍然是 HSSF,即 .xls,而不是 OP 想要的 .xlsx 的 XSSF。您能强调一下这里的不同之处,以及您认为的不同之处吗? 基于this other answer,看起来重点是设置内容长度。【参考方案2】:我知道这是一个非常古老的(6 年),但我在更新一些旧代码以从 HSSF 移动到 XSSF 之后来到这里,我的问题是缺少 jar xmlbeans-3.1.0.jar。错误已写入 TomCat localhost 日志“java.lang.ClassNotFoundException: org.apache.xmlbeans.XmlObject”
【讨论】:
以上是关于Apache POI - 使用 XSSFWorkbok + servlet 响应的主要内容,如果未能解决你的问题,请参考以下文章