Oracle Blob到XLS工作表

编辑:解决。 我通过写一个jdbc连接器到数据库,获得blob,并将其转储到一个文件,从而绕过了ibatis / ApachePOI。 有一天,我想知道为什么它会搞砸 – 但今天我很高兴有这个在我身后。

简介:我正在获取Oracle blob,并使用Apache POI来重buildExcel二进制文件以通过SOAP服务层。 .Net客户端将这些文件写入.xls文件中,但写入UNIX目录时会损坏文件。

详细信息:我有存储在oracle表中的Excel blob。 这些blob是使用iBatis编写的,并使用这个(截断的)结果地图来拉取。

<resultMap id="report" class="Report"> <result column="content" property ="content" typeHandler="BlobByteArrayTypeHandler"/> 

excel报告是由我们的Java服务使用Apache.POI生成的。 目前,我们的客户端(.net)查询服务的字节数组,这是写入一个Wi​​ndows机器没有错误 – 只是转储字节到一个文件。

这些excel文件就好了。

我遇到的问题是我们有一个新的要求,我们应该将这些文件写入到UNIX文件系统中,以便进一步处理。

所有的尝试都失败了。 以下是一些代码示例:

 private void writeReportDumpBytes(Report report) { File file = new File("report.xls"); FileOutputStream fileOutputStream; try { fileOutputStream = new FileOutputStream(file); fileOutputStream.write(report.getContent()); fileOutputStream.flush(); fileOutputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private void writeReportWithEncoding(Report report, String encoding) { File file = new File("Report.xls"); FileOutputStream fileOutputStream; try { fileOutputStream = new FileOutputStream(file); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, encoding); Writer out = new BufferedWriter(outputStreamWriter); String reportBytes = new String(report.getContent()); out.write(reportBytes.toCharArray()); out.flush(); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public void writeReportHssfPoifileSystem(Report report) { try { InputStream byteStream = new ByteArrayInputStream(report.getContent()); POIFSFileSystem fs = new POIFSFileSystem(byteStream); HSSFWorkbook workbook = new HSSFWorkbook(fs); FileOutputStream fileOut = new FileOutputStream("Report.xls"); workbook.write(fileOut); fileOut.flush(); fileOut.close(); } catch (IOException e) { log.error(e.getMessage(), e); } } private void writeReportApacheIO(Report report) { File file = new File("Report.xls"); try { logReportBytes(report, "Apache IO"); FileUtils.writeByteArrayToFile(file, report.getContent()); } catch (IOException e) { log.error("Caught IOException", e); } } 

为了诊断这一点,我试图从Oracle抓取blob,并将其保存到文件。 在一个简单的jar可执行文件中,我已经能够读取这个文件中的字节,并使用上面的方法在我们的UNIX机器上重写它们,并且它们都可以工作。

但是,从我们的代码中,excel文件全部损坏,或者缺less来自Apache.POI的标题信息。 在文本编辑器中打开损坏/错误的二进制文件显示64字节的重复模式。 这不是一个有效的xls二进制文件。

有东西在旁边。 blob是一个有效的xls二进制文件,我们只是获取字节(使用上面的iBatis)并通过一个HSSFWorkbook对象传递回来,然后尝试使用这些方法进行编写。

  /** * Return the byte array based on the workbook. * * @return * @throws IOException */ public byte[] getContent() throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); this.workBook.write(bos); return bos.toByteArray(); } 

我在使用Apache POI时遇到的具体错误是:

 java.io.IOException: block[ 0 ] already removed at org.apache.poi.poifs.storage.BlockListImpl.remove(BlockListImpl.java:97) at org.apache.poi.poifs.storage.BlockAllocationTableReader.fetchBlocks(BlockAllocationTableReader.java:190) at org.apache.poi.poifs.storage.BlockListImpl.fetchBlocks(BlockListImpl.java:130) at org.apache.poi.poifs.property.PropertyTable.<init>(PropertyTable.java:79) at org.apache.poi.poifs.filesystem.POIFSFileSystem.<init>(POIFSFileSystem.java:171) 

我直接写了一个jdbc调用数据库,忽略了所有的ibatis和apache poi的废话。 使用各种磁盘写入方法工作得很好。