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

Getting Error while Reading Excel Using Spring-batch-excel

我正在使用 Spring-batch-excel 在我的新应用程序中读取 excel 文件。它被配置为批处理作业并使用 JobManager 触发。现在我收到这个错误。 InputStream 必须支持 mark/reset,或包装为 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].

任何人都请帮助我。

通过查看 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 文件。

老问题,我相信你已经弄明白了,但我发现当前的答案没有帮助,sooo...

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

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

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

我今天遇到了这个问题。解决方案是从磁盘而不是类路径加载文件。有趣的是,在我们的本地 Windows 环境中,从类路径加载工作正常,但在 Unix 环境中却不行。我怀疑打包在 JAR 中时 excel 文件中可能存在一些损坏。无论如何,我们在 URL 查询参数中指定要加载的 excel 文件的位置,前缀为 classpath: 以从 Java CLASSPATH 加载它,或者 file: 从磁盘加载它。所以我们所要做的就是将文件放在与 运行 应用程序相同的服务器上的某个路径中,然后将 URL 查询参数更新到它的位置,如下所示:

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

瞧。在内部,我们使用 Spring 的 ResourceLoader, which is nothing more than the Spring ApplicationContext. The ResourceLoader understands classpath: and file: prefixes and interprets each accordingly (read the documentation on the ResourceLoader.getResource() method for more details). We got a reference to the Spring's ResourceLoader 只需让我们的 @Service 组件实现 Spring 的 ResourceLoaderAware.

如@Thrax 所述,spring-batch-excel 期望在 Resource 中找到 PushbackInputStream。这是我在文件系统上处理文件时解决这个问题的方法:

我使用来自命令行的输入文件创建我的 reader --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;
}

希望对您有所帮助