0

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

即使我生成一个简单的空 .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) 在开发环境中,我有 Microsoft Office Excel 2007 (12.0.6611.1000) SP3 MSO (12.0.6607.1000)

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

谢谢。

编辑:我已经添加了整个 JSP 代码。我知道有些进口商品可能无法使用;当我裁剪原始代码以查找问题时,我只是将它们留在那里。

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

4

3 回答 3

2

the reason you are getting this error is because the MIME type is wrong. instead of

"application/vnd.ms-excel"

you need to use

"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

for XLSX documents

于 2012-10-19T01:19:00.267 回答
2

我发现每当将二进制文件作为 http 响应发回时,您都应该始终设置内容长度。尽管有时您可以在不设置长度的情况下逃脱,但浏览器通常无法可靠地自动确定文件的长度。

通常,我这样做的方式是首先将我的输出文件写入 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();
于 2012-06-12T06:08:24.533 回答
0

这是我解决它的方式:

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 发现无法读取的内容...”消息。

于 2016-09-20T13:06:00.783 回答