EasyExcel处理复杂Excel模版导出

EasyExcel处理复杂Excel模版导出

  • 近期有功能涉及到需要excel单元格合并的模版导出,正巧最近有EasyExcel作者创业的消息,写一篇使用案例支持FastExcel继续更新。
  • 官网 easyexcel.opensource.alibaba.com/
  • 代码 gitcode.com/gh_mirrors/...
  • 建议还是把代码拉下来,可以看到里面有很多作者写的测试类。我们想要实现某些功能的话,可以直接参考官方demo。

模版制作

目标样式如下图: 经过拆分可以把问题分为:

  1. 基本的数据填充
  2. 颜色数据的填充
  3. 列表数据的填充
  4. 单元格的合并 先根据{param}替换参数的方式一一解决问题

基础数据填充

按照官方的demo,简单的表格导出可以横向填充数据也可以纵向填充数据,但是我们的表格是需要自定义的,所以只能通过模版填充的形式去实现。使用EasyExcel 利用模板填充的方式,就是以一个单元格 为最小单位,把数据全部查出来 ,然后将数据处理成一行一行的形式进行填充,碰到相同的数据,就进行合并单元格。

基础的数据填充使用map做参数对照,对应模版上的{参数名}即可正确填充

javascript 复制代码
// 表格数据填充
Map<String, String> fileData = getData(assessmentTemplateData);

//单行数据
excelWriter.fill(fileData, writeSheet);

颜色数据填充

使用 CustomRowStyleStrategy 编写某个单元格的颜色背景

java 复制代码
import com.alibaba.excel.write.handler.AbstractRowWriteHandler;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.IndexedColors;

public class CustomRowStyleStrategy extends AbstractRowWriteHandler {
    private final int targetRow; // 目标行号
    private final short color;   // 背景颜色

    public CustomRowStyleStrategy(int targetRow, short color) {
        this.targetRow = targetRow;
        this.color = color;
    }

    @Override
    protected void afterRowCreate(com.alibaba.excel.metadata.Head head, com.alibaba.excel.write.metadata.holder.WriteSheetHolder writeSheetHolder, Integer relativeRowIndex, Boolean isHead) {
        if (relativeRowIndex == targetRow) {
            // 获取当前行的所有单元格样式
            for (int i = 0; i < 10; i++) { // 假设最多有10列
                CellStyle cellStyle = writeSheetHolder.getSheet().getWorkbook().createCellStyle();
                cellStyle.setFillForegroundColor(color);
                cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
                writeSheetHolder.getSheet().setColumnWidth(i, 20 * 256); // 设置列宽
                writeSheetHolder.getSheet().getRow(relativeRowIndex).getCell(i).setCellStyle(cellStyle);
            }
        }
    }
}
ini 复制代码
// 假设你想为第5行(索引从0开始)设置红色背景
int targetRow = 5;
short color = IndexedColors.RED.getIndex();

// 注册自定义行样式策略
excelWriter.registerWriteHandler(new CustomRowStyleStrategy(targetRow, color));

列表数据填充

列表数据可以使用一个对象进行控制,然后对象的属性和模版的{实体类.属性名}对应上,进行循环填充

ini 复制代码
// 列表数据填充
List<AssessmentTemplate> list = tableDataMap.get(assessmentTemplateData);

//列表循环数据
if (CollectionUtils.isNotEmpty(list)) {
    FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
    excelWriter.fill(new FillWrapper("details", list), fillConfig, writeSheet);
}

单元格的合并

我是重写了单元格合并的策略类,然后注册到writter里进行操作

ExcelFillCellMergeLineUtils

java 复制代码
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 列合并工具类
 */
public class ExcelFillCellMergeLineUtils implements CellWriteHandler {

    private static final String KEY = "%s-%s";
    // 所有的合并信息都存在了这个map里面
    private Map<String, int[]> mergeInfo = new HashMap<>();

    public ExcelFillCellMergeLineUtils() {
    }

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {
    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) {
    }

