ExcelUtils实现 设置内容 插入行 复制行列格式

ExcelUtils实现:

1.实现输入 例如 2 A 的excel格式,自动填充对应excel单元格;

2.实现复制并新增下一行

3.实现控制复制上一行相同列的格式;

4.实现控制复制同一行上一列的格式;

java 复制代码
  /**
     * 在指定行下方插入新行并复制上一行格式
     *
     * @param sheet    Excel工作表
     * @param rowIndex 在此行下方插入新行(从0开始)
     * @return 插入的新行
     */
    public static Row insertRowWithFormat(Sheet sheet, int rowIndex) {
        // 使用excel 行数 自动-1
        rowIndex = rowIndex - 1;
        // 将指定行下方的所有行向下移动
        sheet.shiftRows(rowIndex + 1, sheet.getLastRowNum(), 1);

        // 创建新行
        Row newRow = sheet.createRow(rowIndex + 1);

        // 复制上一行的格式
        copyRowFormat(sheet, rowIndex, rowIndex + 1);

        return newRow;
    }

    /**
     * 在指定位置插入多行并复制格式
     *
     * @param sheet         Excel工作表
     * @param startRowIndex 开始行索引
     * @param rowCount      插入行数
     */
    public static void insertRowsWithFormat(Sheet sheet, int startRowIndex, int rowCount) {
        // 将指定行下方的所有行向下移动
        sheet.shiftRows(startRowIndex + 1, sheet.getLastRowNum(), rowCount);

        // 逐行复制格式
        for (int i = 0; i < rowCount; i++) {
            int targetRowIndex = startRowIndex + 1 + i;
            Row newRow = sheet.createRow(targetRowIndex);

            // 复制上一行的格式(始终复制startRowIndex行的格式)
            copyRowFormat(sheet, startRowIndex, targetRowIndex);
        }
    }


    /**
     * 在指定的行和列设置单元格的值和样式
     *
     * @param sheet           Excel工作表
     * @param workbook        Excel工作簿
     * @param rowNum          行号(从0开始)
     * @param cellNum         列号(从0开始)
     * @param value           要设置的值
     * @param style           单元格样式,如果为null则使用默认样式
     * @param isCopyRowStyle  是否复制上一行相同列的样式 优先
     * @param isCopyCellStyle 是否复制同一行上一列的样式
     * @return 设置的单元格
     */
    public static Cell setCellValueAndStyle(Sheet sheet, Workbook workbook, int rowNum, int cellNum,
                                            String value, CellStyle style,
                                            boolean isCopyRowStyle, boolean isCopyCellStyle) {
        // 获取或创建行
        Row row = sheet.getRow(rowNum);
        if (row == null) {
            row = sheet.createRow(rowNum);
        }

        // 获取或创建单元格
        Cell cell = row.getCell(cellNum);
        if (cell == null) {
            cell = row.createCell(cellNum);
        }

        // 设置单元格的值
        if (StringUtils.isNotEmpty(value)) {
            cell.setCellValue(value);
        }
        CellStyle cellStyle = null;
        if (style != null) {
            cellStyle = style;
        } else {
            // 尝试复制同一行上一列的格式
            if (isCopyCellStyle && cellNum > 0) {
                Cell previousColCell = row.getCell(cellNum - 1);
                if (previousColCell != null) {
                    cellStyle = previousColCell.getCellStyle();
                }
            }
            // 如果没有提供样式,则尝试复制上一行相同列的格式
            if (isCopyRowStyle) {
                if (rowNum > 0) {
                    Row previousRow = sheet.getRow(rowNum - 1);
                    if (previousRow != null) {
                        Cell previousCell = previousRow.getCell(cellNum);
                        if (previousCell != null) {
                            cellStyle = previousCell.getCellStyle();
                        }
                    }
                }
            }
        }
        // 如果上一行同列有样式,则使用该样式;否则使用默认居中样式
        if (cellStyle != null) {
            cell.setCellStyle(cellStyle);
        } else {
            if (cell.getCellStyle() == null) {
                CellStyle defaultStyle = workbook.createCellStyle();
                defaultStyle.setAlignment(HorizontalAlignment.CENTER);
                defaultStyle.setVerticalAlignment(VerticalAlignment.CENTER);
                cell.setCellStyle(defaultStyle);
            }
        }

        return cell;
    }

    /**
     * 在指定的行和列设置单元格的值(使用默认居中样式)
     *
     * @param sheet    Excel工作表
     * @param workbook Excel工作簿
     * @param rowNum   行号(从0开始)
     * @param cellNum  列号(从0开始)
     * @param value    要设置的值
     * @return 设置的单元格
     */
    public static Cell setCellValue(Sheet sheet, Workbook workbook, int rowNum, int cellNum, String value) {
        return setCellValueAndStyle(sheet, workbook, rowNum, cellNum, value, null, false, false);
    }

    /**
     * 在指定的行和列设置单元格值(使用默认居中样式)
     *
     * @param sheet    Excel工作表
     * @param workbook Excel工作簿
     * @param rowNum   行号(从1开始)
     * @param cellNum  列号(如"A", "H", "AA")
     * @param value    要设置的值
     * @return 设置的单元格
     */
    public static Cell setCellValueByColumn(Sheet sheet, Workbook workbook, int rowNum, String cellNum, String value) {
        return setCellValueByColumn(sheet, workbook, rowNum, cellNum, value, null, false, false);
    }

    /**
     * 在指定的行和列设置单元格值(使用默认居中样式)
     *
     * @param sheet           Excel工作表
     * @param workbook        Excel工作簿
     * @param rowNum          行号(从1开始)
     * @param cellNum         列号(如"A", "H", "AA")
     * @param value           要设置的值
     * @param style           单元格样式,如果为null则使用默认样式
     * @param isCopyRowStyle  是否复制上一行相同列的样式
     * @param isCopyCellStyle 是否复制同一行上一列的样式
     * @return 设置的单元格
     */
    public static Cell setCellValueByColumn(Sheet sheet, Workbook workbook, int rowNum, String cellNum, String value,
                                            CellStyle style,
                                            boolean isCopyRowStyle, boolean isCopyCellStyle) {
        int rowNumInt = rowNum - 1;
        int cellNumInt = columnToNumber(cellNum);  // 将列标识转换为数字索引
        return setCellValueAndStyle(sheet, workbook, rowNumInt, cellNumInt, value, style, isCopyRowStyle, isCopyCellStyle);
    }

    /**
     * 将Excel列标识(如 "A", "H", "AA")转换为数字索引(从0开始)
     *
     * @param cellNum Excel列标识,例如 "A", "H", "AA"
     * @return 对应的数字索引,从0开始
     */
    public static int columnToNumber(String cellNum) {
        int result = 0;
        for (int i = 0; i < cellNum.length(); i++) {
            char c = cellNum.charAt(i);
            // 每一位代表26进制的一位,但没有0,A=1, B=2, ..., Z=26
            result = result * 26 + (c - 'A' + 1);
        }
        // 转换为从0开始的索引
        return result - 1;
    }

    /**
     * 时间转换方法,将日期转换为指定格式的字符串
     *
     * @param date    日期对象
     * @param pattern 日期格式
     * @return 转换后的日期字符串,如果日期为空则返回空字符串
     */
    public static String formatDate(Object date, String pattern) {
        if (date == null) {
            return "";
        }

        try {
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            if (date instanceof Date) {
                return sdf.format((Date) date);
            } else if (date instanceof String) {
                // 如果是字符串,先尝试解析再格式化
                Date parsedDate = sdf.parse((String) date);
                return sdf.format(parsedDate);
            } else {
                // 其他类型尝试转换为字符串再处理
                String dateStr = String.valueOf(date);
                if (dateStr.matches("\\d{4}-\\d{2}-\\d{2}.*")) {
                    // 简单匹配日期格式
                    return dateStr;
                }
                return dateStr;
            }
        } catch (Exception e) {
            // 发生异常时返回原始值的字符串形式
            return String.valueOf(date);
        }

    }

    /**
     * 将Long类型转换为带千位分隔符的String类型
     *
     * @param value Long类型的值
     * @return 格式化后的String类型值
     */
    public static String longToFormattedString(Long value) {
        if (value == null) {
            return "";
        }
        return String.format("%,d", value);
    }

    /**
     * 将Long类型转换为指定格式的String类型
     *
     * @param value  Long类型的值
     * @param format 格式化字符串
     * @return 格式化后的String类型值
     */
    public static String longToStringWithFormat(Long value, String format) {
        if (value == null || format == null) {
            return value == null ? "" : String.valueOf(value);
        }
        return String.format(format, value);
    }

    /**
     * 安全的Integer转String方法,包含空值判断
     *
     * @param value 待转换的Integer值
     * @return 转换后的String,如果输入为null则返回空字符串
     */
    public static String integerToString(Integer value) {
        if (value == null) {
            return "";
        }
        return String.valueOf(value);
    }

    /**
     * 将BigDecimal转换为指定格式的字符串
     *
     * @param value         BigDecimal值
     * @param formatPattern 格式模式,如 "0.00", "#,##0.00" 等
     * @return 格式化后的字符串
     */
    public static String formatBigDecimal(BigDecimal value, String formatPattern) {
        if (value == null) {
            return "";
        }
        DecimalFormat df = new DecimalFormat(formatPattern);
        return df.format(value);
    }

    /**
     * 设置单元格为数字格式样式
     *
     * @param workbook      工作簿
     * @param formatPattern 数字格式模式
     * @return 数字格式的单元格样式
     */
    public static CellStyle createNumberCellStyle(Workbook workbook, String formatPattern) {
        CellStyle style = workbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);

        // 设置数字格式
        DataFormat format = workbook.createDataFormat();
        style.setDataFormat(format.getFormat(formatPattern));

        return style;
    }
相关推荐
cxyxiaokui0011 分钟前
线程池的“变形记”:核心线程数居然能随时变大变小?
java·面试
灵魂猎手8 分钟前
11. Mybatis SQL解析源码分析
java·后端·源码
努力的小郑36 分钟前
别再说你会 new Object() 了!JVM 类加载的真相,绝对和你想的不一样
java·jvm·面试
cxyxiaokui00141 分钟前
论如何优雅地让AI“闭嘴”:深入SpringAI的流式停止与记忆难题
java·后端
嗝屁小孩纸44 分钟前
使用EasyExcel自定义导出表格
java·excel
秦禹辰1 小时前
本地Docker部署开源Web相册图库Piwigo与在线远程访问实战方案
开发语言·后端·golang
the beard1 小时前
深入理解Java多线程:状态、安全、同步与通信
java·开发语言
pengzhuofan1 小时前
Java设计模式-享元模式
java·设计模式·享元模式
灵魂猎手2 小时前
10. Mybatis XML配置到SQL的转换之旅
java·后端·源码
掉鱼的猫2 小时前
10分钟带你体验 Solon 的状态机
java