2016-10-12 138 views
0

我想创建一个使用spring-batch-excel扩展的应用程序,以便能够读取由用户通过Web界面上传的Excel文件,以解析Excel文件的地址。Spring批处理:文件未被读取

当代码运行时,没有错误,但我得到的是我的日志中的以下内容。即使我的处理器和写入器中都有log/syso(这些永远不会被调用,而且我可以想象的是它没有正确读取文件,并且没有返回任何数据来处理/写入)。是的,该文件实际上有数据,数千条记录。

Job: [FlowJob: [name=excelFileJob]] launched with the following parameters: [{file=Book1.xlsx}] 
Executing step: [excelFileStep] 
Job: [FlowJob: [name=excelFileJob]] completed with the following parameters: [{file=Book1.xlsx}] and the following status: [COMPLETED] 

下面是我JobConfig

@Configuration 
@EnableBatchProcessing 
public class AddressExcelJobConfig { 

    @Bean 
    public BatchConfigurer configurer(EntityManagerFactory entityManagerFactory) { 
     return new CustomBatchConfigurer(entityManagerFactory); 
    } 

    @Bean 
    Step excelFileStep(ItemReader<AddressExcel> excelAddressReader, 
         ItemProcessor<AddressExcel, AddressExcel> excelAddressProcessor, 
         ItemWriter<AddressExcel> excelAddressWriter, 
         StepBuilderFactory stepBuilderFactory) { 
     return stepBuilderFactory.get("excelFileStep") 
       .<AddressExcel, AddressExcel>chunk(1) 
       .reader(excelAddressReader) 
       .processor(excelAddressProcessor) 
       .writer(excelAddressWriter) 
       .build(); 
    } 

    @Bean 
    Job excelFileJob(JobBuilderFactory jobBuilderFactory, 
        @Qualifier("excelFileStep") Step excelAddressStep) { 
     return jobBuilderFactory.get("excelFileJob") 
       .incrementer(new RunIdIncrementer()) 
       .flow(excelAddressStep) 
       .end() 
       .build(); 
    } 
} 

下面是我AddressExcelReader 的后期绑定工作正常,没有错误。除了创建一个新的ClassPathResource和FileSystemResource之外,我尝试了加载给定文件名的资源。所有这些都给了我相同的结果。

@Component 
@StepScope 
public class AddressExcelReader implements ItemReader<AddressExcel> { 

    private PoiItemReader<AddressExcel> itemReader = new PoiItemReader<AddressExcel>(); 

    @Override 
    public AddressExcel read() 
      throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException { 
     return itemReader.read(); 
    } 

    public AddressExcelReader(@Value("#{jobParameters['file']}") String file, StorageService storageService) { 
     //Resource resource = storageService.loadAsResource(file); 
     //Resource testResource = new FileSystemResource("upload-dir/Book1.xlsx"); 
     itemReader.setResource(new ClassPathResource("/upload-dir/Book1.xlsx")); 
     itemReader.setLinesToSkip(1); 
     itemReader.setStrict(true); 
     itemReader.setRowMapper(excelRowMapper()); 
    } 

    public RowMapper<AddressExcel> excelRowMapper() { 
     BeanWrapperRowMapper<AddressExcel> rowMapper = new BeanWrapperRowMapper<>(); 
     rowMapper.setTargetType(AddressExcel.class); 
     return rowMapper; 
    } 

} 

下面是我AddressExcelProcessor

@Component 
public class AddressExcelProcessor implements ItemProcessor<AddressExcel, AddressExcel> { 

    private static final Logger log = LoggerFactory.getLogger(AddressExcelProcessor.class); 

    @Override 
    public AddressExcel process(AddressExcel item) throws Exception { 
     System.out.println("Converting " + item); 
     log.info("Convert {}", item); 
     return item; 
    } 

} 

再次,这是从来没有进入播放(无日志生成)。如果它很重要,这是怎么了。我现在是@PostMapping(“/”)启动从FileUploadController我的工作就是处理文件上传,其第一家门店的文件,然后运行作业:

@PostMapping("/") 
public String handleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) { 

    storageService.store(file); 

    try { 
     JobParameters jobParameters = new JobParametersBuilder() 
       .addString("file", file.getOriginalFilename().toString()).toJobParameters(); 
     jobLauncher.run(job, jobParameters); 
    } catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException 
      | JobParametersInvalidException e) { 
     e.printStackTrace(); 
    } 

    redirectAttributes.addFlashAttribute("message", 
      "You successfully uploaded " + file.getOriginalFilename() + "!"); 

    return "redirect:/"; 
} 

而在去年通过并非最不重要的

这里是我的AddressExcel POJO

import lombok.Data; 

@Data 
public class AddressExcel { 

    private String address1; 
    private String address2; 
    private String city; 
    private String state; 
    private String zip; 

    public AddressExcel() {} 

} 

更新(2016年10月13日) 从Nghia酒店待办事项的意见,我也创建了自己的RowMapper而不是使用BeanWrapper来查看是否是这个问题。仍然是相同的结果。

public class AddressExcelRowMapper implements RowMapper<AddressExcel> { 

    @Override 
    public AddressExcel mapRow(RowSet rs) throws Exception { 
     AddressExcel temp = new AddressExcel(); 

     temp.setAddress1(rs.getColumnValue(0)); 
     temp.setAddress2(rs.getColumnValue(1)); 
     temp.setCity(rs.getColumnValue(2)); 
     temp.setState(rs.getColumnValue(3)); 
     temp.setZip(rs.getColumnValue(4)); 

     return temp; 
    } 

} 
+0

为了排除故障,你可以有它实现org.springframework.batch.item一个简单的类.excel.RowMapper来查看Reader是否实际读取数据并到达RowMapper。 –

+1

你确定,那'itemReader.setResource(新的ClassPathResource(“/ upload-dir/Book1.xlsx”));'是正确的?您需要在类路径中包含ubdirectory“upload-dir”的目录。 –

+0

您是否调试过您的阅读器以检查文件是否被找到并正确打开? –

回答

0

所有看来我需要的是以下内容添加到我的ItemReader:而不是使用BeanWrapperRowMapper

itemReader.afterPropertiesSet(); 
itemReader.open(new ExecutionContext()); 
+0

这只是问题的部分解决方案。你需要注册代表作为流或按照我的问题 –

+0

的评论我没有实现ItemStreamReader它的工作。那会给我什么好处?对不起,我只是不知道是为什么我问。 – ThirstyForJava

+0

@ThirstyForJava:每当我尝试去做上述事情时,我得到这个异常:'org.springframework.batch.item.ItemStreamException:未能初始化读取器'由于java.lang.IllegalStateException:InputStream必须支持标记/重置,或者被封装为PushbackInputStream' 我该怎么办?还有其他的选择吗? –

相关问题