Apache POI shiftRows corrupts file and deletes content

前端 未结 1 1337
轻奢々
轻奢々 2021-01-17 02:10

I want to fill table a template excel file. I want to insert rows and fill them. I used java Apache POI library to access excel files. At first, I created a new file and fil

相关标签:
1条回答
  • 2021-01-17 02:42

    Your shiftRows tries shifting rows between row 5 (index 4) and row 6 (index 5) one row down. But what about row 7, 8, 9 and 10? You needs shifting rows between row 5 and last row one row down if the need is getting a new empty row 5.

    Using apache poi version 3.17 this is as simple as:

    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.xssf.usermodel.*;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    
    class ExcelReadShiftRowsAndWrite {
    
     public static void main(String[] args) throws Exception {
      //String fileIn= "TestIn.xls";
      //String fileOut= "TestOut.xls";
      String fileIn= "TestIn.xlsx";
      String fileOut= "TestOut.xlsx";
    
      try (Workbook workbook = WorkbookFactory.create(new FileInputStream(fileIn));
           FileOutputStream out = new FileOutputStream(fileOut)) {
    
       Sheet sheet = workbook.getSheet("Sheet1");
    
       sheet.shiftRows(4, sheet.getLastRowNum(), 1); //shifts rows between row 5 (index 4) and last row one row down
    
       workbook.write(out);
      } 
     }
    }
    

    But apache poi versions greater than 3.17, also 4.1.0, have a bug in shiftRows using XSSF. There, after shifting, the references in the cells remain old instead being adjusted to the new rows. For example the references A5, A6, ... remain after shifting down instead of getting adjusted to A6, A7, ...

    So this bug must be corrected:

    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.xssf.usermodel.*;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    
    class ExcelReadShiftRowsAndWrite {
    
     public static void main(String[] args) throws Exception {
      //String fileIn= "TestIn.xls";
      //String fileOut= "TestOut.xls";
      String fileIn= "TestIn.xlsx";
      String fileOut= "TestOut.xlsx";
    
      try (Workbook workbook = WorkbookFactory.create(new FileInputStream(fileIn));
           FileOutputStream out = new FileOutputStream(fileOut)) {
    
       Sheet sheet = workbook.getSheet("Sheet1");
    
       sheet.shiftRows(4, sheet.getLastRowNum(), 1); //shifts rows between row 5 (index 4) and last row one row down
    
       if (sheet instanceof XSSFSheet) {  
        XSSFSheet xSSFSheet = (XSSFSheet)sheet;
        // correcting bug that shiftRows does not adjusting references of the cells
        // if row 3 is shifted down, then reference in the cells remain r="A3", r="B3", ...
        // they must be adjusted to the new row thoug: r="A4", r="B4", ...
        // apache poi 3.17 has done this properly but had have other bugs in shiftRows.
        for (int r = xSSFSheet.getFirstRowNum(); r < sheet.getLastRowNum() + 1; r++) {
         XSSFRow row = xSSFSheet.getRow(r); 
         if (row != null) {
          long rRef = row.getCTRow().getR();
          for (Cell cell : row) {
           String cRef = ((XSSFCell)cell).getCTCell().getR();
           ((XSSFCell)cell).getCTCell().setR(cRef.replaceAll("[0-9]", "") + rRef);
          }
         }
        }
        // end correcting bug
       }
    
       workbook.write(out);
      } 
     }
    }
    
    0 讨论(0)
提交回复
热议问题