java操作sheet实现整体行下移

由于poi中不支持整体行下移,或者通过复制的时候行下移样式丢失,所以找到一个整体下移的思路,并进行了一部分自己理解的简化

 /**
     * 整体行下移
     * @param sheet 表
     * @param rows 移动的行
     */
    private void move(XSSFSheet sheet,Integer rows){
            int beginRowNo = rows;
            Row beginRow = sheet.getRow(beginRowNo);
            int addNo = 1;
            int moveBeginRow = beginRowNo+1;
            //如果移动的开始行不存在,则创建一个空行,否则复制的时候会丢掉不存在的行
            if(sheet.getRow(moveBeginRow)==null){
                sheet.createRow(moveBeginRow);
            }
            int lastRowNo = sheet.getLastRowNum();

            //计算移动的行数
            int movedNo = lastRowNo-moveBeginRow+1;
            //临时区的开始行
            int tempBeginRowNo = lastRowNo+addNo+1;
            //临时区的结束行
            int tempLastRowNo = tempBeginRowNo+movedNo-1;
            //末尾部分的最终开始行
            int finalBeginRowNo = addNo+beginRowNo;

            //移动开始行以后的行到临时的开始行
            moveRows(sheet,moveBeginRow,lastRowNo,tempBeginRowNo);
            //在空出位置插入新行并复制第一行的样式
            for (int i = moveBeginRow; i <finalBeginRowNo; i++){
                Row row = sheet.getRow(i);
                if (row != null){
                    sheet.removeRow(row);
                }
                //创建空白的行
                sheet.createRow(i);
                if(beginRow!=null){
                    //复制第一行的样式到当前行
                    CellCopyPolicy cellCopyPolicy=new CellCopyPolicy();
                    cellCopyPolicy.setCopyRowHeight(DEFAULT_COPY_ROW_HEIGHT_POLICY);
                    sheet.copyRows(beginRowNo,beginRowNo, i, cellCopyPolicy);
                }
            }
            //将移动的行从临时开始行回移新增好的行的末尾
            /*
              为什么不直接第一次移动的预期的末尾呢?是因为POX只支持Copy行的操作,而copy操作不是完整的区间覆盖。
              如果源区间内带有格式,并且目的区间和源区间有重叠话,会导致无法copy后源区间和目的区间混合在一起,无法清理。
              因此实现移动行区间的操作时,需要先将源行区间复制到一个临时的区域,然后清理掉源行区间的行和样式,再插入需要新增的行
              ,最后再将被移动的行区间移动回新的行末尾。
             */
            moveRows(sheet,tempBeginRowNo,tempLastRowNo,finalBeginRowNo);
    }

    /**
     * 移动行
     * @param sheet
     * @param srcBeginRow 临时区的开始行
     * @param srcEndRow 临时区的结束行
     * @param destBeginRow 末尾部分的最终开始行
     */
    private static void moveRows(XSSFSheet sheet,int srcBeginRow,int srcEndRow,int destBeginRow){
        //先复制到目的位置

        CellCopyPolicy cellCopyPolicy=new CellCopyPolicy();
        cellCopyPolicy.setCopyRowHeight(DEFAULT_COPY_ROW_HEIGHT_POLICY);
        sheet.copyRows(srcBeginRow, srcEndRow, destBeginRow, cellCopyPolicy);
        //清理之前残留的合并单元格
        List<Integer> removeMergedRegion = new ArrayList<>();
        for(int i=sheet.getMergedRegions().size()-1;i>=0;i--){
            CellRangeAddress address = sheet.getMergedRegions().get(i);
            //如果合并单元格在复制前的位置,则删除
            if(address.getFirstRow() >= srcBeginRow && address.getFirstRow()<destBeginRow ){
                removeMergedRegion.add(i);
            }
        };
        //执行清理合并的单元格
        for(Integer i:removeMergedRegion){
            sheet.removeMergedRegion(i);
        }
        //删除移动后原地的行
        for (int i = srcBeginRow; i <= srcEndRow; i++){
            Row row = sheet.getRow(i);
            if (row != null){
                //删除复制后残留的行
                sheet.removeRow(row);
            }
        }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值