【问题标题】:Not able to read xlsx file saved in postgres database (as bytea) using apache POI无法使用 apache POI 读取保存在 postgres 数据库(作为 bytea)中的 xlsx 文件
【发布时间】:2015-01-13 18:17:06
【问题描述】:

我正在使用 apache POI 读取 xlsx 文件并上传数据库中的数据。我必须在 Jboss 上运行的调度程序(在预定时间)中完成这项工作。由于调度程序与上传的一个文件在不同的服务器上运行,我使用 postgres bytea 数据类型使用以下代码将文件保存在数据库中 PreparedStatement ps = con.prepareStatement("UPDATE tk_tablename SET tk_filecolumnname = ? WHERE primarykey = '" + fileAttachment.getPrimaryKey() + "';" );

FilePathAssociation filePathAssociation = fileAttachment.getFilePathAssociation();

if ( filePathAssociation != null )

{

File blobFile = new File( filePathAssociation.getPhysicalFilePath() );
   FileInputStream fis = new FileInputStream( blobFile );
   ps.setBinaryStream( 1, fis, (int)blobFile.length() );
   ps.executeUpdate();
   ps.close();
   fis.close();
}

一切正常,文件已保存在数据库中。

但是在使用下面的代码读取服务器上的文件时

ResultSet rs =
                        stmt.executeQuery( "SELECT tk_filecolumnname FROM tk_tablename WHERE primarykey = '"
                            + fileAttachment.getPrimaryKey() + "';" );
                    if ( rs != null && rs.next() )
                    {
                        InputStream fileInputStream = rs.getBinaryStream( 1 );
                        Workbook workbook = WorkbookFactory.create( fileInputStream ); // apache POI code to read a xlsx file.
                        rs.close();
                        return file;
                    }

它给出以下错误,

java.lang.IllegalArgumentException: Your InputStream was neither an OLE2 stream, nor an OOXML stream

我知道要读取 xlsx 文件,POI 需要由 OOXML 支持的流。但是为什么

ResultSet.getBinaryStream()

方法返回的输入流与创建文件时保存的输入流不同。

请帮助或分享您的知识。

谢谢, 阿米特。

【问题讨论】:

  • 读取数据很可能不会返回 same 输入流(实例),尤其是。因为在 db 中没有关于使用哪个流的数据(它只是二进制文件数据)。

标签: java apache-poi


【解决方案1】:

执行以下操作:

1) 断言您的代码正在从文件中正确读取工作簿(只需打开 FileInputStream)。

2) 一旦您的代码处理的是文件,而不是来自数据库的流,它可能与库处理流的方式有关。您可以尝试将整个流保存到临时文件中,还有什么好处,您可以更快地释放数据库连接。

【讨论】:

    【解决方案2】:

    1.您可能正在使用 postgres 9.0。在 postgres 9.0 中,bytea 的默认值为十六进制。准备好的语句中的简单 setByte 不起作用。一种解决方法是编辑 postgresql.conf

    bytea_output = '转义'

    升级您的 jdbc 驱动程序也可能会解决此问题,但尚未尝试。

    2.尝试使用 oid。这是为了将大文件存储到您的数据库中。 您可以在这里找到更多信息。 http://jdbc.postgresql.org/documentation/80/binary-data.html

    Java API 可以找到http://jdbc.postgresql.org/documentation/publicapi/org/postgresql/largeobject/LargeObjectManager.html

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题(PostgreSQL 配置级别的建议更改或选择新驱动程序不起作用),现在只是通过使用将从 PostgreSQL DB 读取的输入流包装到缓冲输入流中来解决它

      import org.apache.commons.io.IOUtils;
      
      IOUtils.toBufferedInputStream(file.getBinaryStream()));
      

      希望这会有所帮助!

      问候,

      尼科·维滕贝克

      【讨论】:

        【解决方案4】:

        确保您的类路径未被 Maven 过滤。 这篇文章解决了同样的问题:https://stackoverflow.com/a/13969688/704246

        【讨论】:

          猜你喜欢
          • 2013-03-11
          • 1970-01-01
          • 2018-01-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多