How to insert a row between two rows in an existing excel with HSSF (Apache POI)

前端 未结 8 929
自闭症患者
自闭症患者 2020-11-27 02:38

Somehow I manage to create new rows between two rows in an existing excel file. The problem is, some of the formatting were not include along the shifting of the rows.

相关标签:
8条回答
  • 2020-11-27 03:39

    I merged some of the other answers and comments in the following implementation, tested with Apache POI v3.9.

    I have only one rownum parameter because I shift down the target row and copy it in the new empty row. Formulas are handled as expected, they are not copied verbatim, with one exception: references to cells that are above the copied line are not updated; the workaround is to replace these explicit references (if any) with references calculated using INDIRECT() as suggested by this post.

    protected void copyRow(Sheet worksheet, int rowNum) {
        Row sourceRow = worksheet.getRow(rowNum);
    
        //Save the text of any formula before they are altered by row shifting
        String[] formulasArray = new String[sourceRow.getLastCellNum()];
        for (int i = 0; i < sourceRow.getLastCellNum(); i++) {
            if (sourceRow.getCell(i) != null && sourceRow.getCell(i).getCellType() == Cell.CELL_TYPE_FORMULA) 
                formulasArray[i] = sourceRow.getCell(i).getCellFormula();
        }
    
        worksheet.shiftRows(rowNum, worksheet.getLastRowNum(), 1);
        Row newRow = sourceRow;  //Now sourceRow is the empty line, so let's rename it
        sourceRow = worksheet.getRow(rowNum + 1);  //Now the source row is at rowNum+1
    
        // Loop through source columns to add to new row
        for (int i = 0; i < sourceRow.getLastCellNum(); i++) {
            // Grab a copy of the old/new cell
            Cell oldCell = sourceRow.getCell(i);
            Cell newCell;
    
            // If the old cell is null jump to next cell
            if (oldCell == null) {
                continue;
            } else {
                newCell = newRow.createCell(i);
            }
    
            // Copy style from old cell and apply to new cell
            CellStyle newCellStyle = worksheet.getWorkbook().createCellStyle();
            newCellStyle.cloneStyleFrom(oldCell.getCellStyle());
            newCell.setCellStyle(newCellStyle);
    
            // If there is a cell comment, copy
            if (oldCell.getCellComment() != null) {
                newCell.setCellComment(oldCell.getCellComment());
            }
    
            // If there is a cell hyperlink, copy
            if (oldCell.getHyperlink() != null) {
                newCell.setHyperlink(oldCell.getHyperlink());
            }
    
            // Set the cell data type
            newCell.setCellType(oldCell.getCellType());
    
            // Set the cell data value
            switch (oldCell.getCellType()) {
                case Cell.CELL_TYPE_BLANK:
                    break;
                case Cell.CELL_TYPE_BOOLEAN:
                    newCell.setCellValue(oldCell.getBooleanCellValue());
                    break;
                case Cell.CELL_TYPE_ERROR:
                    newCell.setCellErrorValue(oldCell.getErrorCellValue());
                    break;
                case Cell.CELL_TYPE_FORMULA:
                    newCell.setCellFormula(formulasArray[i]);
                    break;
                case Cell.CELL_TYPE_NUMERIC:
                    newCell.setCellValue(oldCell.getNumericCellValue());
                    break;
                case Cell.CELL_TYPE_STRING:
                    newCell.setCellValue(oldCell.getRichStringCellValue());
                    break;
                default:   
                    break; 
            }
        }
    
        // If there are any merged regions in the source row, copy to new row
        for (int i = 0; i < worksheet.getNumMergedRegions(); i++) {
            CellRangeAddress cellRangeAddress = worksheet.getMergedRegion(i);
            if (cellRangeAddress.getFirstRow() == sourceRow.getRowNum()) {
                CellRangeAddress newCellRangeAddress = new CellRangeAddress(newRow.getRowNum(),
                        (newRow.getRowNum() +
                                (cellRangeAddress.getLastRow() - cellRangeAddress.getFirstRow()
                                        )),
                        cellRangeAddress.getFirstColumn(),
                        cellRangeAddress.getLastColumn());
                worksheet.addMergedRegion(newCellRangeAddress);
            }
        }
    }
    

    I'm using this implementation in production code.

    0 讨论(0)
  • 2020-11-27 03:40

    Referencing Qwerty's answer, you can avoid to inflate XL size by re-using cellStyle. And when the type is CELL_TYPE_BLANK, getStringCellValue returns "" instead of null.

    private static void copyRow(Sheet worksheet, int sourceRowNum, int destinationRowNum) {
      // Get the source / new row
      Row newRow = worksheet.getRow(destinationRowNum);
      Row sourceRow = worksheet.getRow(sourceRowNum);
    
      // If the row exist in destination, push down all rows by 1 else create a new row
      if (newRow != null) {
        worksheet.shiftRows(destinationRowNum, worksheet.getLastRowNum(), 1);
      } else {
        newRow = worksheet.createRow(destinationRowNum);
      }
    
      // Loop through source columns to add to new row
      for (int i = 0; i < sourceRow.getLastCellNum(); i++) {
        // Grab a copy of the old/new cell
        Cell oldCell = sourceRow.getCell(i);
        Cell newCell = newRow.createCell(i);
    
        // If the old cell is null jump to next cell
        if (oldCell == null) {
          newCell = null;
          continue;
        }
    
        // Use old cell style
        newCell.setCellStyle(oldCell.getCellStyle());
    
        // If there is a cell comment, copy
        if (newCell.getCellComment() != null) {
          newCell.setCellComment(oldCell.getCellComment());
        }
    
        // If there is a cell hyperlink, copy
        if (oldCell.getHyperlink() != null) {
          newCell.setHyperlink(oldCell.getHyperlink());
        }
    
        // Set the cell data type
        newCell.setCellType(oldCell.getCellType());
    
        // Set the cell data value
        switch (oldCell.getCellType()) {
        case Cell.CELL_TYPE_BLANK:
          break;
        case Cell.CELL_TYPE_BOOLEAN:
          newCell.setCellValue(oldCell.getBooleanCellValue());
          break;
        case Cell.CELL_TYPE_ERROR:
          newCell.setCellErrorValue(oldCell.getErrorCellValue());
          break;
        case Cell.CELL_TYPE_FORMULA:
          newCell.setCellFormula(oldCell.getCellFormula());
          break;
        case Cell.CELL_TYPE_NUMERIC:
          newCell.setCellValue(oldCell.getNumericCellValue());
          break;
        case Cell.CELL_TYPE_STRING:
          newCell.setCellValue(oldCell.getRichStringCellValue());
          break;
        }
      }
    }
    
    0 讨论(0)
提交回复
热议问题