EasyExcel下载带下拉框和批注模板

EasyExcel下载带下拉框和批注模板

一、 代码实现

  1. controller下载入口
/***下载excel模板* @author youlu* @date 2023/8/14 17:31* @param response* @param request* @return void*/@PostMapping("/downloadTemplate")public void downloadExcel(HttpServletResponse response, HttpServletRequest request) throws IOException {//查询字典数据,用于模板下拉框和批注说明使用Map<String, List<SysDictData>> dictDataMap = dictDataService.selectDictDataMapByDictTypeAndStatus("worksheet", "0");//获取供应商类型,不同供应商类型展示的下拉框和批注会有不一样Boolean supplier = getSupplierBoolean();ParamThreadLocal.setParam(supplier);try {long currentTimeMillis = System.currentTimeMillis();String name = "工单模板_" + currentTimeMillis;response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系String fileName = URLEncoder.encode(name, "UTF-8");response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), TWorkSheetReadVO.class).inMemory(true).registerWriteHandler(new CommentWriteHandler(dictDataMap)) //加下拉框的拦截器.registerWriteHandler(new CustomSheetWriteHandler(dictDataMap)) //加批注的拦截器.build();WriteSheet writeSheet = EasyExcel.writerSheet("工单模板").build();excelWriter.write(Lists.newArrayList(), writeSheet);excelWriter.finish();} finally {ParamThreadLocal.clearParam();}}
  1. 实体对象
package com.smy.ows.project.worksheet.domain.vo;import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.HeadStyle;
import com.alibaba.excel.converters.date.DateStringConverter;
import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.smy.framework.base.DesensitizationAnnotation;
import com.smy.ows.project.worksheet.enums.SheetLevelEnums;
import com.smy.ows.project.worksheet.enums.WorkSheetStatus;
import com.smy.ows.util.*;
import lombok.Data;import java.io.Serializable;
import java.util.Date;/*** 客诉工单对象 t_work_sheet** @author youlu* @date 2023-01-11*/
@Data
public class TWorkSheetReadVO implements Serializable {private static final long serialVersionUID = 5924360788178861972L;/*** 客诉标题*/@ExcelProperty(value = "客诉标题", index = 0)@ColumnWidth(20)private String complaintHeadline;/*** @see SheetLevelEnums*/@ExcelProperty(value = "优先级", index = 1, converter = PriorityIntegerStringConverter.class)@ColumnWidth(10)@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 40)private Integer priority;@ExcelProperty(value = "客户姓名", index = 2)@ColumnWidth(20)@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 40)private String custName;/*** 客户号*/@ExcelProperty(value = "客户号", index = 3)@ColumnWidth(20)private String custNo;@DesensitizationAnnotation@ExcelProperty(value = "客户手机号", index = 4)@ColumnWidth(20)@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 40)private String custMobile;@DesensitizationAnnotation@ExcelProperty(value = "客户身份证", index = 5)@ColumnWidth(30)private String custIdNo;/*** 投诉时间*/@ExcelProperty(value = "投诉时间(yyyy-MM-dd HH:mm:ss)", index = 6, converter = DateStringConverter.class)@ColumnWidth(40)@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date complaintTime;//反馈渠道@ExcelProperty(value = "反馈渠道", index = 7, converter = ChannelStringStringConverter.class)@ColumnWidth(15)@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 40)private String feedbackChannel;@ExcelProperty(value = "工单类型", index = 8, converter = TypeIntegerStringConverter.class)@ColumnWidth(15)@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 40)private Integer type;@ExcelProperty(value = "业务类型", index = 9, converter = BizTypeIntegerStringConverter.class)@ColumnWidth(15)@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 40)private Integer bizType;@DesensitizationAnnotation@ExcelProperty(value = "客户联系方式", index = 10)@ColumnWidth(15)private String custContactMobile;/*** 所属资方*/@ExcelProperty(value = "所属资方", index = 11)@ColumnWidth(15)private String capital;@ExcelProperty(value = "投诉内容", index = 12)@ColumnWidth(30)@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 40)private String content;/*** @see WorkSheetStatus*/@ExcelProperty(value = "工单状态", index = 13, converter = StatusIntegerStringConverter.class)@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 40)@ColumnWidth(15)private Integer status;@ExcelProperty(value = "处理结果", index = 14, converter = ResultIntegerStringConverter.class)@ColumnWidth(15)private Integer result;/*** 处理情况*/@ExcelProperty(value = "处理情况", index = 15)@ColumnWidth(15)private String handingInfo;}
  1. 下拉框拦截器
