【发布时间】:2017-02-17 16:58:50
【问题描述】:
我们需要将上传的电子表格存储在 Oracle 数据库 blob 列中。 用户将使用 ADF UI 上传电子表格,并且相同的电子表格将保存到数据库并稍后检索。 我们正在使用 POI 来处理电子表格。 上传的文件被转换为 byte[] 并发送到 appserver。 Appserver 将相同的内容保存到 blob 列。 但是当我稍后尝试检索相同内容时,我看到“Excel 在 *****.xlsx 中发现不可读的内容。你想恢复此工作簿的内容吗?”信息。 我可以通过 将 byte[] 转换为 XSSFWorkbook 并将其转换回 byte[] 并将其持久化。 但根据我的要求,我可能会得到非常大的电子表格,初始化 XSSFWorkbook 可能会导致内存不足问题。 从上传的电子表格中获取字节[]的代码如下
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. 将此 byte[] 分配给 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[] 是多余的。
任何帮助将不胜感激。 谢谢。
【问题讨论】:
-
某处引入了损坏,但不清楚您的进程是什么。你能一步一步把它拼出来,然后告诉我们错误发生在哪里吗?包括有关如何保存电子表格以及通过哪个过程保存的细节。转换也是如此:你是如何做到的,以及正在做的过程。我最初的想法是 POI 写入
OutputStream,也许ByteArrayOutputStream可以与toString()一起使用。
标签: java apache-poi blob