    @Override
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, WriteCellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {
    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
        // 当前行
        int curRowIndex = cell.getRowIndex();
        // 当前列
        int curColIndex = cell.getColumnIndex();

        int[] mergeColumns = mergeInfo.get(String.format(KEY, curRowIndex, curColIndex));
        if (mergeColumns != null) {
            // 合并最后一行, 列
            mergeWithPrevCol(writeSheetHolder, cell, curRowIndex, curColIndex, mergeColumns);
        }
    }

    public void mergeWithPrevCol(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex, int[] mergeColumns) {
        Sheet sheet = writeSheetHolder.getSheet();

        for (int i = 0; i < mergeColumns.length; i += 2) {
            int startColIndex = mergeColumns[i];
            int num = mergeColumns[i + 1];

            if (startColIndex + num < startColIndex) {
                throw new IllegalArgumentException("合并列范围无效: startColIndex=" + startColIndex + ", num=" + num);
            }

            CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex, curRowIndex, startColIndex, startColIndex + num);

            // 检查是否已经合并
            for (int j = 0; j < sheet.getNumMergedRegions(); j++) {
                CellRangeAddress existingRegion = sheet.getMergedRegion(j);
                if (existingRegion.intersects(cellRangeAddress)) {
                    throw new IllegalStateException("目标区域已被合并: " + cellRangeAddress);
                }
            }

            // 添加合并区域
            sheet.addMergedRegion(cellRangeAddress);
        }
    }


    // 添加需要合并的列信息
    // 例如:第5行从第5列开始合并3列,从第8列开始合并3列
    // add(4, 4, 2, 7, 2); 表示第5行的第5列到第7列合并,第8列到第10列合并
    public void add(int curRowIndex, int startColIndex1, int num1, int startColIndex2, int num2) {
        mergeInfo.put(String.format(KEY, curRowIndex, startColIndex1), new int[]{startColIndex1, num1, startColIndex2, num2});
    }

    public void add(int curRowIndex, int... columns) {
        if (columns.length % 2 != 0) {
            throw new IllegalArgumentException("列信息必须成对出现(起始列索引和合并数量)");
        }
        mergeInfo.put(String.format(KEY, curRowIndex, columns[0]), columns);
    }
}

ExcelFillCellMergeRowUtils

java 复制代码
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.ArrayList;
import java.util.List;

/**
 * 行合并工具类
 */
public class ExcelFillCellMergeRowUtils implements CellWriteHandler {

    private static final String KEY = "%s-%s";
    // 所有的合并信息都存在了这个map里面

    private static class CellMerge {
        int colIndex;
        int startRow;
        int num;

        public CellMerge(int colIndex, int startRow, int num) {
            this.colIndex = colIndex;
            this.startRow = startRow;
            this.num = num;
        }
    }

    private List<CellMerge> mergeList = new ArrayList<>();

    public ExcelFillCellMergeRowUtils() {
    }

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {
    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) {
    }

    @Override
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, WriteCellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {
    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
        Sheet sheet = writeSheetHolder.getSheet();
        int curRowIndex = cell.getRowIndex();
        int curColIndex = cell.getColumnIndex();

        for (CellMerge merge : mergeList) {
            if (merge.colIndex == curColIndex && merge.startRow == curRowIndex) {
                CellRangeAddress region = new CellRangeAddress(
                        merge.startRow,
                        merge.startRow + merge.num - 1,
                        merge.colIndex,
                        merge.colIndex
                );

                for (int j = 0; j < sheet.getNumMergedRegions(); j++) {
                    CellRangeAddress existingRegion = sheet.getMergedRegion(j);
                    if (existingRegion.intersects(region)) {
                        throw new IllegalStateException("目标区域已被合并: " + region.formatAsString());
                    }
                }
                sheet.addMergedRegion(region);

            }
        }
    }

