2008-07-24

POI的WorkBook.getBytes()方法不友好

关键字: poi

最近在项目里用POI处理Excel,看了一下例子,跟以前用的jxl差不多,但是生成的Excel文件用office 2007打开老是抱错,本以为是office 2007兼容性问题,但在网上没有找到相关信息;后来才发现是代码写得有问题……;为了使用struts2的文件下载功能,处理数据流时,就直接使用了WorkBook.getBytes()方法构造一个ByteArrayInputStream,这是问题的根源。仔细看了看API和源码才知道WorkBook提供的getBytes()和write()方法的差别:

public void write(OutputStream stream)
            throws IOException
    {
        byte[] bytes = getBytes();
        POIFSFileSystem fs = new POIFSFileSystem();

        // For tracking what we've written out, used if we're
        //  going to be preserving nodes
        List excepts = new ArrayList(1);

        // Write out the Workbook stream
        fs.createDocument(new ByteArrayInputStream(bytes), "Workbook");

        // Write out our HPFS properties, if we have them
        writeProperties(fs, excepts);

        if (preserveNodes) {
            // Don't write out the old Workbook, we'll be doing our new one
            excepts.add("Workbook");
            // If the file had WORKBOOK instead of Workbook, we'll write it
            //  out correctly shortly, so don't include the old one
            excepts.add("WORKBOOK");

            // Copy over all the other nodes to our new poifs
            copyNodes(this.filesystem,fs,excepts);
        }
        fs.writeFilesystem(stream);
        //poifs.writeFilesystem(stream);
    }

如果直接使用getBytes()方法,需自己处理POIFS,否则文档结构是不符合要求的;为了绕开这个点,可以用以下方式处理:

ByteArrayOutputStream os = new ByteArrayOutputStream();
workBook.write(os);

//ByteArrayInputStream is = new ByteArrayInputStream(workBook.getBytes());
ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());

搞笑的是在POI的bug列表 里发现了有人跟我一样误将getBytes()方法理解为是获得整个文档的字节数组了,呵呵,看来犯错的人不止我一个。

 

评论
发表评论

您还没有登录,请登录后发表评论

numenzq
搜索本博客
存档
最新评论