如何使用 Apache POI 通过 Google App Engine 读取电子表格?

How to use Apache POI to read spreadsheets with Google App Engine?

我一直在使用 JXL 处理 webapp 文件夹中的 excel 文件。这适用于开发和生产。我只是注入一个 ServletContext 并调用类似的东西:

Workbook.getWorkbook(new File(servletContext.getRealPath("WEB-INF/myfile.xls"))) 并且 JXL 可以读取文件并处理它。

我最近切换到在 App Engine Servlet 中使用 Apache POI,但出现异常:

[ERROR] java.security.AccessControlException: access denied ("java.io.FilePermission" "C:\Users\Drew\IntelliJ\UsavApp\target\UsavAppV7-1.0-SNAPSHOT\WEB-INF\myfile.xlsx" "write")
[ERROR]     at java.security.AccessControlContext.checkPermission(AccessControlContext.java:372)
[ERROR]     at java.security.AccessController.checkPermission(AccessController.java:559)
[ERROR]     at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
[ERROR]     at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:429)
[ERROR]     at java.lang.SecurityManager.checkWrite(SecurityManager.java:979)
[ERROR]     at java.io.RandomAccessFile.<init>(RandomAccessFile.java:229)
[ERROR]     at org.apache.poi.poifs.nio.FileBackedDataSource.newSrcFile(FileBackedDataSource.java:130)
[ERROR]     at org.apache.poi.poifs.nio.FileBackedDataSource.<init>(FileBackedDataSource.java:46)
[ERROR]     at org.apache.poi.poifs.filesystem.NPOIFSFileSystem.<init>(NPOIFSFileSystem.java:218)
[ERROR]     at org.apache.poi.poifs.filesystem.NPOIFSFileSystem.<init>(NPOIFSFileSystem.java:166)
[ERROR]     at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:278)
[ERROR]     at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:250)
[ERROR]     at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:229)
[ERROR]     at com.utilitiessavings.usavappv7.server.handler.parse.ParseElecTariffBooksHandler.processTariffsFromExcel(ParseElecTariffBooksHandler.java:108)
[ERROR]     at com.utilitiessavings.usavappv7.server.handler.parse.ParseElecTariffBooksHandler.execute(ParseElecTariffBooksHandler.java:91)
[ERROR]     at com.utilitiessavings.usavappv7.server.handler.parse.ParseElecTariffBooksHandler.execute(ParseElecTariffBooksHandler.java:39)
...etc

通过阅读我了解到 POI 与 GAE 并不完全兼容,但大多数人谈论从头开始创建文件,或将它们写入本地磁盘。我没有做任何一个,所以我想确定这是 App Engine 的限制,而不是我正在做的事情。

我对异常的猜测是 POI 甚至需要写入权限才能读取文件,而 JXL 则不需要。 有没有办法使用 Apache POI 在 App Engine 中读取电子表格?

提升对答案的评论 - 在这种情况下,您应该明确告诉 Apache POI 在 read-only 模式下打开您的文件

对于 .xlsx 文件,使用

OPCPackage pkg = OPCPackage.open(new File("input.xlsx"), PackageAccess.READ);
XSSFWorkbook wb = new XSSFWorkbook(pkg);

对于 .xls 文件,使用

NPOIFSFileSystem fs = new NPOIFSFileSystem(new File("input.xls"), true);
HSSFWorkbook wb = new HSSFWorkbook(fs);

如果您使用的是 WorkbookFactory,那么您可以通过传入 null 作为密码并传入 setting the read-only flag

来做到这一点
Workbook wb = WorkbookFactory.create(new File("input.xlsx"), null, true);

一般来说,从 InputStream 中读取总是 read-only,它与文件一起读取 read-only 与 read-write

也看到 constructor javadocs for a little bit more details, and the WorkbookFactory 一个。