    // 添加需要合并的行信息
    // 例如:第5列从第5行开始合并3行,从第8行开始合并3行
    // add(4, 4, 2, 7, 2); 表示第5列的第5行到第7行合并,第8行到第10行合并


    public void add(int curColIndex, int... rows) {
        if (rows.length % 2 != 0) {
            throw new IllegalArgumentException("行信息必须成对出现(起始行索引和合并数量)");
        }

        for (int i = 0; i < rows.length; i += 2) {
            int startRow = rows[i];
            int num = rows[i + 1];
            mergeList.add(new CellMerge(curColIndex, startRow, num));
        }
    }
}

行合并的业务逻辑

ini 复制代码
/**
 * 行合并
 * @param list
 * @param mergeRowUtils
 */
private static void mergeRow(List<AssessmentTemplate> list, ExcelFillCellMergeRowUtils mergeRowUtils) {
    if (CollectionUtils.isNotEmpty(list)) {
        // 从第五行开始(索引为4),合并第二列和第三列
        String prevSecondColValue = null;
        String prevThirdColValue = null;
        int startRowSecondCol = 4; // 第五行的索引
        int startRowThirdCol = 4; // 第五行的索引
        List<int[]> mergeSecondRanges = new ArrayList<>();
        List<int[]> mergeThirdRanges = new ArrayList<>();
        // 循环列表行
        for (int i = 0; i < list.size(); i++) {
            AssessmentTemplate assessmentTemplate = list.get(i);
            String secondColValue = assessmentTemplate.getIndicatorType(); // 第二列是 考核维度类型
            String thirdColValue = assessmentTemplate.getIndicator(); // 第三列是 考核维度
            // 处理第二列合并
            if (i == 0 || !secondColValue.equals(prevSecondColValue)) {
                // 上一组结束,添加合并范围
                if (i > 0 && (i - startRowSecondCol + 4) > 1) {
                    mergeSecondRanges.add(new int[]{1, startRowSecondCol, i - startRowSecondCol + 4}); // 第二列合并
                }
                // 新的一组开始
                startRowSecondCol = 4 + i;
            }
            // 处理第三列合并
            if (i == 0 || !thirdColValue.equals(prevThirdColValue)) {
                if (i > 0 && (i - startRowThirdCol + 4) > 1) {
                    mergeThirdRanges.add(new int[]{2, startRowThirdCol, i - startRowThirdCol + 4}); // 第三列合并
                }
                startRowThirdCol = 4 + i;
            }
            prevSecondColValue = secondColValue;
            prevThirdColValue = thirdColValue;
        }
        // 添加最后一组的合并
        if (!list.isEmpty()) {
            if((list.size() - startRowSecondCol + 4) > 1){
                mergeSecondRanges.add(new int[]{1, startRowSecondCol, list.size() - startRowSecondCol + 4});
            }
            if((list.size() - startRowThirdCol + 4) > 1){
                mergeThirdRanges.add(new int[]{2, startRowThirdCol, list.size() - startRowThirdCol + 4});
            }
        }
        // 执行所有合并操作
        mergeThirdRanges.sort((a, b) -> Integer.compare(a[1], b[1])); // 按起始行排序
        mergeSecondRanges.sort((a, b) -> Integer.compare(a[1], b[1])); // 按起始行排序
        for (int[] range : mergeSecondRanges) {
            mergeRowUtils.add(range[0], range[1], range[2]);
        }
        for (int[] range : mergeThirdRanges) {
            mergeRowUtils.add(range[0], range[1], range[2]);
        }
    }
}

可以根据业务进行 mergeRowUtils操作需要合并的单元格位置,需要注意的是工具类对单元格冲突的问题我采取了直接报错的方式,如果对单元格合并冲突有其他业务要求可以改为其他方式处理。

完整处理代码

controller层方法 可以单个导出也可以批量导出,批量导出可以转为压缩包

ini 复制代码
/**
 * 批量打包导出
 *
 * @param response
 * @param ids
 */