package com.smy.ows.util;import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.handler.context.SheetWriteHandlerContext;
import com.smy.ows.common.core.domain.entity.SysDictData;
import com.smy.ows.common.utils.ParamThreadLocal;
import com.smy.ows.project.worksheet.constant.WorksheetDictTypeConstant;
import com.smy.ows.project.worksheet.enums.WorkSheetStatus;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.util.CellRangeAddressList;import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** 自定义拦截器.** @author youlu*/
public class CustomSheetWriteHandler implements SheetWriteHandler {private  Map<String, List<SysDictData>> notationMap;public CustomSheetWriteHandler(Map<String, List<SysDictData>> notationMap) {this.notationMap = notationMap;}@Overridepublic void afterSheetCreate(SheetWriteHandlerContext context) {DataValidationHelper helper = context.getWriteSheetHolder().getSheet().getDataValidationHelper();Map<Integer, String[]> mapDropDown = this.getIntegerMap();for (Integer integer : mapDropDown.keySet()) {//起始行,结束行,元素位置(ExcelProperty中的value值)CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 65535, integer, integer);String[] strings = mapDropDown.get(integer);DataValidationConstraint constraint = helper.createExplicitListConstraint(strings);DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);context.getWriteSheetHolder().getSheet().addValidationData(dataValidation);}}private Map<Integer, String[]> getIntegerMap() {//map中key对应,ExcelProperty中的value值。map中value对应下拉框的值Map<Integer, String[]> mapDropDown = new HashMap<>();for (String key : notationMap.keySet()) {String[] strings = notationMap.get(key).stream().map(k -> k.getDictLabel()).toArray(String[]::new);if (WorksheetDictTypeConstant.WORKSHEET_RESULT.equals(key)) {mapDropDown.put(14, strings);} else if (WorksheetDictTypeConstant.WORKSHEET_TYPE.equals(key)) {mapDropDown.put(8, strings);} else if (WorksheetDictTypeConstant.WORKSHEET_BIZ_TYPE.equals(key)) {mapDropDown.put(9, strings);} else if (WorksheetDictTypeConstant.WORKSHEET_PRIORITY.equals(key)) {mapDropDown.put(1, strings);} else if (WorksheetDictTypeConstant.WORKSHEET_FEEDBACK_CHANNEL.equals(key)) {mapDropDown.put(7, strings);}}Boolean supplier = (Boolean) ParamThreadLocal.getParam();if (supplier) {//供应商 和 资方的,工单状态只能选择【待分配】mapDropDown.put(13, new String[]{WorkSheetStatus.PENDING.getDesc()});//其他的工单状态只能选择【待分配】和 【已处理】} else {mapDropDown.put(13, new String[]{WorkSheetStatus.PENDING.getDesc(), WorkSheetStatus.FINISHED.getDesc()});}return mapDropDown;}
}
  1. 批注拦截器
package com.smy.ows.util;import com.alibaba.excel.util.BooleanUtils;
import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
import com.google.common.collect.Lists;
import com.smy.ows.common.core.domain.entity.SysDictData;
import com.smy.ows.project.worksheet.constant.WorksheetDictTypeConstant;
import com.smy.ows.project.worksheet.enums.WorkSheetStatus;
import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;/*** 自定义拦截器.新增注释,第一行头加批注** @author Jiaju Zhuang*/
public class CommentWriteHandler implements RowWriteHandler {private final Map<String, List<SysDictData>> notationMap;public CommentWriteHandler(Map<String, List<SysDictData>> notationMap) {this.notationMap = notationMap;}@Overridepublic void afterRowDispose(RowWriteHandlerContext context) {if (BooleanUtils.isTrue(context.getHead())) {Sheet sheet = context.getWriteSheetHolder().getSheet();Drawing<?> drawingPatriarch = sheet.createDrawingPatriarch();// 在第一行 第二列创建一个批注String priorityDesc = Optional.ofNullable(notationMap.get(WorksheetDictTypeConstant.WORKSHEET_PRIORITY)).orElse(Lists.newArrayList()).stream().map(k -> k.getDictValue() + ":" + k.getDictLabel()).collect(Collectors.joining("\r\n"));//对应要加批注的元素的ExcelProperty中的value值       Comment comment = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short)1, 0, (short)2, 1));comment.setString(new XSSFRichTextString(priorityDesc));// 将批注添加到单元格对象中sheet.getRow(0).getCell(1).setCellComment(comment);//对应要加批注的元素的ExcelProperty中的value值Comment comment6 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short)6, 0, (short)2, 1));comment6.setString(new XSSFRichTextString("yyyy-MM-dd HH:mm:ss"));sheet.getRow(0).getCell(6).setCellComment(comment6);String channelDesc = Optional.ofNullable(notationMap.get(WorksheetDictTypeConstant.WORKSHEET_FEEDBACK_CHANNEL)).orElse(Lists.newArrayList()).stream().map(k -> k.getDictValue() + ":" + k.getDictLabel()).collect(Collectors.joining("\r\n"));Comment comment7 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 7, 0, (short) 2, 1));comment7.setString(new XSSFRichTextString(channelDesc));sheet.getRow(0).getCell(7).setCellComment(comment7);String typeDesc = Optional.ofNullable(notationMap.get(WorksheetDictTypeConstant.WORKSHEET_TYPE)).orElse(Lists.newArrayList()).stream().map(k -> k.getDictValue() + ":" + k.getDictLabel()).collect(Collectors.joining("\r\n"));Comment comment8 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 8, 0, (short) 2, 1));comment8.setString(new XSSFRichTextString(typeDesc));sheet.getRow(0).getCell(8).setCellComment(comment8);String bizDesc = Optional.ofNullable(notationMap.get(WorksheetDictTypeConstant.WORKSHEET_BIZ_TYPE)).orElse(Lists.newArrayList()).stream().map(k -> k.getDictValue() + ":" + k.getDictLabel()).collect(Collectors.joining("\r\n"));Comment comment9 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 9, 0, (short) 2, 1));comment9.setString(new XSSFRichTextString(bizDesc));sheet.getRow(0).getCell(9).setCellComment(comment9);String statusDesc = Arrays.stream(WorkSheetStatus.values()).map(k -> k.getCode() + ":" + k.getDesc()).collect(Collectors.joining("\r\n"));Comment comment13 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 13, 0, (short) 2, 1));comment13.setString(new XSSFRichTextString(statusDesc));sheet.getRow(0).getCell(13).setCellComment(comment13);String resultDesc = Optional.ofNullable(notationMap.get(WorksheetDictTypeConstant.WORKSHEET_RESULT)).orElse(Lists.newArrayList()).stream().map(k -> k.getDictValue() + ":" + k.getDictLabel()).collect(Collectors.joining("\r\n"));Comment comment14 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 14, 0, (short) 2, 1));comment14.setString(new XSSFRichTextString(resultDesc));sheet.getRow(0).getCell(14).setCellComment(comment14);}}
}

二、实现效果

