2016-10-12 3 views
0

Я пытаюсь создать приложение, использующее расширение spring-batch-excel, чтобы читать файлы Excel, загруженные через веб-интерфейс его пользователями, чтобы анализировать файл Excel для адресов ,Spring Batch: Файл не читается

Когда код запущен, ошибки нет, но все, что я получаю, является следующим в моем журнале. Несмотря на то, что у меня есть log/syso на протяжении всего моего Процессора и Writer (они никогда не вызываются, и все, что я могу себе представить, это не правильно читать файл и не возвращать данные для обработки/записи). И да, файл имеет данные, несколько тысяч записей.

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; 
    } 

} 

Опять же, это никогда не приходит в игру (нет журналы не генерируется). И если это имеет значение, это то, как я запускать свою работу из FileUploadController от @PostMapping («/») для обработки загрузки файла, который сначала сохраняет файл, а затем выполняет задание:

@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() {} 

} 

UPDATE (10/13/2016) Из комментариев 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

Для устранения неполадок, вместо использования BeanWrapperRowMapper, вы могли бы иметь простой класс, которые реализуют org.springframework.batch.item .excel.RowMapper, чтобы убедиться, что Reader действительно читает данные и подходит к вашему RowMapper. –

+1

вы уверены, что 'itemReader.setResource (новый ClassPathResource ("/ upload-dir/Book1.xlsx"));' верно? Вам нужно будет иметь каталог, содержащий ubdirectory "upload-dir" в вашем пути к классам. –

+0

Вы отлаживали вашего читателя, чтобы проверить, найден ли файл и его открытие правильно? –

ответ

0

Все это, кажется, что мне было нужно добавить следующее к моему ItemReader:

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

Это лишь частичное решение проблемы. Вам необходимо зарегистрировать делегат как поток или следовать моему комментарию по вопросу –

+0

Мне не нужно было выполнять ItemStreamReader для его работы. Какую выгоду мне это даст? Извините, я просто не знаю, почему я спрашиваю. – ThirstyForJava

+0

@ThirstyForJava: всякий раз, когда я пытался сделать то, что упоминалось выше, я получил это исключение: 'org.springframework.batch.item.ItemStreamException: не удалось инициализировать читателя и' вызвано: java.lang.IllegalStateException: InputStream ДОЛЖЕН либо знак поддержки/сброс или быть обернутым как PushbackInputStream' Что мне делать? Есть ли другая альтернатива? –

Смежные вопросы