@GetMapping("/exportAssessmentInfo")
public void exportAssessmentInfoForZip(HttpServletResponse response, @RequestParam Long[] ids) {
    if (ids == null || ids.length == 0) {
        throw new ServiceException("参数错误");
    }
    try {
        // 统一获取数据
        Map<String, byte[]> excelBytesMap = assessmentDetailService.exportSingleAssessmentInfo(ids);
        if (excelBytesMap.isEmpty()) {
            throw new ServiceException("未找到可导出的数据");
        }
        if (ids.length == 1) {
            //导出单个excel
            String fileName = excelBytesMap.keySet().iterator().next();
            byte[] bytes = excelBytesMap.get(fileName);
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" +
                    URLEncoder.encode(fileName, StandardCharsets.UTF_8));
            try (ServletOutputStream outputStream = response.getOutputStream()) {
                outputStream.write(bytes);
                outputStream.flush();
            } catch (Exception e) {
                log.error("导出Excel失败:{}", e.getMessage(), e);
            }
        } else {
            // 导出多个文件打包为ZIP
            String zipFileName = "考核信息-" + System.currentTimeMillis() + ".zip";
            response.setContentType("application/zip");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" +
                    URLEncoder.encode(zipFileName, StandardCharsets.UTF_8));
            try (ServletOutputStream outputStream = response.getOutputStream();
                 ZipArchiveOutputStream zipOutputStream = new ZipArchiveOutputStream(outputStream)) {
                for (Map.Entry<String, byte[]> entry : excelBytesMap.entrySet()) {
                    String fileName = entry.getKey();
                    byte[] bytes = entry.getValue();
                    try {
                        zipOutputStream.putArchiveEntry(new ZipArchiveEntry(fileName));
                        zipOutputStream.write(bytes);
                        zipOutputStream.closeArchiveEntry();
                    } catch (Exception e) {
                        log.error("添加文件[{}]到压缩包失败", fileName, e);
                    }
                }
                zipOutputStream.finish();
                outputStream.flush();
            } catch (IOException e) {
                log.error("导出ZIP失败:{}", e.getMessage(), e);
                throw new ServiceException("导出失败:" + e.getMessage());
            }
        }
    } catch (Exception e) {
        log.error("批量导出失败:{}", e.getMessage(), e);
        throw new ServiceException("系统异常,请联系管理员");
    }
}

数据获取后的表格处理,转换为内存流

scss 复制代码
/**
 * 导出
 */
public Map<String,byte[]> exportSingleAssessmentInfo(Long[] assessmentDetailIds) throws Exception {
    Map<String,byte[]> result = new HashMap<>();
    // 1. 数据获取
    Map<AssessmentTemplateData, List<AssessmentTemplate>> tableDataMap = getTableData(assessmentDetailIds);
    // 2. 表格处理
    for (AssessmentTemplateData assessmentTemplateData : tableDataMap.keySet()) {
        String excelName = assessmentTemplateData.getExcelName();
        // 表格数据填充
        Map<String, String> fileData = getData(assessmentTemplateData);
        // 列表数据填充
        List<AssessmentTemplate> list = tableDataMap.get(assessmentTemplateData);
        // 列合并(合并考核目标 以及考核依据)
        ExcelFillCellMergeLineUtils mergeLineUtils = new ExcelFillCellMergeLineUtils();
        //首行不需要合并,新增的行都需要合并
        for (int i = 0; i < list.size(); i++) {
            int rowIndex = 4 + i;
            mergeLineUtils.add(rowIndex, 5, 2, 8, 2);
        }
        // 行合并
        ExcelFillCellMergeRowUtils mergeRowUtils = new ExcelFillCellMergeRowUtils();
        // 行合并逻辑
        mergeRow(list, mergeRowUtils);
        // 3. 构建流返回
        try (InputStream template = getTemplateInputStream()) {
            if (ObjectUtils.isEmpty(template)) {
                throw new ServiceException("模板文件不存在");
            }
            // 写入内存流
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            //写入到内存流
            try (ExcelWriter excelWriter = EasyExcel.write(byteArrayOutputStream).withTemplate(template)
                    .registerWriteHandler(new CustomStyleStrategy())
                    .registerWriteHandler(mergeLineUtils)
                    .registerWriteHandler(mergeRowUtils)
                    .build()) {
                //构建excel的sheet
                WriteSheet writeSheet = EasyExcel.writerSheet().build();
                //列表循环数据
                if (CollectionUtils.isNotEmpty(list)) {
                    FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
                    excelWriter.fill(new FillWrapper("details", list), fillConfig, writeSheet);
                }
                //单行数据
                excelWriter.fill(fileData, writeSheet);
                excelWriter.finish();
            }
            result.put(excelName, byteArrayOutputStream.toByteArray());
        } catch (Exception e) {
            log.error("导出考核信息失败: {}", e.getMessage(), e);
            throw new ServiceException("导出失败:" + e.getMessage());
        }

    }
    return result;
}

