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

前端 未结 8 994
自闭症患者
自闭症患者 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.

提交回复
热议问题