Java 使用zip中的POI生成xlsx文件

Java 使用zip中的POI生成xlsx文件,java,excel,struts2,Java,Excel,Struts2,我用POI Api导出xlsx文件中的数据,并将它们添加到Zip文件中。当我打开zip时,我没有任何xlsx文件,只有三个目录(docProps、xl和_rels)和一个文件[Content_Types]xml。我想这是xlsx文件的描述,但我不明白为什么 代码: public InputStream exportXlsx(List<MyObject> listeOfObject) throws IOException { ByteArrayOutputStream

我用POI Api导出xlsx文件中的数据,并将它们添加到Zip文件中。当我打开zip时,我没有任何xlsx文件,只有三个目录(docProps、xl和_rels)和一个文件[Content_Types]xml。我想这是xlsx文件的描述,但我不明白为什么

代码:

public InputStream exportXlsx(List<MyObject> listeOfObject) throws IOException {

        ByteArrayOutputStream excelOutputStreamZip = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(excelOutputStreamZip);

        for (MyObject myObject : listeOfObject) {

            XSSFWorkbook wb = new XSSFWorkbook();
            XSSFSheet wsheet = wb.createSheet("mySheet");
            XSSFRow row = wsheet.createRow(0);
            XSSFCell cell = row.createCell(1);
            cell.setCellValue(myObject.getValue1());

            // Create all sheet and cell....

            // Write WB conntent in outputStream
            wb.write(excelOutputStreamZip);

            addEntry(zip, myObject.getFileName(), excelOutputStreamZip);
        }

        InputStream inputStreamZipByte = new ByteArrayInputStream(
                ((ByteArrayOutputStream) excelOutputStreamZip).toByteArray());
        zip.close();

        return inputStreamZipByte;

    }

    public void addEntry(OutputStream zip, String filename, ByteArrayOutputStream os) {

        byte[] bytes = os.toByteArray();

        ZipEntry entry = new ZipEntry(filename);
        Date d = new Date();
        entry.setTime(d.getTime());
        try {
            ((ZipOutputStream) zip).putNextEntry(entry);
            ((ZipOutputStream) zip).write(bytes);
            ((ZipOutputStream) zip).closeEntry();
        } catch (IOException e) {
            log.error("Can't read the file !", e);
        } catch (ClassCastException cce) {
            log.error("Bad format !", cce);
        }

    }
public InputStream exportXlsx(List listofObject)引发IOException{
ByteArrayOutputStream excelOutputStreamZip=新建ByteArrayOutputStream();
ZipOutputStream zip=新ZipOutputStream(excelOutputStreamZip);
用于(MyObject MyObject:ListoObject){
XSSF工作簿wb=新XSSF工作簿();
XSSFSheet wsheet=wb.createSheet(“mySheet”);
XSSFRow row=wsheet.createRow(0);
XSSFCell cell=row.createCell(1);
cell.setCellValue(myObject.getValue1());
//创建所有工作表和单元格。。。。
//在outputStream中写入WB连接
wb.write(excelOutputStreamZip);
addEntry(zip,myObject.getFileName(),excelOutputStreamZip);
}
InputStream inputStreamZipByte=新的ByteArrayInputStream(
((ByteArrayOutputStream)excelOutputStreamZip.toByteArray());
zip.close();
返回输入流ZipByte;
}
public void addEntry(OutputStream zip、字符串文件名、ByteArrayOutputStream os){
byte[]bytes=os.toByteArray();
ZipEntry条目=新ZipEntry(文件名);
日期d=新日期();
setTime(d.getTime());
试一试{
(ZipOutputStream)zip.putNextEntry(条目);
((ZipOutputStream)zip)。写入(字节);
((ZipOutputStream)zip).closeEntry();
}捕获(IOE异常){
log.error(“无法读取文件!”,e);
}捕获(ClassCastException cce){
log.error(“格式错误!”,cce);
}
}
此代码是在一个服务中编写的,该服务被注入Struts2操作

struts.xml:

<action name="*MyAction" class="com.omb.view.action.myAction" method="{1}">
    <result name="export" type="stream">
        <param name="contentType">application/zip</param>
        <param name="inputName">inputStreamZipByte</param>
        <param name="contentDisposition">attachment;filename="myZip.zip"</param> 
        <param name="bufferSize">1024</param>
    </result>
</action>

应用程序/zip
输入流字节
附件filename=“myZip.zip”
1024

xlsx文件是一个zip文件。您应该检查适合结果的
contentType
参数的MIME类型。请参见

我找到了解决方案的一部分,但现在我遇到了另一个问题:

inital post的问题在于流的处理。因为我对Zip和工作簿使用了相同的outputStream。为每个工作簿创建了一个新的ByteArrayOutpuStream解决方案

// Write WB conntent in outputStream    
ByteArrayOutputStream wbOutputStream = new ByteArrayOutputStream();  
wb.write(wbOutputStream);    
addEntry(zip, myObject.getFileName(), wbOutputStream);    
wbOutputStream.close();

但是…现在生成的Zip文件已损坏…

只需将工作簿写入BytearrayInputStream,然后转换为字节数组 在ZipOutPutStream中使用该字节数组

这个对我有用

response.setContentType(“应用程序/zip”)

response.setHeader(“内容处置”、“附件;文件名=\”“+filename+”.zip\”)

工作簿=获取工作簿(显示列表,cfgType)

ByteArrayOutputStream bas=新的ByteArrayOutputStream()

ZipOutputStream zos=新ZipOutputStream(BAS)

ByteArrayOutputStream fileBaos=new>ByteArrayOutputStream()

zos.putNextEntry(新ZipEntry(“Test.xlsx”)

工作簿.编写(fileBaos)

write(fileBaos.toByteArray())

zos.putNextEntry(新ZipEntry(“Test1.xlsx”)

write(fileBaos.toByteArray())

fileBaos.close(); zos.close()

response.getOutputStream().write(baos.toByteArray()); response.flushBuffer()


好的,谢谢你的帮助。我试图生成一组xlsx文件,并将它们放在一个zip文件中,由用户下载。那么我应该在struts2配置文件中更改contentType吗?即使你想要一个zip文件?如果你想在Struts2的zip中动态添加多个文件(xls、xlsx等),这可能会有所帮助。谢谢你,Andrea,我解决了这篇文章的问题。我在使用JSF和Spring时也会遇到同样的错误,我也不明白为什么