我们要求将上传的电子表格存储在Oracle数据库blob列中。 用户将使用ADF UI上传电子表格,同一电子表格将保留到数据库并稍后检索。 我们正在使用POI处理电子表格。 上传的文件将转换为byte []并发送到appserver。 Appserver对blob列保持不变。 但是当我试图稍后检索相同内容时,我看到“Excel在*****中找到了不可读的内容.xlsx。你想要恢复这个工作簿的内容吗?”信息。 我可以解决这个问题 将byte []转换为XSSFWorkbook并将其转换回byte []并将其保留。 但根据我的要求,我可能会得到非常大的电子表格,初始化XSSFWorkbook可能会导致内存问题。 从上传的电子表格中获取byte []的代码如下所示
if (uploadedFile != null) {
InputStream inputStream;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
inputStream = uploadedFile.getInputStream();
int c = 0;
while (c != -1) {
c = inputStream.read();
byteArrayOutputStream.write((char) c);
}
bytes = byteArrayOutputStream.toByteArray();
}
并且相同的byte []被持久化到blob列中,如下所示。 1.将此字节[]分配给BlobCloumn 2.使用bolobColumn更新SQL Update语句 3.执行声明。
完成上述步骤后,按如下方式检索电子表格。 1.阅读BlobColumn 2.从BlobColumn中获取bytes [] 3.设置响应的内容类型以支持电子表格。 4.发送字节[]。
但是,当我打开上面下载的电子表格时,我收到电子表格损坏的错误。
如果我在从UI接收到byte []后引入了如下的附加步骤,则问题就解决了。
InputStream is = new ByteArrayInputStream(uploadedSpreadSheetBytes);
XSSFWorkbook uploadedWorkbook = new XSSFWorkbook(is);
然后,再从XSSFWorkbook中导出byte [],如下所示
byteArrayOutputStream = new ByteArrayOutputStream();
workbook.write(byteArrayOutputStream);
byte[] spreadSheetBytes = byteArrayOutputStream.toByteArray();
我觉得将byte []转换为XSSFWorkbook,然后将XSSFWorkbook转换回byte []是多余的。
任何帮助将不胜感激。 感谢。
答案 0 :(得分:0)
使用基于事件的解析(SAX),而不是初始化整个XSSFWorkbook,可以避免内存问题。这样,您只处理文件中消耗较少内存的部分。有关SAX解析的更多信息,请参阅the POI spreadsheet how-to page。 你也可以增加JVM内存,但当然不能保证。