操作方法

java 复制代码
/**
 * 行合并
 * @param list
 * @param mergeRowUtils
 */
private static void mergeRow(List<AssessmentTemplate> list, ExcelFillCellMergeRowUtils mergeRowUtils) {
    if (CollectionUtils.isNotEmpty(list)) {
        // 从第五行开始(索引为4),合并第二列和第三列
        String prevSecondColValue = null;
        String prevThirdColValue = null;
        int startRowSecondCol = 4; // 第五行的索引
        int startRowThirdCol = 4; // 第五行的索引
        List<int[]> mergeSecondRanges = new ArrayList<>();
        List<int[]> mergeThirdRanges = new ArrayList<>();
        // 循环列表行
        for (int i = 0; i < list.size(); i++) {
            AssessmentTemplate assessmentTemplate = list.get(i);
            String secondColValue = assessmentTemplate.getIndicatorType(); // 第二列是 考核维度类型
            String thirdColValue = assessmentTemplate.getIndicator(); // 第三列是 考核维度
            // 处理第二列合并
            if (i == 0 || !secondColValue.equals(prevSecondColValue)) {
                // 上一组结束,添加合并范围
                if (i > 0 && (i - startRowSecondCol + 4) > 1) {
                    mergeSecondRanges.add(new int[]{1, startRowSecondCol, i - startRowSecondCol + 4}); // 第二列合并
                }
                // 新的一组开始
                startRowSecondCol = 4 + i;
            }
            // 处理第三列合并
            if (i == 0 || !thirdColValue.equals(prevThirdColValue)) {
                if (i > 0 && (i - startRowThirdCol + 4) > 1) {
                    mergeThirdRanges.add(new int[]{2, startRowThirdCol, i - startRowThirdCol + 4}); // 第三列合并
                }
                startRowThirdCol = 4 + i;
            }
            prevSecondColValue = secondColValue;
            prevThirdColValue = thirdColValue;
        }
        // 添加最后一组的合并
        if (!list.isEmpty()) {
            if((list.size() - startRowSecondCol + 4) > 1){
                mergeSecondRanges.add(new int[]{1, startRowSecondCol, list.size() - startRowSecondCol + 4});
            }
            if((list.size() - startRowThirdCol + 4) > 1){
                mergeThirdRanges.add(new int[]{2, startRowThirdCol, list.size() - startRowThirdCol + 4});
            }
        }
        // 执行所有合并操作
        mergeThirdRanges.sort((a, b) -> Integer.compare(a[1], b[1])); // 按起始行排序
        mergeSecondRanges.sort((a, b) -> Integer.compare(a[1], b[1])); // 按起始行排序
        for (int[] range : mergeSecondRanges) {
            mergeRowUtils.add(range[0], range[1], range[2]);
        }
        for (int[] range : mergeThirdRanges) {
            mergeRowUtils.add(range[0], range[1], range[2]);
        }
    }
}

/**
 * 获取模版输入流
 *
 * @return
 * @throws IOException
 */
