POI动态合并单元格,添加计算公式

昨天整了一天,记录以后方便查看。

/**
     * 设置单元格样式
     *
     * @param workbook
     * @param cell
     */
    private static void setBodrerStyle(HSSFWorkbook workbook, HSSFCell cell) {
        if (cell != null) {
            HSSFCellStyle cellStyle = workbook.createCellStyle();       // 单元格样式

            cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);         // 水平居中
            cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 垂直居中

            cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);       //下边框
            cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);         //左边框
            cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);          //上边框
            cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);        //右边框

            cellStyle.setWrapText(true);                                // 自动换行

//            sheet.autoSizeColumn(1, true);          // 自动适应宽度
            cell.setCellStyle(cellStyle);
        }
    }

    /**
     * 动态合并行
     *
     * @param sheet
     * @param mergedRegion 需要合并的列集合
     * @param colIndex     当前列
     * @param row          当前行
     * @param value        单元格值
     * @return
     */
    private static boolean mergedRegion(HSSFSheet sheet, Integer[] mergedRegion, int colIndex, int row, Object value) {
        // 合并单元格
        for (Integer col : mergedRegion) {
            if (colIndex == col) {
                int firstRow = 0;
                // 从下往上合并原则
                // 得到上一个单元格的开始下标
                if ((firstRow = equals(sheet, colIndex, row, value)) < row) {
                    sheet.addMergedRegion(new CellRangeAddress(firstRow, row, col, col));
                    // 合并后重新设置样式
//                    setBodrerStyle(sheet.getWorkbook(), sheet.getRow(firstRow).getCell(col));
                    return true;
                }
                break;
            }
        }
        return false;
    }

    private static int equals(HSSFSheet sheet, int colIndex, int row, Object value) {
        // 获取上一个单元格
        int firstRow = isMergedRegion(sheet, row - 1, colIndex);
        Object lastCellValue = ExcelUtils.getCellFormatValue(sheet.getRow(firstRow).getCell(colIndex));
        if (value != null && value.equals(lastCellValue)) {
            return firstRow;
        }
        return row;
    }

    private static int isMergedRegion(HSSFSheet sheet, int row, int column) {
        int sheetMergeCount = sheet.getNumMergedRegions();
        for (int i = 0; i < sheetMergeCount; i++) {
            CellRangeAddress range = sheet.getMergedRegion(i);
            int firstColumn = range.getFirstColumn();
            int lastColumn = range.getLastColumn();
            int firstRow = range.getFirstRow();
            int lastRow = range.getLastRow();
            if (row >= firstRow && row <= lastRow) {
                if (column >= firstColumn && column <= lastColumn) {
//                    return new Result(true, firstRow + 1, lastRow + 1, firstColumn + 1, lastColumn + 1);
                    return firstRow;
                }
            }
        }
        return row;
    }

    /**
     * 设置公式
     *
     * @param sheet
     * @param rowNum
     * @param formula
     * @param propertyNames
     * @return
     */
    private static String setFormula(HSSFSheet sheet, int rowNum, int col, String formula, String[] propertyNames) {
        if (StringUtils.isNotEmpty(formula)) {
            // 第一位 公式
            // 第二位 取值列
            // 第三位 参考合并
            String[] vals = formula.split(":");
            if (vals.length == 3) {
                int pi = 1, pe = 0;
                boolean ib = false, eb = false;
                for (String property : propertyNames) {
                    if (!property.equals(vals[1]) && !ib) {
                        pi++;
                    } else {
                        ib = true;
                    }
                    if (!property.equals(vals[2]) && !eb) {
                        pe++;
                    } else {
                        eb = true;
                    }
                    if (ib && eb) break;
                }
                String rowName = NumberToChar.getMsg(pi);

                // 取参考合并列
                int fristRow = isMergedRegion(sheet, rowNum, pe);
                formula = vals[0] + "(" + rowName + (fristRow + 1) + ":" + rowName + (rowNum + 1) + ")";
                if (fristRow != rowNum) {
                    CellRangeAddress cellRangeAddress = new CellRangeAddress(fristRow, rowNum, col, col);
                    sheet.addMergedRegion(cellRangeAddress);
                }
                logger.debug("第{}行第{}列,设置公式:{}", fristRow, col, formula);

                HSSFRow row = sheet.getRow(fristRow);
                HSSFCell cell = row.getCell(col);
                if (cell == null) cell = row.createCell(col);
                cell.setCellFormula(formula);
            }
        }
        return formula;
    }

    /**
     * 写一行数据
     *
     * @param row
     * @param resultObject  值
     * @param propertyNames 属性列
     * @param formatPropers 格式化值(取数据字典)
     * @param mergedRegion  合并列索引
     * @param evaluators    计算公式列
     */
    private static void WriteOneRowToExcel(HSSFRow row, Object resultObject, String[] propertyNames, String[] formatPropers, Integer[] mergedRegion, Map<String, String> evaluators) {
        HSSFSheet sheet = row.getSheet();
        HSSFWorkbook workbook = sheet.getWorkbook();
        try {
            int rowNum = row.getRowNum();
            for (int i = 0; i < propertyNames.length; i++) {
                String name = propertyNames[i];
                if (StringUtils.isEmpty(name)) continue;

                Object value = null;
                if (resultObject instanceof Map) {
                    Map temp = (Map) resultObject;
                    value = temp.get(name);
                } else if (name.contains(".")) {
                    String[] nameArr = name.split("\\.");
                    Object innerObjectvalue = PropertyUtils.getSimpleProperty(resultObject, nameArr[0]);
                    if (innerObjectvalue != null) {
                        value = PropertyUtils.getSimpleProperty(innerObjectvalue, nameArr[1]);
                    }
                } else {
                    value = PropertyUtils.getSimpleProperty(resultObject, name);
                }
                if (value == null) continue;
                for (String formatProper : formatPropers) {
                    if (formatProper.equals(name)) {
                        value = DictUtils.getDictLabel(value.toString(), formatProper, null);
                        break;
                    }
                }
                // 公式 判断
                String formula = setFormula(sheet, rowNum, i, evaluators.get(name), propertyNames);
                if (!mergedRegion(sheet, mergedRegion, i, rowNum, value) && !StringUtils.isNotEmpty(formula)) {
                    HSSFCell cell = row.createCell(i);
//                    setBodrerStyle(workbook, cell);
                    String typeName = value.getClass().getName();
                    switch (typeName) {
                        case "java.lang.String": {
                            HSSFRichTextString cellText = new HSSFRichTextString(value.toString());
                            cell.setCellValue(cellText);
                            break;
                        }
                        case "java.util.Date":
                        case "java.sql.Timestamp":
                            cell.setCellValue((Date) value);
                            cell.setCellStyle(dateStyle);
                            break;
                        case "java.lang.Double":
                        case "java.lang.Float":
                            cell.setCellValue(((Double) value).doubleValue());
                            cell.setCellStyle(decmialStyle);
                            break;
                        case "java.lang.Long":
                        case "java.lang.Short":
                            cell.setCellValue(((Long) value).doubleValue());
                            cell.setCellStyle(numberStyle);
                            break;
                        case "java.math.BigDecimal":
                            cell.setCellValue(((BigDecimal) value).doubleValue());
                            cell.setCellStyle(decmialStyle);
                            break;
                        case "java.lang.Integer":
                            cell.setCellValue(((Integer) value).intValue());
                            cell.setCellStyle(numberStyle);
                            break;
                        default: {
                            HSSFRichTextString cellText = new HSSFRichTextString(value.toString());
                            cell.setCellValue(cellText);
                            break;
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

猜你喜欢

转载自blog.csdn.net/xiaxiaolin_yun/article/details/86624003