19

我可以使用 apache poi 创建一个 excel 文件。但是,我希望用户能够将其下载为“真正的”excel 文件。我想要达到的效果是有一个弹出框允许用户下载文件。这类似于使用

<%@ page contentType="application/vnd.ms-excel" pageEncoding="ISO-8859-1"%> 
<%response.setHeader("Content-Disposition", "attachment;filename=myfile.xls"); %>

有一个严重的例外:我必须允许用户下载正确的 excel 文件。我在某处读到上面的代码只是对客户端说服务器正在发送一个 excel 文件

4

3 回答 3

40

在普通的 servlet 而不是 JSP 文件中完成这项工作。JSP 文件用于动态生成 HTML 代码,并且为此使用字符编写器而不是二进制输出流,因此只会损坏 POI 生成的 Excel 文件,该文件本质上是二进制流。

所以,基本上你在doGet()servlet 的方法中需要做的事情如下:

response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=filename.xls");
HSSFWorkbook workbook = new HSSFWorkbook();
// ...
// Now populate workbook the usual way.
// ...
workbook.write(response.getOutputStream()); // Write workbook to response.
workbook.close();

现在,要下载它,请通过其 URL 而不是 JSP 文件调用 servlet。

于 2012-06-27T13:27:35.230 回答
21

虽然使用 servlet 而不是 jsp 编写二进制附件确实更常见,但从 jsp 编写二进制附件当然是可能的。这样做的好处是您不必担心配置 web.xml 或重新加载您的应用程序。这可能是一个重要的考虑因素,具体取决于您的 Web 服务器环境。

这是一个使用 poi 将二进制附件发送到浏览器的示例 jsp。

<%@page import="org.apache.poi.hssf.usermodel.*" %><%@page import="java.io.*" %><%

// create a small spreadsheet
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell(0);
cell.setCellValue("Some text");

// write it as an excel attachment
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();

%>

重要的技巧是确保在开始代码的“<%”之前只有一行包含所有导入和其他指令。否则,jsp 可能会输出一些初始的新行并破坏您的输出。

另外,我建议您始终设置内容长度。如果未设置,某些浏览器将无法正常工作。这就是为什么我首先将电子表格输出到一个字节数组,这样我就可以在实际发送数据之前设置长度。

于 2012-06-28T16:31:53.250 回答
0

如果你想下载不要使用 hssf 工作簿,它会变慢并消耗更多空间使用 apche poi 3.17 beta-1

SXSSFWorkbook workbook = new SXSSFWorkbook(100); 
workbook.setCompressTempFiles(true);
Sheet sh = workbook.createSheet();
//write your data on sheet

//below code will download file in browser default download folder
response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment; filename="+filename+".xlsx");
            workbook.write(response.getOutputStream());
            workbook.close();
            workbook.dispose();

对于 Pdf 使用 Itext

     Document document = new Document();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            PdfWriter.getInstance(document, baos);
            document.open(); 
//write your code

 document.add("content");
            document.close();
            response.setHeader("Expires", "0");
            response.setHeader("Cache-Control","must-revalidate, post-check=0, pre-check=0");
            response.setHeader("Pragma", "public");
            response.setContentType("application/pdf");
            response.addHeader("Content-Disposition", "attachment; filename="+filename+".pdf");
            response.setContentLength(baos.size());
            OutputStream os = response.getOutputStream();
            baos.writeTo(os);
            os.flush();
            os.close();
于 2017-11-03T13:34:26.493 回答