Save the data to table and save it to database even if empty rows in EXCEL java POI Apache

时间秒杀一切 提交于 2020-01-06 04:31:22

问题


I dont know how to save the content in database, I try to import the excel it works but if the excel one of the rows are empty it appears java.lang.IndexOutOfBoundsException

-- Here's my code --

-- BranchEntity.java --

public class Branch {

private static final long serialVersionUID = 1L;

@Column(name = "branch_code", nullable = false, length = 10)
private String branchCode;

@Column(name = "branch_desc", nullable = false, length = 100)
private String branchDescription;

@OneToMany(mappedBy = "branch", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JsonIgnore
private List<User> user;

public Branch(String branchCode, String branchDescription, List<User> user) {
    super();
    this.branchCode = branchCode;
    this.branchDescription = branchDescription;
    this.user = user;
}

public Branch() {
    super();
}

public String getBranchCode() {
    return branchCode;
}

public void setBranchCode(String branchCode) {
    this.branchCode = branchCode;
}

public String getBranchDescription() {
    return branchDescription;
}

public void setBranchDescription(String branchDescription) {
    this.branchDescription = branchDescription;
}

public List<User> getUser() {
    return user;
}

public void setUser(List<User> user) {
    this.user = user;
}

}

-- BranchService.java ---

@Autowired private BranchRepository branchRepository;

public List> uploadEmployee(MultipartFile multip) throws Exception {

    DataFormatter formatter = new DataFormatter();

    String fileNames = multip.getOriginalFilename();

    File file = new File("./reports/" + fileNames);
    Workbook workbook = WorkbookFactory.create(file);

    FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();

    Sheet sheet = workbook.getSheetAt(0);

    Supplier<Stream<Row>> rowStreamSupplier = uploadUtils.getRowStreamSupplier(sheet);

    Row headerRow = rowStreamSupplier.get().findFirst().get();
    List<String> headerCells = uploadUtils.getStream(headerRow)
    .map(Cell::getStringCellValue) 
    .collect(Collectors.toList());

    int colCount = headerCells.size();

    List<Map<String, String>> content = rowStreamSupplier.get()
    .skip(1)
    .map(row -> {

    List<String> cellList = uploadUtils.getStream(row)
    .map((cell) -> formatter.formatCellValue(cell, evaluator))
    .collect(Collectors.toList());  
        return uploadUtils.cellIteratorSupplier(colCount)
    .get()
    .collect(Collectors.toMap(headerCells::get, cellList::get));
    }).collect(Collectors.toList());

    branchRepository.save(content);

    workbook.close();

    return content;

}

-- BranchController.java --

@RequestMapping(value = "/uploadEmployee", method = RequestMethod.POST)
public List<Map<String, String>> uploadEmployee(MultipartFile file) throws Exception {
    return employeeService.uploadEmployee(file);
}

回答1:


To avoid the java.lang.IndexOutOfBoundsException you need to avoid the java.util.stream.* approach since this fully depends on using Iterators. But apache poi's Busy Developers' Guide -> Iterate over rows and cells tells:

Note that a rowIterator and cellIterator iterate over rows or cells that have been created, skipping empty rows and cells.

So empty rows and cells are not iterated. That's why getting a empty cell from a cellIterator is impossible and fails.

To avoid that we should do the following:

First collect the column headers as a Map of header names to column indexes. This can be done using a cell iterator over the first row. If cells are empty there, then this column will be skipped.

Then collect the content into your needed List of Maps where cell values are mapped to header names. This must be done for each row using a for loop from first header column index to last header column index. If cells are empty, then the cell can be created as empty cell. So DataFormatter gets it's value as empty string then.

Complete working example:

import org.apache.poi.ss.usermodel.*;

import java.io.File;
import java.util.*;

public class ReadExcelToCollection {

 public static void main(String[] args) throws Exception {

  DataFormatter formatter = new DataFormatter();

  File file = new File("Excel.xlsx");
  Workbook workbook = WorkbookFactory.create(file);

  FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();

  Sheet sheet = workbook.getSheetAt(0);

  int headerRowNum = sheet.getFirstRowNum();

  // collecting the column headers as a Map of header names to column indexes
  Map<Integer, String> colHeaders = new HashMap<Integer, String>();
  Row row = sheet.getRow(headerRowNum);
  for (Cell cell : row) {
   int colIdx = cell.getColumnIndex();
   String value = formatter.formatCellValue(cell, evaluator);
   colHeaders.put(colIdx, value);
  }

  System.out.println(colHeaders);

  // collecting the content into List of Maps where cell values are mapped to header names.
  List<Map<String, String>> content = new ArrayList<Map<String, String>>();
  for (int r = headerRowNum + 1; r <= sheet.getLastRowNum(); r++) {
   row = sheet.getRow(r); if (row == null) row = sheet.createRow(r);
   Map<String, String> valuesToHeaders = new HashMap<String, String>();
   for (Map.Entry<Integer, String> entry : colHeaders.entrySet()) {
    int colIdx = entry.getKey();
    Cell cell = row.getCell(colIdx); if (cell == null) cell = row.createCell(colIdx);
    String cellValue = formatter.formatCellValue(cell, evaluator);
    valuesToHeaders.put(entry.getValue(), cellValue);
   }
   content.add(valuesToHeaders);
  }

  System.out.println(content);

  workbook.close();
 }
}


来源:https://stackoverflow.com/questions/58974646/save-the-data-to-table-and-save-it-to-database-even-if-empty-rows-in-excel-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!