目录

1 Maven依赖

2 实现代码

3 调试代码

4 模板内容

5 调试结果

注:


1 Maven依赖

        <!-- easyExcel  Excel文档处理工具     --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.8</version></dependency><!-- hutool工具包       --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.5.7</version></dependency>

2 实现代码

  /*** 行复制(多行)** @param workbook     文档对象* @param sheet        sheet对象* @param fromRowIndex* @param toRowIndex* @param copyRowNum   复制行数*/public static void copyRow(Workbook workbook, Sheet sheet, int fromRowIndex, int toRowIndex, int copyRowNum, boolean insertFlag, Integer colNum) {for (int i = 0; i < copyRowNum; i++) {Row fromRow = sheet.getRow(fromRowIndex + i);Row toRow = sheet.getRow(toRowIndex + i);if (insertFlag) {//复制行超出原有sheet页的最大行数时,不需要移动直接插入if (toRowIndex + i <= sheet.getLastRowNum()) {//先移动要插入的行号所在行及之后的行sheet.shiftRows(toRowIndex + i, sheet.getLastRowNum(), 1, true, false);}//然后再插入行toRow = sheet.createRow(toRowIndex + i);//设置行高toRow.setHeight(fromRow.getHeight());}for (int colIndex = 0; colIndex < (colNum != null ? colNum : fromRow.getLastCellNum()); colIndex++) {Cell tmpCell = fromRow.getCell(colIndex);if (tmpCell == null) {tmpCell = fromRow.createCell(colIndex);if (colIndex != 0) {copyCell(workbook, fromRow.createCell(colIndex - 1), tmpCell);}}Cell newCell = toRow.createCell(colIndex);copyCell(workbook, tmpCell, newCell);}}//获取合并单元格List<CellRangeAddress> cellRangeAddressList = sheet.getMergedRegions();Map<Integer, List<CellRangeAddress>> rowCellRangeAddressMap = CollUtil.isNotEmpty(cellRangeAddressList) ? cellRangeAddressList.stream().collect(Collectors.groupingBy(x ->x.getFirstRow())) : new HashMap<>();//获取形状(线条)XSSFDrawing drawing = (XSSFDrawing) sheet.getDrawingPatriarch();List<XSSFShape> shapeList = new ArrayList<>();Map<Integer, List<XSSFShape>> rowShapeMap = new HashMap<>();if (drawing != null) {shapeList = drawing.getShapes();rowShapeMap = shapeList.stream().filter(x -> x.getAnchor() != null).collect(Collectors.groupingBy(x -> ((XSSFClientAnchor) x.getAnchor()).getRow1()));}List<XSSFShape> insertShapeList = new ArrayList<>();for (int i = 0; i < copyRowNum; i++) {Row toRow = sheet.getRow(toRowIndex + i);//复制合并单元格List<CellRangeAddress> rowCellRangeAddressList = rowCellRangeAddressMap.get(fromRowIndex + i);if (CollUtil.isNotEmpty(rowCellRangeAddressList)) {for (CellRangeAddress cellRangeAddress : rowCellRangeAddressList) {CellRangeAddress newCellRangeAddress = new CellRangeAddress(toRow.getRowNum(), (toRow.getRowNum() +(cellRangeAddress.getLastRow() - cellRangeAddress.getFirstRow())), cellRangeAddress.getFirstColumn(), cellRangeAddress.getLastColumn());sheet.addMergedRegionUnsafe(newCellRangeAddress);}}//复制形状(线条)List<XSSFShape> rowShapeList = rowShapeMap.get(fromRowIndex + i);if (CollUtil.isNotEmpty(rowShapeList)) {for (XSSFShape shape : rowShapeList) {//复制描点XSSFClientAnchor fromAnchor = (XSSFClientAnchor) shape.getAnchor();XSSFClientAnchor toAnchor = new XSSFClientAnchor();toAnchor.setDx1(fromAnchor.getDx1());toAnchor.setDx2(fromAnchor.getDx2());toAnchor.setDy1(fromAnchor.getDy1());toAnchor.setDy2(fromAnchor.getDy2());toAnchor.setRow1(toRow.getRowNum());toAnchor.setRow2(toRow.getRowNum() + fromAnchor.getRow2() - fromAnchor.getRow1());toAnchor.setCol1(fromAnchor.getCol1());toAnchor.setCol2(fromAnchor.getCol2());//复制形状if (shape instanceof XSSFConnector) {copyXSSFConnector((XSSFConnector) shape, drawing, toAnchor);} else if (shape instanceof XSSFSimpleShape) {copyXSSFSimpleShape((XSSFSimpleShape) shape, drawing, toAnchor);}}}}}/*** 复制XSSFSimpleShape类** @param fromShape* @param drawing* @param anchor* @return*/public static XSSFSimpleShape copyXSSFSimpleShape(XSSFSimpleShape fromShape, XSSFDrawing drawing, XSSFClientAnchor anchor) {XSSFSimpleShape toShape = drawing.createSimpleShape(anchor);CTShape ctShape = fromShape.getCTShape();CTShapeProperties ctShapeProperties = ctShape.getSpPr();CTLineProperties lineProperties = ctShapeProperties.isSetLn() ? ctShapeProperties.getLn() : ctShapeProperties.addNewLn();CTPresetLineDashProperties dashStyle = lineProperties.isSetPrstDash() ? lineProperties.getPrstDash() : CTPresetLineDashProperties.Factory.newInstance();STPresetLineDashVal.Enum dashStyleEnum = dashStyle.isSetVal() ? dashStyle.getVal() : STPresetLineDashVal.Enum.forInt(1);CTSolidColorFillProperties fill = lineProperties.isSetSolidFill() ? lineProperties.getSolidFill() : lineProperties.addNewSolidFill();CTSRgbColor rgb = fill.isSetSrgbClr() ? fill.getSrgbClr() : CTSRgbColor.Factory.newInstance();// 设置形状类型toShape.setShapeType(fromShape.getShapeType());// 设置线宽toShape.setLineWidth(lineProperties.getW() * 1.0 / Units.EMU_PER_POINT);// 设置线的风格toShape.setLineStyle(dashStyleEnum.intValue() - 1);// 设置线的颜色byte[] rgbBytes = rgb.getVal();if (rgbBytes == null) {toShape.setLineStyleColor(0, 0, 0);} else {toShape.setLineStyleColor(rgbBytes[0], rgbBytes[1], rgbBytes[2]);}return toShape;}/*** 复制XSSFConnector类** @param fromShape* @param drawing* @param anchor* @return*/public static XSSFConnector copyXSSFConnector(XSSFConnector fromShape, XSSFDrawing drawing, XSSFClientAnchor anchor) {XSSFConnector toShape = drawing.createConnector(anchor);CTConnector ctConnector = fromShape.getCTConnector();CTShapeProperties ctShapeProperties = ctConnector.getSpPr();CTLineProperties lineProperties = ctShapeProperties.isSetLn() ? ctShapeProperties.getLn() : ctShapeProperties.addNewLn();CTPresetLineDashProperties dashStyle = lineProperties.isSetPrstDash() ? lineProperties.getPrstDash() : CTPresetLineDashProperties.Factory.newInstance();STPresetLineDashVal.Enum dashStyleEnum = dashStyle.isSetVal() ? dashStyle.getVal() : STPresetLineDashVal.Enum.forInt(1);CTSolidColorFillProperties fill = lineProperties.isSetSolidFill() ? lineProperties.getSolidFill() : lineProperties.addNewSolidFill();CTSRgbColor rgb = fill.isSetSrgbClr() ? fill.getSrgbClr() : CTSRgbColor.Factory.newInstance();// 设置形状类型toShape.setShapeType(fromShape.getShapeType());// 设置线宽toShape.setLineWidth(lineProperties.getW() * 1.0 / Units.EMU_PER_POINT);// 设置线的风格toShape.setLineStyle(dashStyleEnum.intValue() - 1);// 设置线的颜色byte[] rgbBytes = rgb.getVal();if (rgbBytes == null) {toShape.setLineStyleColor(0, 0, 0);} else {toShape.setLineStyleColor(rgbBytes[0], rgbBytes[1], rgbBytes[2]);}return toShape;}/*** 复制单元格** @param srcCell* @param distCell*/public static void copyCell(Workbook workbook, Cell srcCell, Cell distCell) {CellStyle newStyle = workbook.createCellStyle();copyCellStyle(srcCell.getCellStyle(), newStyle, workbook);//样式distCell.setCellStyle(newStyle);//设置内容CellType srcCellType = srcCell.getCellTypeEnum();distCell.setCellType(srcCellType);if (srcCellType == NUMERIC) {if (DateUtil.isCellDateFormatted(srcCell)) {distCell.setCellValue(srcCell.getDateCellValue());} else {distCell.setCellValue(srcCell.getNumericCellValue());}} else if (srcCellType == CellType.STRING) {distCell.setCellValue(srcCell.getRichStringCellValue());} else if (srcCellType == CellType.BOOLEAN) {distCell.setCellValue(srcCell.getBooleanCellValue());} else if (srcCellType == CellType.ERROR) {distCell.setCellErrorValue(srcCell.getErrorCellValue());} else if (srcCellType == CellType.FORMULA) {distCell.setCellFormula(srcCell.getCellFormula());} else {}}/*** 复制一个单元格样式到目的单元格样式** @param fromStyle* @param toStyle*/public static void copyCellStyle(CellStyle fromStyle, CellStyle toStyle, Workbook workbook) {//水平垂直对齐方式toStyle.setAlignment(fromStyle.getAlignmentEnum());toStyle.setVerticalAlignment(fromStyle.getVerticalAlignmentEnum());//边框和边框颜色toStyle.setBorderBottom(fromStyle.getBorderBottomEnum());toStyle.setBorderLeft(fromStyle.getBorderLeftEnum());toStyle.setBorderRight(fromStyle.getBorderRightEnum());toStyle.setBorderTop(fromStyle.getBorderTopEnum());toStyle.setTopBorderColor(fromStyle.getTopBorderColor());toStyle.setBottomBorderColor(fromStyle.getBottomBorderColor());toStyle.setRightBorderColor(fromStyle.getRightBorderColor());toStyle.setLeftBorderColor(fromStyle.getLeftBorderColor());//背景和前景if (fromStyle instanceof XSSFCellStyle) {XSSFCellStyle xssfToStyle = (XSSFCellStyle) toStyle;xssfToStyle.setFillBackgroundColor(((XSSFCellStyle) fromStyle).getFillBackgroundColorColor());xssfToStyle.setFillForegroundColor(((XSSFCellStyle) fromStyle).getFillForegroundColorColor());} else {toStyle.setFillBackgroundColor(fromStyle.getFillBackgroundColor());toStyle.setFillForegroundColor(fromStyle.getFillForegroundColor());}toStyle.setDataFormat(fromStyle.getDataFormat());toStyle.setFillPattern(fromStyle.getFillPatternEnum());if (fromStyle instanceof XSSFCellStyle) {toStyle.setFont(((XSSFCellStyle) fromStyle).getFont());} else if (fromStyle instanceof HSSFCellStyle) {toStyle.setFont(((HSSFCellStyle) fromStyle).getFont(workbook));}toStyle.setHidden(fromStyle.getHidden());//首行缩进toStyle.setIndention(fromStyle.getIndention());toStyle.setLocked(fromStyle.getLocked());//旋转toStyle.setRotation(fromStyle.getRotation());toStyle.setWrapText(fromStyle.getWrapText());}

3 调试代码

  /*** 测试复制行(样式、合并单元格、形状)*/@Testpublic void testCopyRow() {try {//读文件ClassPathResource classPathResource = new ClassPathResource("/doc/excel/copyRowTemplate.xlsx");XSSFWorkbook workbook = new XSSFWorkbook(classPathResource.getFile());Sheet sheet = workbook.getSheetAt(0);File file = new File("D:/easyexcel/testCopyRow.xlsx");FileUtil.createNewFile(file);//复制前两行POIExcelUtil.copyRow(workbook,sheet,0,2,2,true,null);workbook.write(new FileOutputStream(file));} catch (Exception e) {e.printStackTrace();}}

4 模板内容

5 调试结果

注:

(1) 支持复制文本内容、单元格样式、合并单元格、形状信息。复制形状只支持形状类型的复制,不支持线条类型、宽度、颜色的复制。

(2)源码请查看Gitee。

xudongbase: 主要是项目中可以用到的共通方法https://gitee.com/xudong_master/xudongbase

POI Excel复制行(支持复制样式、合并单元格、形状)相关推荐

  1. java通过poi生成excel表格(自适应列宽、合并单元格后的边框添加)

    具体java通过POI读写Excel的基本使用方法可参考: POI读写Excel的基本使用 1.项目导入依赖: <!--xls--> <dependency><group ...

  2. C# Excel 行高,列宽,合并单元格,单元格边框线,冻结

    C# Excel 行高,列宽,合并单元格,单元格边框线,冻结 原文:http://hi.baidu.com/kjkj911/blog/item/0ecc3ec7855dd6d4d100600f.htm ...

  3. 信创办公–基于WPS的EXCEL最佳实践系列 (处理合并单元格)

    信创办公–基于WPS的EXCEL最佳实践系列 (处理合并单元格) 目录 应用背景 相关知识 操作步骤 1.合并单元格对排序的影响 2.取消合并单元格并自动填充内容 应用背景 在Excle表格中,对于相 ...

  4. Web中的EasyExcel导出Excel(不创建对象且自定义合并单元格策略)

    Web中的EasyExcel导出Excel(不创建对象且自定义合并单元格策略) 适用于多张表(只查单表数据就用创建对象那种方法) Controller @RequestMapping(value = ...

  5. 在Excel表格中如何快速拆分合并单元格

    在Excel表格中如何快速拆分合并单元格 目录 在Excel表格中如何快速拆分合并单元格 1.例如:将销售人列中的合并单元格拆分还原 2.选中销售人姓名,点击[开始]选项卡中[合并居中] 3.再点击[ ...

  6. C# Excel 行高,列宽,合并单元格,单元格边框线,冻结(转载) - 关于C#操作EXCLE常见操作比较全的

    网上看到的比较全的关于C#操作EXCEL常见操作集合,比较全,写的不错 原文地址:http://hi.baidu.com/kjkj911/blog/item/0ecc3ec7855dd6d4d1006 ...

  7. poi导出excel,行相同数据自动合并单元格

    /***excel行自动合并*listData 待导出数据*/ public void test(SXSSFSheet sheet,List<FanManagerExt> listData ...

  8. Excel表格自动筛选时显示合并单元格中全部记录的方法

    今天给单位一个分公司导数据,因为报表是全司的,如何导成某一个分公司的呢? 1.复制合并单元格所在的A列到其他空白列,如本例中的列的E2:E18,这样做的目的是保留合并单元格的大小和样式. 2.选择A2 ...

  9. java poi生成word 插入表格,图片,自动合并单元格,并且可以在已存在的word上追加

    poi版本选3.10以上的 要不然插入图片 word会打不开 <dependency><groupId>org.apache.poi</groupId><ar ...

  10. html粘贴excel表格大小不一样,为什么excel表格粘贴的时候显示因为单元格形状大小不一样无法粘贴呢...

    EXCEL依然是现在最流行的表格处理软件,我们很多汇总.财务等工作都需要用到,各种公式更是让excel更为强大,但是,我们在粘贴数据的时候,经常会遇到:"excel 无法粘贴信息,原因是复制 ...

最新文章

  1. 12 个最佳的免费学习编程的游戏网站【转】
  2. 如何在网页标题栏title加入icon图标?
  3. docker环境安装redis
  4. 关于ExtJS通过单击左边的treePanel在居中的panel加载页面问题
  5. 史上最全的ECharts讲解与使用
  6. 巴铁 无人驾驶_巴铁骗局再现 深圳无人巴士谎言又来忽悠人
  7. php-fpm哪里下载_centos – Nginx PHP-FPM提供.php文件作为下载
  8. python和java还有sql区别_人人都在学编程?Python,R,Java,SQL,你究竟需要学哪一种?...
  9. animate支持的css属性
  10. php国际象棋棋盘奇行奇列,国际象棋怎么玩
  11. 【参考文献】软骨细胞生长培养方法
  12. RabbitMQ使用案例
  13. Mysql比较运算符实战
  14. MATLAB深度学习代码详细分析(一)__nnff.m
  15. 用键盘控制鼠标移动的Python脚本
  16. 标题优化的技巧是什么
  17. 酷冷战神 先手致胜:腾讯ROG游戏手机6为游戏而生
  18. CSS3 弹性布局/伸缩布局 flex
  19. Android 13 针对 Intent filters 安全的再加强
  20. 2022年顶级网络安全专家最爱的5大数据加密方法

热门文章

  1. 2023年医院三基题库精选套卷及答案
  2. 国产公链发力点在哪里?NFT、隐私计算和可管理的区块链
  3. pytorch加载部分参数训练
  4. 发票信息批量提取到 excel 软件 2.4
  5. 智能手机的聊天记录误删怎么办
  6. 程序设计入门C语言 --- 逆序的三位数
  7. rockeMq linux 安装过程 注意一些细节
  8. 2021-08-09 程序员的自我修养
  9. 【UE5】打开他人的UE4/5项目没有.sln文件,打开c++文件失败
  10. 两台计算机组成一个局域网的方法,两台电脑如何建立局域网