java - Apache POI SXSSFWorkbook无法创建工作表

时间:2015-03-26 17:28:37

标签: java excel apache-poi

在我的项目中一个更大的代码流程中,我正在尝试创建一个空白的SXSSFWorkbook并创建工作表并向其写入数据,但我无法为其提供运行时异常:没有这样的文件或目录。我不明白为什么会这样。我仔细检查了代码,找不到任何理由。

使用的罐子:

poi-3.10-FINAL.jar
poi-ooxml-3.10-FINAL.jar
  

java.lang.RuntimeException:java.io.IOException:没有这样的文件或目录     在org.apache.poi.xssf.streaming.SXSSFWorkbook.createAndRegisterSXSSFSheet(SXSSFWorkbook.java:568)     在org.apache.poi.xssf.streaming.SXSSFWorkbook.createSheet(SXSSFWorkbook.java:584)

代码:

csvDataWorkbook = new SXSSFWorkbook(-1);
Sheet sheet = csvDataWorkbook.createSheet("csvDataSheet");

上面的第二行抛出了异常。可能听起来很奇怪,但直到昨天仍然很好,但从今天开始就停止了。

的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <groupId>com.company</groupId>
    <artifactId>project</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>


    <dependencies>
        .......
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.10-FINAL</version>
        </dependency>


        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.10-FINAL</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.10-FINAL</version>
        </dependency>

        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>3.10-FINAL</version>
        </dependency>



    </dependencies>
</project>

3 个答案:

答案 0 :(得分:3)

在使用diff上下文运行集成测试期间,我遇到了确切的问题。

POI中存在错误。

当使用org.apache.poi.util.TempFile类保存时,SXSSF会创建一个临时文件。首次创建临时文件时,目录名称将保存在此类中的静态单例DefaultTempFileCreationStrategy对象中。此目录仅在第一次保存时创建,并在虚拟机退出时自动删除,并且从不检查该目录是否仍然存在。

public File createTempFile(String prefix, String suffix) throws IOException {
            // Identify and create our temp dir, if needed
            if (dir == null)
            {
                dir = new File(System.getProperty("java.io.tmpdir"), "poifiles");
                dir.mkdir();
                if (System.getProperty("poi.keep.tmp.files") == null)
                    dir.deleteOnExit();
            }

因此,如果您有两个应用程序同时加载和保存Excel,然后关闭一个,则会自动删除此目录。现在两个应用程序使用完全相同的临时目录。因此,如果您尝试将文件保存在仍处于打开状态的第二个应用程序中,则会在尝试在不再存在的目录中创建tmp文件时引发IOException。

有关详细信息,请检查Bug 57200 - 由于TempFile创建失败,SXSSF保存有时会失败

可能的解决方案:

  • 使用临时文件夹&#34; java.io.tmpdir&#34;而不是它的子文件夹&#34; poifiles&#34;。
  • 为每个进程使用唯一的临时文件夹名称,而不是&#34; poifiles&#34;。
  • 永远不要删除子文件夹&#34; poifiles&#34;。
  • 删除文件夹&#34; poifiles&#34;仅当用户明确地设置相应的系统属性时,例如, &#34; poi.delete.tmp.dirs&#34; (设置此属性还必​​须删除包含的临时文件,即使指定了&#34; poi.keep.tmp.files&#34;)。

我已修复它&#34;永远不会删除子文件夹。创建文件夹,不要使用dir.deleteOnExit();

File dir = new File(System.getProperty("java.io.tmpdir"),"poifiles");
dir.mkdir();
TempFile.setTempFileCreationStrategy(new TempFile.DefaultTempFileCreationStrategy(dir));

答案 1 :(得分:1)

如果您在Apache上运行它,请检查temp文件夹是否存在。

可以在tomcat bin文件夹里面的tomcat7w.exe中找到。

参考下图, http://i.stack.imgur.com/y6VGc.jpg

-Djava.io.tmpdir =

如果该选项不可用,请尝试创建它。

答案 2 :(得分:0)

如果你在同一台服务器上有几个jvm,我建议你使用版本3.12并指明你自己想要写的地方:

File generateTempDir = ...
//OR File generateTempDir = new File(System.getProperty("java.io.tmpdir"),"poifiles");
TempFile.setTempFileCreationStrategy(new TempFile.DefaultTempFileCreationStrategy(generateTempDir));

(或根据jvm设置java.io.tmpdir属性)