实体类

@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value="FireChemicalDto", description="危化品")
public class FireChemicalDto  extends BaseDto {@ExcelIgnoreprivate static final long serialVersionUID = 1L;@ApiModelProperty(value = "casNo")@ExcelProperty(value = "casNo", index = 1)private String casNo;@ApiModelProperty(value = "国际危险号")@ExcelProperty(value = "国际危险号", index = 2)private String dangerId;@ApiModelProperty(value = "防护处理")@ExcelProperty(value = "防护处理", index = 3)private String defendWay;@ApiModelProperty(value = "处理措施")@ExcelProperty(value = "处理措施", index = 4)private String dispose;@ApiModelProperty(value = "英文名")@ExcelProperty(value = "英文名", index = 5)private String englishName;@ApiModelProperty(value = "分子式")@ExcelProperty(value = "分子式", index = 6)private String formula;@ApiModelProperty(value = "主要成分")@ExcelProperty(value = "主要成分", index = 7)private String ingredient;@ApiModelProperty(value = "泄漏处理")@ExcelProperty(value = "泄漏处理", index = 8)private String leakWay;@ExcelProperty(value = "中文名", index = 0)@ApiModelProperty(value = "中文名")private String name;@ApiModelProperty(value = "性状")@ExcelProperty(value = "性状", index = 9)private String property;@ApiModelProperty(value = "贮藏方法")@ExcelProperty(value = "贮藏方法", index = 10)private String store;@ApiModelProperty(value = "症状")@ExcelProperty(value = "症状", index = 11)private String symptom;@ApiModelProperty(value = "禁忌物/禁忌")@ExcelProperty(value = "禁忌物/禁忌", index = 12)private String tabu;@ExcelIgnore@ApiModelProperty(value = "类型code")private String typeCode;@ExplicitConstraint(type="CHEMICALTYPE",indexNum=13,sourceClass = RoleNameExplicitConstraint.class) //动态下拉内容@ApiModelProperty(value = "类型名称")@ExcelProperty(value = "类型名称", index = 13)private String type;
//    @ExplicitConstraint(indexNum=14,source = {"男","女"}) //固定下拉内容@ExcelProperty(value = "国标号", index = 14)@ApiModelProperty(value = "国标号")private String un;@ApiModelProperty(value = "化学品图片")@ExcelProperty(value = "化学品图片", index = 15)private String image;@ExcelIgnore@ApiModelProperty(value = "更新时间")private Date updateTime;@ExcelIgnore@ApiModelProperty(value = "操作人名称")private String recUserName;@ExcelIgnorepublic static final String bigTitle= "填写须知: \n" +"1.第1、2行为固定结构,不可更改;以下示例行,导入前请先删除\n" +"2.请严格按照填写规则输入数据,不合规的数据无法成功导入";/*** 每个模板的首行高度, 换行数目+2 乘以15*/public   static int getHeadHeight(){return  (RedisKey.countStr(bigTitle,"\n")+2)*15;}
}