private InputStream getTemplateInputStream() throws IOException {
    return new PathMatchingResourcePatternResolver()
            .getResource("templates/AssessmentTemplate.xlsx").getInputStream();
}

/**
 * 设置模版名称字体样式
 *
 * @param cellStyleMap
 */
private void templateSetRed(Map<String, CustomCellStyleHandler.CellStyleInfo> cellStyleMap, String templateName) {
    // 示例:设置第六行第三列的样式
    String text2 = "绩效考核评估表(" + templateName + ")";
    List<int[]> redIndexRanges2 = new ArrayList<>();
    redIndexRanges2.add(new int[]{8, 12}); // 红色部分
    cellStyleMap.put("0_1", new CustomCellStyleHandler.CellStyleInfo(text2, redIndexRanges2));
}

/**
 * 主体内容
 *
 * @param assessmentTemplateData
 * @return
 */
private Map<String, String> getData(AssessmentTemplateData assessmentTemplateData) {
    Map<String, String> fileData = new HashMap<>();
    // 模板名称
    fileData.put("template_name", assessmentTemplateData.getTemplateName() == null ? "" : assessmentTemplateData.getTemplateName());
    // 所属部门
    fileData.put("department", assessmentTemplateData.getDepartment() == null ? "" : assessmentTemplateData.getDepartment());
    // 岗位
    fileData.put("post", assessmentTemplateData.getPost() == null ? "" : assessmentTemplateData.getPost());
    // 被考核人
    fileData.put("name", assessmentTemplateData.getName() == null ? "" : assessmentTemplateData.getName());
    // 评分人
    fileData.put("evaluator", assessmentTemplateData.getEvaluator() == null ? "" : assessmentTemplateData.getEvaluator());
    // 考核周期
    fileData.put("period", assessmentTemplateData.getPeriod() == null ? "" : assessmentTemplateData.getPeriod());
    // 目标确认被考核对象
    fileData.put("target_assessed_person_name", assessmentTemplateData.getTargetAssessedPersonName() == null ? "" : assessmentTemplateData.getTargetAssessedPersonName());
    // 目标确认考核人
    fileData.put("target_assess_person_name", assessmentTemplateData.getTargetAssessPersonName() == null ? "" : assessmentTemplateData.getTargetAssessPersonName());
    // 目标确认时间
    fileData.put("target_assessed_date", assessmentTemplateData.getTargetAssessedDate() == null ? "" : assessmentTemplateData.getTargetAssessedDate());
    // 结果确认被考核对象
    fileData.put("result_assessed_person_name", assessmentTemplateData.getResultAssessedPersonName() == null ? "" : assessmentTemplateData.getResultAssessedPersonName());
    // 结果确认考核人
    fileData.put("result_assess_person_name", assessmentTemplateData.getResultAssessPersonName() == null ? "" : assessmentTemplateData.getResultAssessPersonName());
    // 结果确认时间
    fileData.put("result_assessed_date", assessmentTemplateData.getResultAssessedDate() == null ? "" : assessmentTemplateData.getResultAssessedDate());
    // 复盘备注 或者 其他内容
    fileData.put("content", assessmentTemplateData.getContent() == null ? "" : assessmentTemplateData.getContent());
    return fileData;

}

大致就是以上内容,希望可以帮到你!

相关推荐
uzong3 小时前
技术故障复盘模版
后端
GetcharZp4 小时前
基于 Dify + 通义千问的多模态大模型 搭建发票识别 Agent
后端·llm·agent
桦说编程4 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
IT毕设实战小研4 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi5 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
阿华的代码王国6 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
Jimmy6 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
AntBlack6 小时前
不当韭菜V1.1 :增强能力 ,辅助构建自己的交易规则
后端·python·pyqt
bobz9657 小时前
pip install 已经不再安全
后端
寻月隐君7 小时前
硬核实战:从零到一,用 Rust 和 Axum 构建高性能聊天服务后端
后端·rust·github