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;

}

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

相关推荐
小蒜学长17 分钟前
springboot多功能智能手机阅读APP设计与实现(代码+数据库+LW)
java·spring boot·后端·智能手机
追逐时光者1 小时前
精选 4 款开源免费、美观实用的 MAUI UI 组件库,助力轻松构建美观且功能丰富的应用程序!
后端·.net
你的人类朋友2 小时前
【Docker】说说卷挂载与绑定挂载
后端·docker·容器
间彧3 小时前
在高并发场景下,如何平衡QPS和TPS的监控资源消耗?
后端
间彧3 小时前
QPS和TPS的区别,在实际项目中,如何准确测量和监控QPS和TPS?
后端
间彧3 小时前
消息队列(RocketMQ、RabbitMQ、Kafka、ActiveMQ)对比与选型指南
后端·消息队列
brzhang4 小时前
AI Agent 干不好活,不是它笨,告诉你一个残忍的现实,是你给他的工具太难用了
前端·后端·架构
brzhang4 小时前
一文说明白为什么现在 AI Agent 都把重点放在上下文工程(context engineering)上?
前端·后端·架构
Roye_ack5 小时前
【项目实战 Day9】springboot + vue 苍穹外卖系统(用户端订单模块 + 商家端订单管理模块 完结)
java·vue.js·spring boot·后端·mybatis
AAA修煤气灶刘哥6 小时前
面试必问的CAS和ConcurrentHashMap,你搞懂了吗?
后端·面试