EasyExcel下载带下拉框和批注模板
一、 代码实现
- controller下载入口
@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");
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();
}
}
- 实体对象
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;
@Data
public class TWorkSheetReadVO implements Serializable {
private static final long serialVersionUID = 5924360788178861972L;
@ExcelProperty(value = "客诉标题", index = 0)
@ColumnWidth(20)
private String complaintHeadline;
@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;
@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;
}
- 下拉框拦截器
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;
public class CustomSheetWriteHandler implements SheetWriteHandler {
private Map<String, List<SysDictData>> notationMap;
public CustomSheetWriteHandler(Map<String, List<SysDictData>> notationMap) {
this.notationMap = notationMap;
}
@Override
public void afterSheetCreate(SheetWriteHandlerContext context) {
DataValidationHelper helper = context.getWriteSheetHolder().getSheet().getDataValidationHelper();
Map<Integer, String[]> mapDropDown = this.getIntegerMap();
for (Integer integer : mapDropDown.keySet()) {
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<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;
}
}
- 批注拦截器
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;
public class CommentWriteHandler implements RowWriteHandler {
private final Map<String, List<SysDictData>> notationMap;
public CommentWriteHandler(Map<String, List<SysDictData>> notationMap) {
this.notationMap = notationMap;
}
@Override
public 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"));
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);
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);
}
}
}
二、实现效果
- 批注效果
- 下拉框效果
三、参考文档
easyExcel自定义拦截器