使用Spring-batch-excel读取Excel时出错

时间:2015-11-20 08:38:13

标签: java excel spring spring-batch

我使用Spring-batch-excel在我的新应用程序中读取excel文件。它被配置为批处理作业并使用JobManager触发。现在我收到了这个错误。 InputStream必须支持标记/重置,或者包装为PushbackInputStream

Caused by: java.lang.IllegalStateException: InputStream MUST either support mark/reset, or be wrapped as a PushbackInputStream
at org.springframework.batch.item.excel.poi.PoiItemReader.openExcelFile(PoiItemReader.java:82) ~[spring-batch-excel-0.5.0-SNAPSHOT.jar:?]
at org.springframework.batch.item.excel.AbstractExcelItemReader.doOpen(AbstractExcelItemReader.java:111) ~[spring-batch-excel-0.5.0-SNAPSHOT.jar:?]
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:144) ~[spring-batch-infrastructure-3.0.5.RELEASE.jar:3.0.5.RELEASE].

请帮助我。

5 个答案:

答案 0 :(得分:4)

老问题,我相信你已经明白了,但我觉得目前的答案是无益的,所以... ...

您使用的Resource可能是一个问题。大多数spring-batch-excel示例都使用ClassPathResource。当您尝试生成代码时,您可能需要访问类路径之外的文件。显而易见的选择是FileSystemResource,但这将导致此异常。相反,请查看UrlResource

答案 1 :(得分:2)

如@Thrax所述, spring-batch-excel 期望在PushbackInputStream中找到一个Resource。这是我在文件系统上使用文件时针对此问题的解决方案:

我使用命令行--input.file上的输入文件创建阅读器

@Bean
public PoiItemReader excelReader(@Value("${input.file}") String inputFile) throws FileNotFoundException {
    PoiItemReader reader = new PoiItemReader();
    PushbackInputStream input = new PushbackInputStream(new FileInputStream(inputFile));
    InputStreamResource resource = new InputStreamResource(input);
    reader.setResource(resource);
    reader.setRowMapper(rowMapper());
    return reader;
}

希望对您有帮助。

答案 2 :(得分:1)

spring-batch-excel来源看:

@Override
protected void openExcelFile(final Resource resource) throws Exception {
    workbookStream = resource.getInputStream();
    if (!workbookStream.markSupported() && !(workbookStream instanceof PushbackInputStream)) {
        throw new IllegalStateException("InputStream MUST either support mark/reset, or be wrapped as a PushbackInputStream");
    }

    [...]
}

如果InputStream不支持回读,则抛出此异常。 InputStream取决于您的Resource,因此我的结论是您的资源不是有效的XLS / XLSX文件。

答案 3 :(得分:1)

我知道这是一个老问题,但我遇到了这个问题,但对于那些像我一样有问题的人,我已经注释掉了这段代码并且它有效了

if (!workbookStream.markSupported() && !(workbookStream instanceof PushbackInputStream)) {
        throw new IllegalStateException("InputStream MUST either support mark/reset, or be wrapped as a PushbackInputStream");
    }

了解原因请参考此代码: https://github.com/spring-projects/spring-batch-extensions/issues/34

答案 4 :(得分:0)

我今天遇到了这个问题。解决方案是从磁盘而不是从类路径加载文件。有趣的是,在我们的本地Windows环境中,从classpath加载工作正常,但不是在DEV Unix环境中(我相信@Andy Sampson暗示这一点)。在我们的例子中,我们通过类似于' classpath的前缀来指定要加载的excel的位置:'或者'文件:'在URL查询参数中。因此我们所要做的就是将文件放在与正在运行的应用程序相同的服务器上的某个路径中,然后将URL查询参数更新为如下位置:

http://some.host.com?location=file:/absolute/path/to/excel/file

瞧,瞧。在内部我们使用Spring ResourceLoader,它只不过是Spring ApplicationContext。我们只需要通过我们的excel加载类/ Spring @Service实现Spring的ResourceLoaderAware来引用该ResourceLoader,它可以理解类路径:'和'档案:'前缀。