POI的WorkBook.getBytes()方法不友好
最近在项目里用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()方法理解为是获得整个文档的字节数组了,呵呵,看来犯错的人不止我一个。
?