与Apache POI 3.8不可读的内容错误

我正在使用Apache POI 3.8。 我有一个生成Excel(.xslx)文件的JSP。 我在本地开发它,文件可以打开没有任何问题。 然后,我在开发环境中部署应用程序,当我打开生成的Excel文件时,出现一个警告框:“Excel在ausencias.xlsx中发现不可读的内容。是否要恢复此工作簿的内容?信任此工作簿的来源,请单击“是”。 如果单击是,则出现以下警报:“无法使用Microsoft Excel打开此文件。是否要在Microsoft Office Online网站上search可打开该文件的转换器? 如果我单击否,该文件正确打开。 但我不知道为什么我会得到这些错误。

即使我生成一个简单的空的.xslx文件,也是如此:

<%@page import="java.io.FileOutputStream"%> <%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@page import="java.io.IOException"%> <%@page import="javax.servlet.*"%> <%@page import="org.apache.poi.ss.usermodel.*"%> <%@page import="org.apache.poi.ss.util.CellRangeAddress"%> <%@page import="org.apache.poi.xssf.usermodel.*"%> <% response.setHeader ("Content-Disposition", "attachment;filename=\"ausencias.xlsx\""); response.setContentType("application/vnd.ms-excel"); Workbook wb = new XSSFWorkbook(); Sheet sheet = wb.createSheet("Ausencias"); ServletOutputStream fout = response.getOutputStream(); wb.write(fout); fout.flush(); fout.close(); %> 

在本地机器上,我有Microsoft Office Excel 2007(12.0.6661.5000)SP2 MSO(12.0.6562.5003)在Dev环境中,我有Microsoft Office Excel 2007(12.0.6611.1000)SP3 MSO(12.0.6607.1000)

有谁知道解决scheme或解决方法?

谢谢。

编辑:我已经添加了整个JSP代码。 我知道有些import可能不会用, 当我裁剪我寻找问题的原始代码时,我只是把它们留在那里。

编辑2:我已经在我的本地机器中开发了在开发环境中生成的文件,并引发相同的警告。 所以问题出在文件中,而不是在Excel版本中。 似乎有些东西是篡改Dev Env中的文件。 有任何想法吗??

你得到这个错误的原因是因为MIMEtypes是错误的。 代替

“应用程序/ vnd.ms-EXCEL”

你需要使用

“应用程序/ vnd.openxmlformats-officedocument.spreadsheetml.sheet”

为XLSX文件

我发现每当发送一个二进制文件作为一个http响应,你应该总是设置内容的长度。 尽pipe有时候你可以不用设置长度而离开,但是浏览器通常无法可靠地自动计算出文件的长度。

通常,我这样做的方式是首先将我的输出文件写入ByteArrayOutputStream。 这让我计算输出文件有多大。 然后,我将ByteArrayOutputStream字节写入响应对象。

下面是一个基于你原来的代码的例子:

  // generate the xlsx file as a byte array Workbook wb = new XSSFWorkbook(); Sheet sheet = wb.createSheet("Ausencias"); ByteArrayOutputStream bout = new ByteArrayOutputStream(); wb.write(bout); bout.close(); // send byte array as response response.setHeader ("Content-Disposition", "attachment;filename=\"ausencias.xlsx\""); response.setContentType("application/vnd.ms-excel"); response.setContentLength(bout.size()); ServletOutputStream fout = response.getOutputStream(); fout.write(bout.toByteArray()); fout.flush(); fout.close(); 

这是我解决它的方式:

 String name = "Name_of_file.xlsx"; ByteArrayOutputStream bout = new ByteArrayOutputStream(); workbook.write(bout); bout.close(); response.setHeader("Set-Cookie", "fileDownload=true; path=/"); response.setHeader("Content-Disposition", "attachment; filename=" + name); response.setContentLength(bout.size()); ServletOutputStream out = response.getOutputStream(); out.write(bout.toByteArray()); out.flush(); out.close(); 

我认为与其他答案的区别是,我没有使用response.setContentType指令,我不知道它的工作原因是什么…但它的工作。 没有更多的“Excel发现不可读的内容…”消息。