java - XSSFWorkbook 的构建对于 .xlsm 工作簿非常慢

标签 java apache-poi

我们有一个预先创建的 excel 文件,其中包含交叉引用工作表的精美图表和公式。它还包含宏。源数据应该复制粘贴到一张纸上,工作簿的其余部分从预先存在的布线中填充。

注意:我真的不关心阅读/修改这个工作簿中的其他表,我只需要省去每次复制粘贴原始数据到这个工作簿中的这个数据表的痛苦.

我正在使用 Apache POI 并尝试从这个"template"excel 文件创建一个 XSSFWorkbook 实例。但是,构建此对象需要很长时间(多次运行几乎一分钟)。 excel 文件本身只有 400KB 左右,不是一个大文件。我使用 jconsole 对此进行了概要分析,它似乎不受 CPU 或堆的限制——它仅使用大约 90 MB 堆内存(我用 2GB promise 堆启动它)和大约 52% 的 CPU。

用原始数据实际填充数据表并写出最终更新的文件需要很短的时间(大约 3-4 秒)。这是我的启动代码:

public static void startup() throws FileNotFoundException, IOException {
    long start = System.nanoTime();
    System.out.println("Started...");
    TEMPLATE_WORKBOOK = new XSSFWorkbook(new FileInputStream(new File(TEMPLATE)));
    long end = (System.nanoTime() - start) / NANOS;
    System.out.println("It took " + end + " seconds..");
}

我考虑过一次加载此 TEMPLATE_WORKBOOK,然后重复使用相同的句柄为每个后续请求写入新数据 - 我在我的主类中模拟了一个 sleep 和一个永远的时间。但我显然不能这样做,我得到一个异常“线程“主”org.apache.xmlbeans.impl.values.XmlValueDisconnectedException 中的异常”。 TEMPLATE_WORKBOOK 对象不可重复使用。

我确实看到有一个基于事件的 API,但在开始之前,我想看看我是否遗漏了什么!同样,内存/CPU 在这里不是问题,我们有足够的堆空间。我正在努力减少时间。

P.S:我试过这里的提示:XSSFWorkbook takes a lot of time to load - 它们对启动时间没有帮助。

最佳答案

我认为你对你想做的事处于不利地位。我遇到了同样的问题(请参阅 here),不幸的是,您的情况没有解决方案。

即使您想在数据表中恰到好处,唯一的方法就是将文件作为 XSSFWorkbook 打开,即使是在基于事件的 API 中也是如此。

SXSSFWorkbook 不能从 File、InputStream 或 OPCPackage 构造。您只能从头开始或从 XSSFWorkbook 构建它。

唯一真正weful 耗时的可能解决方案(我不知道是否可能)是尝试使用读取解析器输入数据,这意味着您应该自己将 excel 文件解析为 xml。

我们的最终解决方案是等待解决我们问题的解决方案。

很抱歉,您得不到想要的答案。

关于java - XSSFWorkbook 的构建对于 .xlsm 工作簿非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12091532/

相关文章:

java - 在 POI 中使用列索引

java - 从 sbt 程序集运行 uber jar 会导致错误 : Could not find or load main class

java - 从投影列表中获取子实体时出现间歇性惰性异常

java - 使用 Kerberos 设置 Spark SQL 连接

java - 如何从父类路径使用 CDI 托管 bean

java - Apache POI : changing CellType causes IllegalStateException

java - Apache POI 跳过从未更新过的行

java - 使用 JAVA 中的 JSOUP 和 Apache POI 将 HTML 表转换为 Excel

java - 使用 Java 或 ColdFusion 确定 *.doc 文件是否为 RTF 的最佳方法

java - SonarLint 此处使用原始 boolean 表达式