当前位置: 首页 > news >正文

Excel设置单元格下拉框(poi)

前言

        年关在即,还在最后的迭代处理,还分了个其他同事的单,说是导出的Excel模版的2列要修改为下拉选项,过程很曲折,不说,以下其实就是一个笔记而已!
        其实之前分享过阿里的EasyExcel设置单元格下拉框,这里是poi原生设置。


一、场景描述

        其实就是下载一个Excel文件,作为导入的模版,然后有一行示例,2列是字典值,希望给用户的输入做个示例。

二、使用步骤

1.引入库

        主要就是引入poi相关包

<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.0</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.0</version>
</dependency>

2.工具类

        这里分享工具类的部分方法,免得看的眼花缭乱。
ExcelTools

/*** 导出带下拉框的Excel** @param outStream   输出流* @param keyValueMap 表头和属性的Map集合,其中Map中Key为Excel列的名称,Value为反射类的属性* @param list        数据集合* @param fileType    文件类型* @param title       表头* @param dropDownMap 下拉框Map集合,其中Map中Key为Excel列的序号,Value为下拉框的值* @param <T>         泛型* @throws Exception 异常* @auther zhengwen*/public static <T> void exportDropDownExcel(OutputStream outStream, Map<String, String> keyValueMap, List<T> list,String fileType, String title, Map<Integer, List<String>> dropDownMap) throws Exception {Workbook wb = createWorkbook(fileType);exportExcel(wb, outStream, keyValueMap, list, fileType, title, dropDownMap);}/*** 根据文件后缀创建对应的 Workbook* @param fileType 文件后缀:xls,xlsx* @return Workbook*/private static Workbook createWorkbook(String fileType){return ExcelConstant.XLS.equals(fileType) ? new HSSFWorkbook() : new XSSFWorkbook();}/*** 创建带下拉选项的Workbook** @param wb          Workbook* @param outStream   输出流* @param keyValueMap 表头和属性的Map集合,其中Map中Key为Excel列的名称,Value为反射类的属性* @param list        数据集合* @param fileType    文件类型* @param title       表头* @param dropDownMap 下拉框Map集合,其中Map中Key为Excel列的序号,Value为下拉框的值* @param <T>         泛型* @throws Exception 异常* @auther zhengwen*/private static <T> void exportExcel(Workbook wb, OutputStream outStream, Map<String, String> keyValueMap, List<T> list, String fileType, String title, Map<Integer, List<String>> dropDownMap) throws Exception {List<String> keyList = new ArrayList<>(keyValueMap.keySet());// 存储属性信息Map<String, String> attMap = new HashMap<>(CommonConstant.MAP_DEFAULT_INITIAL_CAPACITY);int index = CommonConstant.ZERO;if (ExcelConstant.XLS.equals(fileType)) {// 创建HSSFWorkbook对象(excel的文档对象)CellStyle cellStyle = wb.createCellStyle();cellStyle.setWrapText(true);cellStyle.setAlignment(HorizontalAlignment.CENTER);cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);int lastCol = keyValueMap.size() - 1;CellRangeAddress callRangeAddress = new CellRangeAddress(0, 0, 0, lastCol);// 建立新的sheet对象(excel的表单)HSSFSheet sheet = (HSSFSheet) wb.createSheet(ExcelConstant.SHEET_NAME);// 设置表格默认列宽度为15个字节sheet.setDefaultColumnWidth(20);sheet.addMergedRegion(callRangeAddress);// 声明样式HSSFCellStyle style = (HSSFCellStyle) wb.createCellStyle();hssfCellStyleForXls(wb, style);//表格标题HSSFRow rowTitle = sheet.createRow(CommonConstant.ZERO);HSSFCell titleCell = rowTitle.createCell(0);rowTitle.setHeight((short) 600);//加载单元格样式CellStyle erStyle = createCellStyle(wb, (short) 13, true, true);titleCell.setCellStyle(erStyle);titleCell.setCellValue(title);//标题换行设置erStyle.setWrapText(true);titleCell.setCellValue(new HSSFRichTextString(title));// 在sheet里创建第二行为表头,参数为行索引(excel的行),可以是0~65535之间的任何一个HSSFRow rowHeader = sheet.createRow(CommonConstant.ONE);DataFormat dataFormat = wb.createDataFormat();for (String key : keyList) {HSSFCell cell = rowHeader.createCell(index);style.setWrapText(true);//设置为文本,防止科学计数style.setDataFormat(dataFormat.getFormat("@"));cell.setCellStyle(style);cell.setCellValue(key);attMap.put(Integer.toString(index), keyValueMap.get(key));index++;}// 在sheet里创建表头下的数据for (int i = CommonConstant.ZERO; i < list.size(); i++) {int rowNum = i + CommonConstant.TWO;HSSFRow row = sheet.createRow(rowNum);for (int j = CommonConstant.ZERO; j < keyValueMap.size(); j++) {String key = Integer.toString(j);String att = attMap.get(key);T t = list.get(i);Object value = getAttrVal(t, att);cellStyle.setWrapText(true);Cell cell = row.createCell(j);cell.setCellStyle(cellStyle);if (dropDownMap.containsKey(j)) {setCellDropDownBox(cell, dropDownMap.get(j), sheet, rowNum, rowNum, j, j);} else {cell.setCellValue(getObject(value));}}}} else if (ExcelConstant.XLSX.equals(fileType)) {int lastCol = keyValueMap.size() - 1;CellRangeAddress callRangeAddress = new CellRangeAddress(0, 0, 0, lastCol);// 建立新的sheet对象(excel的表单)XSSFSheet sheet = (XSSFSheet) wb.createSheet(ExcelConstant.SHEET_NAME);// 设置表格默认列宽度为15个字节sheet.setDefaultColumnWidth(20);sheet.addMergedRegion(callRangeAddress);// 声明样式XSSFCellStyle style = (XSSFCellStyle) wb.createCellStyle();xssfCellStyleFor2007(wb, style);//标题XSSFRow rowTitle = sheet.createRow(CommonConstant.ZERO);rowTitle.setHeight((short) 600);//表格标题XSSFCell titleCell = rowTitle.createCell(0);//加载单元格样式CellStyle erStyle = createCellStyle(wb, (short) 13, true, true);titleCell.setCellStyle(erStyle);titleCell.setCellValue(title);//标题换行设置erStyle.setWrapText(true);titleCell.setCellValue(new XSSFRichTextString(title));// 在sheet里创建第一行为表头,参数为行索引(excel的行),可以是0~65535之间的任何一个XSSFRow rowHeader = sheet.createRow(CommonConstant.ONE);// 创建单元格并设置单元格内容for (String key : keyList) {XSSFCell cell = rowHeader.createCell(index);style.setWrapText(true);cell.setCellStyle(style);cell.setCellValue(key);attMap.put(Integer.toString(index), keyValueMap.get(key));index++;}// 在sheet里创建表头下的数据for (int i = CommonConstant.ZERO; i < list.size(); i++) {int rowNum = i + CommonConstant.TWO;XSSFRow row = sheet.createRow(rowNum);for (int j = CommonConstant.ZERO; j < keyValueMap.size(); j++) {String key = Integer.toString(j);T t = list.get(i);Object value = getAttrVal(t, attMap.get(key));CellStyle cellStyle = wb.createCellStyle();cellStyle.setWrapText(true);cellStyle.setAlignment(HorizontalAlignment.CENTER);cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 下边框cellStyle.setBorderBottom(BorderStyle.THIN);// 左边框cellStyle.setBorderLeft(BorderStyle.THIN);// 上边框cellStyle.setBorderTop(BorderStyle.THIN);// 右边框cellStyle.setBorderRight(BorderStyle.THIN);Font cellfont = wb.createFont();cellfont.setFontHeightInPoints((short) 12);cellfont.setFontName("宋体");cellStyle.setFont(cellfont);//row.createCell(j).setCellValue(getObject(value));//row.createCell(j).setCellStyle(cellStyle);//以上2行写的害人的,会导致单元格格式丢失DataFormat format = wb.createDataFormat();cellStyle.setDataFormat(format.getFormat("@"));//sheet.setDefaultColumnStyle(j, cellStyle);Cell cell = row.createCell(j);cell.setCellStyle(cellStyle);if (dropDownMap.containsKey(j)) {setCellDropDownBox(cell, dropDownMap.get(j), sheet, rowNum, rowNum, j, j);} else {cell.setCellValue(getObject(value));}}}}if (null != wb) {wb.write(outStream);}}/*** 设置cell单元格的下拉框** @param cell        单元格* @param dropDownMap 下拉框Map集合,其中Map中Key为Excel列的序号,Value为下拉框的值* @param sheet       sheet* @param startRow    开始行号* @param endRow      结束行号* @param startCol    开始列号* @param endCol      结束列号* @auther zhengwen*/private static void setCellDropDownBox(Cell cell, List<String> dropDownMap, Sheet sheet, int startRow, int endRow, int startCol, int endCol) {if (cell == null || sheet == null) {throw new DreambaseException("单元格或者sheet为空");}// 生成下拉框内容String[] dropDownArray = dropDownMap.toArray(new String[0]);//设置下拉框CellRangeAddressList regions = new CellRangeAddressList(startRow, endRow, startCol, endCol);if (sheet instanceof XSSFSheet){XSSFSheet xssfSheet = (XSSFSheet) sheet;// 生成下拉框DataValidationHelper helper = sheet.getDataValidationHelper();DataValidationConstraint constraint = helper.createExplicitListConstraint(dropDownArray);DataValidation dataValidation = helper.createValidation(constraint, regions);xssfSheet.addValidationData(dataValidation);}if (sheet instanceof HSSFSheet){// 生成下拉框DVConstraint constraint = DVConstraint.createExplicitListConstraint(dropDownArray);// 绑定下拉框和作用区域HSSFDataValidation dataValidation = new HSSFDataValidation(regions, constraint);sheet.addValidationData(dataValidation);}//设置下拉框选中第一个cell.setCellValue(dropDownArray[0]);}

serviceImpl

@Overridepublic void exportExcel(List<StationExcel> excelList, HttpServletRequest request, HttpServletResponse response){try {OutputStream outputStream = OutputStreamUtil.getOutputStream(request, response, StationExcel.FILE_NAME);//下拉框数据Map<Integer,List<String>> dropDownMap = new HashMap<>();//查询站点类型List<Dictionary> stationTypeDictList = dictionaryService.queryDictionaryByCategory(CommonConstant.DICT_STATION_TYPE);if(CollectionUtil.isNotEmpty(stationTypeDictList)){List<String> typeList = new ArrayList<>();stationTypeDictList.forEach((e) -> typeList.add(e.getDesc()));dropDownMap.put(1,typeList);}//查询电压等级List<Dictionary> electricPowerLevelDictList = dictionaryService.queryDictionaryByCategory(CommonConstant.DICT_ELECTRIC_POWER_LEVEL_TYPE);if(CollectionUtil.isNotEmpty(electricPowerLevelDictList)){List<String> electricPowerLevelList = new ArrayList<>();electricPowerLevelDictList.forEach((e) -> electricPowerLevelList.add(e.getDesc()));dropDownMap.put(3,electricPowerLevelList);}ExcelTools.exportDropDownExcel(outputStream, StationExcel.COLUMN_LIST, excelList, ExcelConstant.XLSX, StationExcel.TITLE, dropDownMap);response.flushBuffer();outputStream.close();} catch (IOException e) {log.error("excel导出失败", e);throw new DreambaseException("excel导出失败!IOException异常" + e.getMessage());} catch (Exception e) {log.error("excel导出失败", e);throw new DreambaseException("excel导出失败!" + e.getMessage());}}

总结

        其实没啥好分享的,真的就是个笔记而已,希望可以帮到大家!

http://www.lryc.cn/news/294687.html

相关文章:

  • api接口是什么意思,api接口该如何防护呢?
  • PMP资料怎么学?PMP备考经验分享
  • partition by list(msn_id)子句的含义
  • 【C++】I/O多路转接详解(二)
  • PySpark(三)RDD持久化、共享变量、Spark内核制度,Spark Shuffle
  • 详解MYSQL中的平均值组大小
  • 【爬虫专区】批量下载PDF (无反爬)
  • PostgreSQL解决序列(自增id)自动增长冲突
  • 1.0 Zookeeper 分布式配置服务教程
  • (Flutter 常用插件整理
  • vue2.0+使用md-edit编辑器
  • Java设计模式大全:23种常见的设计模式详解(二)
  • 【算法与数据结构】718、1143、1035、392、115、LeetCode最长重复子数组+最长公共子序列+不相交的线+判断子序列+不同的子序列
  • OCR文本纠错思路
  • 【java批量导出pdf】优化方案
  • Linux第42步_移植ST公司uboot的第3步_uboot命令测试,搭建nfs服务器和tftp服务器
  • C++枚举算法(3)
  • 【51单片机】LED的三个基本项目(LED点亮&LED闪烁&LED流水灯)(3)
  • Day 17------C语言收尾之链表的删除、位运算、预处理、宏定义
  • python_蓝桥杯刷题记录_笔记_全AC代码_入门5
  • 二叉树的详解
  • 【第三十五节】idea项目的创建以及setting和Project Structure的设置
  • 【c++】跟webrtc学引用计数
  • 开源免费的物联网网关 IoT Gateway
  • 华为OD机试真题C卷-篇3
  • [SWPUCTF 2021 新生赛]include
  • LeetCode、17. 电话号码的字母组合【中等,dfs回溯】
  • SSRF漏洞给云服务元数据带来的安全威胁
  • 【C++】强制类型转换
  • java日志框架总结(四 、JCL日志门面技术)