  1. 批注效果
    在这里插入图片描述
  2. 下拉框效果
    在这里插入图片描述

三、参考文档

easyExcel自定义拦截器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/456517.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯----凑算式

这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。 比如: 68/3952/714 就是一种解法, 53/1972/486 是另一种解法. 这个算式一共有多少种解法? 注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。 代码 public class _03凑算式 {static int a[] {1,2,3…

VScode上无法运行TSC命令,Typescript

如何解决问题 第一步&#xff1a;使用 winx 快捷键&#xff0c;会出现如下弹窗&#xff0c;鼠标左键单击Windows PowerShell 即可打开shell 第二步&#xff1a;运行 set-ExecutionPolicy RemoteSigned 命令&#xff0c;在询问更改执行策略的时候选择敲Y或者A 第三步&#xff…

【多模态大模型】BridgeTower:融合视觉和文本信息的多层语义信息,主打复杂视觉-语言任务

BridgeTower 核心思想子问题1&#xff1a;双塔架构的局限性子问题2&#xff1a;不同层次的语义信息未被充分利用子问题3&#xff1a;模型扩展性和泛化能力 核心思想 论文&#xff1a;https://arxiv.org/pdf/2206.08657.pdf 代码&#xff1a;https://github.com/microsoft/Bri…

【Git】06 常用场景

文章目录 前言一、场景11.1 删除分支1.2 修改message信息1.2.1 最新一次commit的message1.2.2 过去commit的message 1.3 合并commit1.3.1 多个连续commit合并1.3.2 不连续commit合并 二、场景22.1 比较暂存区和HEAD所含文件的差异2.2 比较工作区和暂存区所含文件的差异2.3 将暂…

Blender_pmx导出fbx

Blender_pmx导出fbx 学无止境&#xff1f; 相关链接&#xff1a; Blender教程&#xff1a; Blender中文手册介绍 — Blender Manualhttps://docs.blender.org/manual/zh-hans/2.79/about/introduction.htmlhttps://www.blendercn.org/https://www.blendercn.org/Blender下载…

性能评测|虚拟化和裸金属 K8s 哪个性能更好?

本文重点 整体而言&#xff0c;SKS&#xff08;虚拟机 Kubernetes&#xff09;可以达到裸金属 Kubernetes 性能的 82% – 96%&#xff0c;满足绝大部分场景下生产容器应用的性能需求。更多虚拟化与裸金属 Kubernetes 架构、特性、适用场景与性能对比&#xff0c;欢迎阅读文末电…

MySQL管理的常用工具(mysql,mysqlbinlog,mysqladmin,mysqlshow)

MySQL管理 系统数据库 数据库含义mysql存储MySQL服务器正常运行所需要的各种信息 &#xff08;时区、主从、用 户、权限等&#xff09;information_schema提供了访问数据库元数据的各种表和视图&#xff0c;包含数据库、表、字段类 型及访问权限等performance_schema为MySQL服…

【C++基础入门】七、指针(定义和使用、所占内存空间、空指针和野指针、const关键字修饰指针、指针和数组、指针和函数)

七、指针 7.1 指针的基本概念 指针的作用&#xff1a; 可以通过指针间接访问内存 内存编号是从0开始记录的&#xff0c;一般用十六进制数字表示可以利用指针变量保存地址 7.2 指针变量的定义和使用 指针变量定义语法&#xff1a; 数据类型 * 变量名&#xff1b; 示例&…

OJ_浮点数加法(高精度运算)

题干 C实现 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<map> #include<string> using namespace std;string GetInteger(string a) {return a.substr(0, a.find(.)); }string GetFraction(string a) {return a.substr(a.find(.) 1 ,a.siz…

2023_中国零售业人工智能行业应用 发展图谱

01 零售人工智能行业应用发展背景 02 零售人工智能行业应用发展图谱及行业应用案例 案例&#xff1a;京东云、蓝色光标、京东言犀智能服务、腾讯企点、 案例&#xff1a;淘天集团、极睿科技、百度电商数字人直播 案例&#xff1a;中国联通、云拿科技AI智能商店&#xff1b; 0…

C#向数组指定索引位置插入新的元素值:自定义插入方法 vs List<T>.Add(T) 方法

目录 一、使用的方法 1.自定义插入方法 2.使用List.Add(T) 方法 二、实例 1.示例1&#xff1a;List.Add(T) 方法 2.示例&#xff1a;自定义插入方法 一、使用的方法 1.自定义插入方法 首先需要定义一个一维数组&#xff0c;然后修改数组的长度(这里使用Length属性获取…

全面理解jvm

jvm是什么&#xff1f; java虚拟机 为什么要学jvm&#xff1f; 解决性能调优&#xff0c;优化内存空间&#xff0c;防止服务崩掉的问题。同时是java的工作环境, 一些基于java开发的语言Scale &#xff0c; Jpython都可以运行在java虚拟机上。 jvm的工作原理&#xff1a; 类加…