easypoi 导入导出excel,一对多关系的对象

该篇文章详细描述了如何在SpringMVC框架中,使用`@GetMapping`等注解创建一个用于导出安全培训试题Excel的功能,包括预授权、操作日志和字典数据的处理,以及如何处理试题与选项的一对多关系并进行合并输出。
摘要由CSDN通过智能技术生成

控制层:

@GetMapping("/export-excel")
    @Operation(summary = "导出安全培训-试题 Excel")
    @PreAuthorize("@ss.hasPermission('sta:question:export')")
    @OperateLog(type = EXPORT)
    public void exportQuestionExcel(@Valid QuestionExportReqVO exportReqVO,
              HttpServletResponse response) throws IOException {
        List<QuestionDO> list = questionService.getQuestionListAll(exportReqVO);
        // 导出 Excel
        List<QuestionImportVO> datas = QuestionConvert.INSTANCE.convertList03(list);
        
        ExportParams params = new ExportParams("试题台账", "试题信息");
        params.setDictHandler(new IExcelDictHandlerImpl());

        try {
            Workbook workbook = ExcelExportUtil.exportExcel(params, QuestionImportVO.class, datas);
            response.setHeader("Content-disposition", "attachment;filename=" + new String("试题信息表".getBytes("gb2312"), "ISO8859-1") + ".xls");
            response.setContentType("multipart/form-data");
            response.setCharacterEncoding("utf-8");
            ServletOutputStream out = response.getOutputStream();
            workbook.write(out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

实体类如下:

@Data
public class QuestionImportVO {

    @ExcelIgnore
    private Long id;

    @Excel(name = "试题内容", needMerge = true, width = 30)
    private String content;

    @ExcelIgnore
    private Long typeId;

    @Excel(name = "试题分类", needMerge = true, width = 10)
    private String typeName;

    @Excel(name = "试题类型" , needMerge = true, width = 10, dict = DictTypeConstants.STA_QUESTION_TYPE, addressList = true)
    private String quType;

    @Excel(name = "答案", needMerge = true, width = 10)
    private String answer;

    @Excel(name = "分数", needMerge = true,type=10, width = 10)
    private Double score;

    @Excel(name = "解析", needMerge = true, width = 30)
    private String analysis;

    @Excel(name = "难度(1-5星)", needMerge = true,type=10, width = 15)
    private Integer grade;

    @ExcelIgnore
    private Long knowId;

    @Excel(name = "关联知识点", needMerge = true, width = 10)
    private String knowName;

    @ExcelCollection(name = "试题选项")
    private List<QuOptionImportVO> options;

}

试题和试题选项为一对多的关系,试题采用@ExcelCollection注解 实现一对多,试题的字段在@Excel注释中加入needMerge = true 表示纵向合并,因为选项为多个就会生成多行,但是每行试题信息都一致就需要合并。

字典字段的处理:在@Excel注解上加入dict = DictTypeConstants.STA_QUESTION_TYPE, addressList = true;dict的值为字典类型,addressList=true表示导出的字典的单元格有字典所有数据的下拉框。要实现上述功能需要实现字典处理器,如下:

/**
 * 支持字典参数设置
 * 举例: @Excel(name = "性别", width = 15, dicCode = "sex")
 * 1、导出的时候会根据字典配置,把值1,2翻译成:男、女;
 * 2、导入的时候,会把男、女翻译成1,2存进数据库;
 *
 * @Author wh
 */
@Slf4j
@Component
public class IExcelDictHandlerImpl implements IExcelDictHandler {

    // <字典分类编码 -- <字典数据编码 -- 字典数据名称>>

    /**
     * 根据输入的字典类型编码,获取对应字典map(封装在List中)
     *
     * @param typeCode
     * @return
     */
    @Override
    public List<Map> getList(String typeCode) {
        List<Map> result = new ArrayList<>();
        List<DictDataRespDTO> dataList = DictFrameworkUtils.getDictList(typeCode);
        Map<String, String> dictListMap = dataList.stream().collect(Collectors.toMap(DictDataRespDTO::getLabel, DictDataRespDTO::getValue));
        if (CollUtil.isNotEmpty(dataList)) {
            for (Map.Entry<String, String> stringStringEntry : dictListMap.entrySet()) {
                Map<String, String> map = new HashMap<>();
                map.put("dictKey", stringStringEntry.getValue());
                map.put("dictValue", stringStringEntry.getKey());
                result.add(map);
            }
        }
        return result;
    }

    /**
     * 从值翻译到名称
     *
     * @param dict  字典Key
     * @param obj   对象
     * @param name  属性名称
     * @param value 属性值
     * @return
     */
    @Override
    public String toName(String dict, Object obj, String name, Object value) {
        return DictFrameworkUtils.getDictDataLabel(dict, String.valueOf(value));
    }

    /**
     * 从名称翻译到值
     *
     * @param dict  字典Key
     * @param obj   对象
     * @param name  属性名称
     * @param value 属性值
     * @return
     */
    @Override
    public String toValue(String dict, Object obj, String name, Object value) {
        return DictFrameworkUtils.parseDictDataValue(dict, String.valueOf(value));
    }
}

导出的示例:

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值