我们有一个预先创建的 Excel 文件,其中包含交叉引用工作表的精美图表和公式。它还包含宏。源数据应该被复制粘贴到一张纸中,工作簿的其余部分从预先存在的接线中填充。
注意:我真的不关心阅读/修改此工作簿中的其他工作表,我只需要节省每次将原始数据复制粘贴到此工作簿中的此数据表的痛苦。
我正在使用 Apache POI 并尝试从这个“模板”excel 文件创建一个 XSSFWorkbook 实例。但是,构建此对象需要很长时间(在多次运行中几乎持续一分钟)。excel文件本身只有400KB左右,不是一个大文件。我使用 jconsole 对此进行了分析,它似乎不受 CPU 或堆的限制 - 它仅使用大约 90 MB 堆内存(我用 2GB 提交的堆启动它)和大约 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,然后重用相同的句柄为每个后续请求写入新数据——我在我的主类中用睡眠和永远模拟了这个。但我显然不能这样做,我得到了一个异常“线程“主”org.apache.xmlbeans.impl.values.XmlValueDisconnectedException中的异常”。TEMPLATE_WORKBOOK 对象不可重用。
我确实看到有一个基于事件的 API,但在我进入它之前,我想看看我是否在这里遗漏了一些东西!再说一次,内存/CPU 在这里不是问题,我们有足够的可用堆空间。我正在努力减少时间。
PS:我在这里尝试了提示:XSSFWorkbook 需要很长时间才能加载——它们对启动时间没有帮助。