实体类数据注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface ExplicitConstraint {//定义固定下拉内容String[]source()default {};//定义动态下拉内容,Class[]sourceClass()default {};//列标号必须和字段下标一致int indexNum() default 0;//字典typeString type() default "";}

动态数据接口

public interface ExplicitInterface {/*** 动态下拉列表的内容数组* @return* type 字典类型*/String[] source(String type,DataDictionaryMapper dataDictionaryMapper);
}

动态数据接口实现类

/**** * 获取动态值* * **/
public class RoleNameExplicitConstraint implements ExplicitInterface {@Overridepublic String[] source(String type,DataDictionaryMapper dataDictionaryMapper) {QueryWrapper<DataDictionary> queryWrapper = new QueryWrapper<>();queryWrapper.eq("type", type);queryWrapper.orderByAsc("sort_num");List<DataDictionary> list= dataDictionaryMapper.selectList(queryWrapper);List<String> names = list.stream().map(dataDictionary->{return dataDictionary.getName()+"@"+dataDictionary.getCode();}).collect(Collectors.toList());String[] str=names.toArray(new String[names.size()]);return str;}
}

工具类

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.yeejoin.amos.boot.module.jcs.api.mapper.DataDictionaryMapper;public class ExcelUtil {/*** 生成excel模板** @param response* @param fileName    下载的文件名,* @param sheetName   sheet名* @param data        导出的数据* @param model       导出的头* @param heardHeight 头行高*/public static void createTemplate(HttpServletResponse response, String fileName,String sheetName, List<? extends Object> data,Class<?> model, int heardHeight, DataDictionaryMapper dataDictionaryMapper)  {HorizontalCellStyleStrategy horizontalCellStyleStrategy = setMyCellStyle();try {//下拉列表集合Map<Integer, String[]> explicitListConstraintMap = new HashMap<>();//循环获取对应列得下拉列表信息Field[] declaredFields = model.getDeclaredFields();for (int i = 0; i < declaredFields.length; i++) {Field field = declaredFields[i];//解析注解信息ExplicitConstraint explicitConstraint = field.getAnnotation(ExplicitConstraint.class);resolveExplicitConstraint(explicitListConstraintMap,explicitConstraint,dataDictionaryMapper);}             EasyExcel.write(getOutputStream(fileName, response, ExcelTypeEnum.XLSX), model).excelType(ExcelTypeEnum.XLSX).sheet(sheetName).registerWriteHandler(new TemplateCellWriteHandlerDate(heardHeight,explicitListConstraintMap)).registerWriteHandler(new TemplateCellWriteHandler()).registerWriteHandler(horizontalCellStyleStrategy).doWrite(data);          } catch (Exception e) {e.printStackTrace();throw new RuntimeException("系统异常!");}}/*** 解析注解内容 获取下列表信息* @param explicitConstraint* @return*/public static Map<Integer, String[]> resolveExplicitConstraint(  Map<Integer, String[]> explicitListConstraintMap,ExplicitConstraint explicitConstraint, DataDictionaryMapper dataDictionaryMapper){if (explicitConstraint == null) {return null;}//固定下拉信息String[] source = explicitConstraint.source();if (source.length > 0) {explicitListConstraintMap.put(explicitConstraint.indexNum(), source);}//动态下拉信息Class<? extends ExplicitInterface>[] classes = explicitConstraint.sourceClass();if (classes.length>0){ExplicitInterface explicitInterface = null;try {explicitInterface = classes[0].newInstance();String[] source1 = explicitInterface.source(explicitConstraint.type(),dataDictionaryMapper);if (source1.length>0){explicitListConstraintMap.put(explicitConstraint.indexNum(), source1);}} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}return null;}/*** 导出文件时为Writer生成OutputStream*/private static OutputStream getOutputStream(String fileName, HttpServletResponse response, ExcelTypeEnum excelTypeEnum) throws Exception {//创建本地文件String filePath = fileName + excelTypeEnum.getValue();try {fileName = new String(filePath.getBytes(), StandardCharsets.ISO_8859_1);response.setCharacterEncoding(StandardCharsets.UTF_8.name());response.setContentType("application/vnd.ms-excel");response.addHeader("Content-Disposition", "filename=" + fileName);return response.getOutputStream();} catch (IOException e) {throw new Exception("系统异常");}}/*** 创建我的cell  策略** @return*/public static HorizontalCellStyleStrategy setMyCellStyle() {// 头的策略WriteCellStyle headWriteCellStyle = new WriteCellStyle();// 设置表头居中对齐headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 颜色headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());WriteFont headWriteFont = new WriteFont();headWriteFont.setFontHeightInPoints((short) 10);// 字体headWriteCellStyle.setWriteFont(headWriteFont);headWriteCellStyle.setWrapped(true);    // 内容的策略WriteCellStyle contentWriteCellStyle = new WriteCellStyle();// 设置内容靠中对齐contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭   return horizontalCellStyleStrategy;}
}

拦截器

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;/*** excel通用单元格格式类*/
public class TemplateCellWriteHandler implements CellWriteHandler {@Overridepublic void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,Head head, int relativeRowIndex, boolean isHead) {// TODO Auto-generated method stub}@Overridepublic void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData,Cell cell, Head head, int relativeRowIndex, boolean isHead) {Workbook workbooks = writeSheetHolder.getSheet().getWorkbook();writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), 20 * 256);CellStyle cellStyle = workbooks.createCellStyle();cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);//居中cellStyle.setAlignment(HorizontalAlignment.CENTER);cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);//设置前景填充样式cellStyle.setFillForegroundColor(IndexedColors.ROYAL_BLUE.getIndex());//前景填充色Font font1 = workbooks.createFont();//设置字体font1.setBold(true);font1.setColor((short)1);font1.setFontHeightInPoints((short)15);cellStyle.setFont(font1);cell.setCellStyle(cellStyle);//其他列if (!isHead){CellStyle style = workbooks.createCellStyle();DataFormat dataFormat = workbooks.createDataFormat();style.setDataFormat(dataFormat.getFormat("@"));style.setVerticalAlignment(VerticalAlignment.CENTER);style.setAlignment(HorizontalAlignment.CENTER);cell.setCellStyle(style);}//设置日期if (!isHead && cell.getColumnIndex()==19 || !isHead && cell.getColumnIndex()==21|| !isHead && cell.getColumnIndex()==20){CellStyle style = workbooks.createCellStyle();DataFormat dataFormat = workbooks.createDataFormat();style.setDataFormat(dataFormat.getFormat("yyyy/mm/dd hh:mm:ss"));style.setVerticalAlignment(VerticalAlignment.CENTER);style.setAlignment(HorizontalAlignment.CENTER);cell.setCellStyle(style);}//设置金额if (!isHead && cell.getColumnIndex()==15 ||!isHead && cell.getColumnIndex()==16||!isHead && cell.getColumnIndex()==22 ||!isHead && cell.getColumnIndex()==24||!isHead && cell.getColumnIndex()==25){CellStyle style = workbooks.createCellStyle();DataFormat dataFormat = workbooks.createDataFormat();style.setDataFormat(dataFormat.getFormat("0.00"));style.setVerticalAlignment(VerticalAlignment.CENTER);style.setAlignment(HorizontalAlignment.CENTER);cell.setCellStyle(style);}         }}

下拉数据多显示空白 处理

import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.Workbook;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddressList;
import java.util.HashMap;
import java.util.Map;/*** excel通用单元格格式类下拉框赋值*/
public class TemplateCellWriteHandlerDate implements SheetWriteHandler {/*** 模板的首行行高 ,通过构造器注入*/private  int height;private Map<Integer, String[]> explicitListConstraintMap = new HashMap<>();public TemplateCellWriteHandlerDate(int height,Map<Integer, String[]> explicitListConstraintMap) {this.height = height;this.explicitListConstraintMap = explicitListConstraintMap;}/*** 设置阈值,避免生成的导入模板下拉值获取不到*/private static final Integer LIMIT_NUMBER = 50;/*** 返回excel列标A-Z-AA-ZZ** @param num 列数* @return java.lang.String*/private String getExcelLine(int num) {String line = "";int first = num / 26;int second = num % 26;if (first > 0) {line = (char) ('A' + first - 1) + "";}line += (char) ('A' + second) + "";return line;}@Overridepublic void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {// TODO Auto-generated method stub}@Overridepublic void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {// 这里可以对cell进行任何操作Sheet sheet = writeSheetHolder.getSheet();DataValidationHelper helper = sheet.getDataValidationHelper();// k 为存在下拉数据集的单元格下表 v为下拉数据集explicitListConstraintMap.forEach((k, v) -> {// 设置下拉单元格的首行 末行 首列 末列CellRangeAddressList rangeList = new CellRangeAddressList(1, 65536, k, k);// 如果下拉值总数大于100,则使用一个新sheet存储,避免生成的导入模板下拉值获取不到if (v.length > LIMIT_NUMBER) {//定义sheet的名称//1.创建一个隐藏的sheet 名称为 hidden + kString sheetName = "hidden" + k;Workbook workbook = writeWorkbookHolder.getWorkbook();Sheet hiddenSheet = workbook.createSheet(sheetName);for (int i = 0, length = v.length; i < length; i++) {// 开始的行数i,列数khiddenSheet.createRow(i).createCell(k).setCellValue(v[i]);}Name category1Name = workbook.createName();category1Name.setNameName(sheetName);String excelLine = getExcelLine(k);// =hidden!$H:$1:$H$50  sheet为hidden的 H1列开始H50行数据获取下拉数组String refers = "=" + sheetName + "!$" + excelLine + "$1:$" + excelLine + "$" + (v.length + 1);// 将刚才设置的sheet引用到你的下拉列表中DataValidationConstraint constraint = helper.createFormulaListConstraint(refers);DataValidation dataValidation = helper.createValidation(constraint, rangeList);writeSheetHolder.getSheet().addValidationData(dataValidation);// 设置存储下拉列值得sheet为隐藏int hiddenIndex = workbook.getSheetIndex(sheetName);if (!workbook.isSheetHidden(hiddenIndex)) {workbook.setSheetHidden(hiddenIndex, true);}}// 下拉列表约束数据DataValidationConstraint constraint = helper.createExplicitListConstraint(v);// 设置约束DataValidation validation = helper.createValidation(constraint, rangeList);// 阻止输入非下拉选项的值validation.setErrorStyle(DataValidation.ErrorStyle.STOP);validation.setShowErrorBox(true);validation.setSuppressDropDownArrow(true);validation.createErrorBox("提示", "此值与单元格定义格式不一致");// validation.createPromptBox("填写说明:","填写内容只能为下拉数据集中的单位,其他单位将会导致无法入仓");sheet.addValidationData(validation);});}}

测试调用

@RestController
@Api(tags = "导出")
@RequestMapping(value = "/excel")
public class ExcelController extends BaseController {@AutowiredDataDictionaryMapper dataDictionaryMapper;@TycloudOperation(needAuth = false,ApiLevel = UserType.AGENCY)@ApiOperation(value = "下载模板")@GetMapping("/template")public void template2(HttpServletResponse response) {String fileName = "导入模板";String sheetName = "模板";try {ExcelUtil.createTemplate(response, fileName, sheetName, null,FireChemicalDto.class, FireChemicalDto.getHeadHeight(),dataDictionaryMapper);} catch (Exception e) {e.printStackTrace();}}}

参考多个博客,   https://blog.csdn.net/qq_32495261/article/details/108482413

https://blog.csdn.net/qq_38404386/article/details/103976220

EasyExcel导出带下拉框 通用模板相关推荐

  1. Easyexcel导出带下拉框选项excel模板

    需求:导出的excel模板,表头字段动态生成.sheet页下拉框内容动态生成 解决思路:为了避免excel下拉框选项过多会导致内容不显示,将下拉框的内容都存储在另一个新建的固定的sheet页,再通过引 ...

  2. EasyExcel导出有下拉框的模板

    Conteoller层: 代码: /*** 创建元数据模板* 导出模板** @param response 响应* @throws Exception 异常*/@GetMapping("/c ...

  3. 使用EasyExcel导出带下拉框的Excel

    1. 创建注解 import java.lang.annotation.*;/*** 标注导出的列为下拉框类型,并为下拉框设置内容*/ @Documented @Retention(Retention ...

  4. EasyExcel在项目中的应用-在web中导出带下拉框和批注的excel文件

    前言 ​ 好长一段时间没有更新博客了,最近刚刚找到实习工作,接触了企业中的项目,在这段时间的实习过程中,终于知道了企业级项目的体量和业务难度跟之前的小项目是完全不同的.10多天的适应期也逐渐让我找到了 ...

  5. Excel表格下载模板(带下拉框选项)

    下载excel模板需要带下拉框选项,现在纯JAVA代码来实现 1.模板标题实体类 import cn.afterturn.easypoi.excel.annotation.Excel; import ...

  6. Java EXCEL 表格导入导出(带下拉选-带VLOOKUP函数封装)

    Java EXCEL 表格导入导出(带下拉选-带VLOOKUP函数封装) 对于excel Java POI 使用 目前简单导出导入功能网上很多,但是对于有下拉选,样式等缺点却是最大硬伤,故此封装一个通 ...

  7. EasyExcel导出表格——下拉筛选

    EasyExcel导出表格--下拉筛选 单元格添加下拉筛选 确保输入内容规范和准确 减少数据查询,提高用户使用感 根据用户权限,下拉筛选项控制 Controller层 /*** 模板下载* @para ...

  8. 导出带下拉选项的Excel基于EasyExcel实现

    前言 今天就是记录一个计算点而已,帮小组成员搽屁股改bug.场景就是导出Excel的模板,希望枚举字段有下拉选择. 一.技术选型场景 我们这里用的是阿里开源的EasyExcel,导出模板是后端动态生成 ...

  9. ExcelJS 导入导出excel带下拉框筛选数据

    import ExcelJS from "exceljs"; 配上文档地址 下载方法 //数据格式 deviceJson:{         't(数据类型)':[{value:0 ...

最新文章

  1. java 排序算法 讲解_java实现排序算法之冒泡排序法详细讲解
  2. iOS导航栏标题错乱的解决方法
  3. 第十六章 贪心算法——0/1背包问题
  4. 学习官方示例 - System.Frac: 返回小数部分
  5. ide在控制台输入编译命令_快速编译调试 Redis
  6. AngularJS(三):重复HTML元素、数据绑定
  7. tooctalstring_Java Long类toOctalString()方法的示例
  8. php标准库string,PHP中的一些标准库
  9. Machine Learning - Coursera week5 Backpropagation in Practice
  10. 如何测试判断云服务器的稳定性?
  11. TFS 2010 使安装更容易,让VSS历史
  12. Map 转 json格式 保留null值的解决办法
  13. ubuntu18使用wine安装TIM和微信
  14. 善领dsa2020最新车机ce版_理想汽车回应碰撞事故 硬件升级计划将推出OTA 2.0版
  15. 图片怎么存储到数据库里
  16. 对数正态随机数c语言程序,对数正态随机数
  17. 2g内存用linux的哪个版本,Linux 下安装sql server 时 2G内存限制的最新(2019-08-15) 解决方案...
  18. Altium Designer挖空开槽填坑之board cutout
  19. 批量计算图片的均值与标准差
  20. python网络编程——套接字名与DNS

热门文章

  1. ExtJs中点击页面有时不加载的问题
  2. Matlab 保持图像矩阵大小不变对图像放大和缩小
  3. 软件开发的一些思考及心得体会
  4. 调用的目标发生了异常。问题处理
  5. 在Node服务器中运行html文件
  6. ER图学习笔记(附各个图型的举例,实战案例)
  7. 数据化管理助力传统制造业,实现供应链上游生产车间可视化监控
  8. 驱动的几种Hook方法
  9. openGauss开源数据库二次开发指导手册(上)
  10. 理解OpenCL中的工作组、工作项的索引