使用Apache POI生成具有三级联动下拉列表的Excel文档;
具体效果图与代码如下文。

先上效果图:


开始贴代码,代码中部分测试数据不影响功能。

第一部分(核心业务处理):

此部分包含几个方面:

  1. 获取三级下拉框各列的数据;
  2. 创建每个下拉功能的名称管理器
  3. 在隐藏的sheet中生成下拉菜单所需要的row
代码如下:
/*** 第一部分* 将三个列表所有字段从数据库查询出,并生成名称管理器,存放至隐藏的sheet中*/
private static HSSFWorkbook writePorpData() {int index = 1;HSSFWorkbook wb = new HSSFWorkbook();   //Excel工作簿创建wb.createSheet(DICT_SHEET_TEST);        //创建主工作表sheetSheet dictDataSheet = wb.createSheet(DICT_SHEET_DATA);  //创建数据源字段sheetList<Province> provinceList = GetData.getProvinces();       //获取所有省份    --测试数据,不影响功能List<String> provinceNames = new ArrayList<String>();       //1.存放所有省份的名称provinceNames.add("  ");        //使下拉框有置空的选择//遍历每个省份for (Province province : provinceList) {String proName = province.getProvinceName();        //获取每个省份名称provinceNames.add(proName);String provinceId = province.getProvinceId();       //获取每个省份IdList<Area> areaList = GetData.getAreas(provinceId);     //获取每个地区    --测试数据,不影响功能List<String> areaNames = new ArrayList<String>();       //2.存放所有地区名称areaNames.add("  ");        //使下拉框有置空的选择//遍历每个地区for (Area area : areaList) {String areaName = area.getAreaName();areaNames.add(areaName);String areaId = area.getAreaId();List<City> cityList = GetData.getCities(areaId);    //获取每个城市    --测试数据,不影响功能List<String> cityNames = new ArrayList<String>();   //3.存放所有城市名称cityNames.add("  ");    //使下拉框有置空的选择//遍历每个城市for (City city : cityList) {String cityName = city.getCityName();cityNames.add(cityName);}cityNames.add(0, areaName);createRowData(dictDataSheet.createRow(index++),cityNames);// 3.创建城市rowint i2 = 0;createExcelName(wb,cityNames.get(i2++),index,cityNames.size()-1,true);  //3.城市row,指定名称管理}areaNames.add(0, proName);createRowData(dictDataSheet.createRow(index++),areaNames);// 2.创建地区rowint i1 = 0;createExcelName(wb,areaNames.get(i1++),index,areaNames.size()-1,true);  //2.地区row,指定名称管理}createRowData(dictDataSheet.createRow(0),provinceNames);    //  1.创建省份row,写入数据createExcelName(wb,DICT_MNGNAME,1,provinceNames.size()-1, false);       //1.省份row,指定名称管理wb.setSheetHidden(wb.getSheetIndex(DICT_SHEET_DATA), true);     //设置隐藏的sheetreturn wb;
}

第二部分:

此部分方法都是第一部分核心处理所要使用的几个函数:

  1. 创建隐藏sheet数据行的函数
  2. 创建名称管理器的函数
  3. 创建名称管理器所需要的:计算列的表达式的函数
  4. 设置数据有效性的函数
  5. 数据验证的函数
代码如下:
/*** 第二部分:2.1     创建隐藏sheet数据行的函数*/
private static void createRowData(Row curRow,List<String> dataList){if(dataList != null && dataList.size()>0){int m = 0;for (String dataValue : dataList) {Cell dataCell = curRow.createCell(m++);dataCell.setCellValue(dataValue);}}
}
/*** 第二部分:2.2     创建名称管理器的函数  每一行数据创建一个*/
private static void createExcelName(HSSFWorkbook workbook,String nameCode,int order,int size,boolean cascadeFlag){Name name;name = workbook.createName();name.setNameName(nameCode);String cellString = DICT_SHEET_DATA + "!" + createExcelNameList(order,size,cascadeFlag);name.setRefersToFormula(cellString);
}
/*** 第二部分:2.3     名称数据行列计算表达式*/
private static String createExcelNameList(int order,int size,boolean cascadeFlag){char start='A';if(cascadeFlag){start = 'B';if(size <= 25){char end = (char)(start + size -1);return "$" + start + "$" + order + ":$" + end + "$" + order;}else{char endPrefix = 'A';char endSuffix = 'A';if((size-25)/26 == 0 || size ==51){ //26-51之间,包括边界if((size-25)%26 == 0){  //边界值endSuffix = (char)('A' + 25);}else{endSuffix = (char)('A' + (size-25)%26-1);}}else{  //51之上if((size-25)%26 == 0){endSuffix = (char)('A' + 25);endPrefix = (char)(endPrefix + (size-25)/26 -1);}else{endSuffix = (char)('A' + (size-25)%26-1);endPrefix = (char)(endPrefix + (size-25)/26);}}return "$" + start + "$" + order + ":$" + endPrefix+endSuffix + "$" + order;}}else{if(size<=26){char end = (char)(start + size -1);return "$" + start + "$" + order + ":$" + end + "$" + order;}else{char endPrefix = 'A';char endSuffix = 'A';if(size%26 == 0){endSuffix = (char)('A' + 25);if(size>52 && size/26>0){endPrefix = (char)(endPrefix + size/26-2);}}else{endSuffix = (char)('A' + size%26-1);if(size>52 && size/26>0){endPrefix = (char)(endPrefix + size/26-1);}}return "$" + start + "$" + order + ":$" + endPrefix+endSuffix + "$" + order;}}
}
/*** 第二部分:2.4 设置数据的有效性,即下拉列表的生成*/
public static HSSFWorkbook getWorkbook(HSSFWorkbook wb, int size){Sheet sheet = wb.getSheet(DICT_SHEET_TEST);DataValidation dataValidation = null;for (int x = 1; x <= size+1; x++) {dataValidation = getDataValidation("IF($B$"+x+"=\"  \",\"  \",INDIRECT($B$"+x+"))", x, 3);sheet.addValidationData(dataValidation);dataValidation = getDataValidation("IF($C$"+x+"=\"  \",\"  \",INDIRECT($C$"+x+"))", x, 4);sheet.addValidationData(dataValidation);}return wb;
}
/*** 第二部分:2.5 数据验证*/
@SuppressWarnings("deprecation")
private static DataValidation getDataValidation(String formulaString,int naturalRowIndex,int naturalColIndex){//设置数据有效性加载在哪个单元格上  四个参数:起始行、终止行、起始列、终止列int firstRow = naturalRowIndex-1;int lastRow = naturalRowIndex-1;int firstCol = naturalColIndex-1;int lastCol = naturalColIndex-1;CellRangeAddressList regions = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);//加载下拉列表DVConstraint constraint = DVConstraint.createFormulaListConstraint(formulaString);//数据有效性对象DataValidation dataValidation = new HSSFDataValidation(regions, constraint);//设置输入信息提示信息dataValidation.createPromptBox("下拉提示", "请选择合适的值");//设置输入错误提示信息dataValidation.createErrorBox("非法输入", "不允许输入,请选取下拉值!");return dataValidation;
}

第三部分:

此部分即获得上两部处理完成后的工作簿,然后填充数据即可。

代码如下:
/*** 创建并生成excel文档*/
public static void createExcelFile(){List<Student> studens = GetData.getStudents();      //测试数据,不影响功能try {FileOutputStream fileOutputStream = new FileOutputStream(new File(filePathName));HSSFWorkbook wb = writePorpData();                      // 创建工作簿HSSFSheet sheet = wb.getSheet(DICT_SHEET_TEST);         // 获取主工作表wb = getWorkbook(wb, studens.size());HSSFRow row = null;HSSFCell cell = null;sheet.setDefaultColumnWidth(28);row = sheet.createRow(0);           // 新增标题行cell = row.createCell(0);cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell.setCellValue("学生");cell = row.createCell(1);cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell.setCellValue("省份");cell = row.createCell(2);cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell.setCellValue("地区");cell = row.createCell(3);cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell.setCellValue("城市");int i = 1;for (Student stu : studens) {row = sheet.createRow(i);                   // 新增一行cell = row.createCell(0);cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell.setCellValue(stu.getStudentName());    // 学生姓名cell = row.createCell(1);cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell.setCellValue(stu.getProvince());       //省份cell = row.createCell(2);cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell.setCellValue(stu.getArea());           // 地区cell = row.createCell(3);cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell.setCellValue(stu.getCity());           //城市i++;}sheet.setColumnWidth(0,5000);//设置列宽sheet.setColumnWidth(1,5000);//设置列宽sheet.setColumnWidth(2,5000);//设置列宽sheet.setColumnWidth(3,5000);//设置列宽wb.write(fileOutputStream);             //生成文档fileOutputStream.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}
}

  • 附上源码下载:源码

转载于:https://www.cnblogs.com/dcncy/p/8153191.html

Java下使用Apache POI生成具有三级联动下拉列表的Excel文档相关推荐

  1. Java使用POI生成饼状图导出到word文档(饼状图)

    本篇文章主要介绍,如何使用Apache POI组件生成饼状图导出到word文档中,具体步骤看下文. 一.实现效果 Java使用POI技术生成饼状图导出到word文档中,最终生成的饼状图如下所示: 二. ...

  2. java后台处理excel_java后台利用Apache poi 生成excel文档提供前台下载示例

    之前在项目中会用到在java在后台把数据填入Word文档的模板来提供前台下载,为了自己能随时查看当时的实现方案及方便他人学习我写了这篇博客,访问量已经是我写的博客里第一了.于是乎我在学会用Java在后 ...

  3. Java实战—POI操作Excel文档、读取、写入、合并单元格

    一.POI项目简介 POI全称 Poor Obfuscation Implementation,利用POI接口可以通过JAVA操作Microsoft office 套件工具的读写功能.官网:http: ...

  4. JAVA - 使用Apache POI生成word(三)设置页边距

    JAVA - 使用Apache POI生成word(三)设置页边距 1. pom引入依赖 <dependency><groupId>org.apache.poi</gro ...

  5. JAVA - 使用Apache POI生成word(二) 设置纸张大小、调整纸张方向

    JAVA - 使用Apache POI生成word(二) 设置纸张大小.调整纸张方向 前言 之前开发时,需要将纸张方向由纵向改为横向,查询资料得出只需要设置一下纸张的长度与宽度便可实现相同的效果. 1 ...

  6. Aspose-Cells结合Apache POI生成excel文件以及转换为pdf

    最近有个需求是需要将数据库中的符合条件的交易流水导出生成为excel,并转换为pdf,提供给客户下载,客户下载核对并签章. 需要用到的jar包依赖: <dependency><gro ...

  7. 根据省份证号前6位数字生成的三级联动下拉菜单

    <Script language="JavaScript"> // 定义一级数组 var D0=new Array('("北京市","11 ...

  8. 关于Apache / poi 生成word文档之后不能正常换行的问题

    近期公司项目有个把文本转成word文档的功能,开始使用io操作输出文件的方式(后缀名是docx),使用手机自带的文档浏览工具打开是没有问题的,但是在电脑上用微软office就打开有问题了,于是找了三方 ...

  9. 【操作word】Java + POI导出富文本的内容到word文档

    这周工作中,遇到一个需求是需要将数据库中富文本内容导出到word文档里面,于是就采用POI技术实现了一下导出word文档的功能.(word文档是识别html内容的,所以富文本内容也自然能够识别.) 一 ...

最新文章

  1. JGG | 这么漂亮的Venn网络竟然可以一步在线绘制?
  2. PANS最新脑神经科学研究:激活一种新语言并不费力气
  3. python字符串用android,通过s从android客户端向python服务器发送字符串
  4. gradle多工程打包冲突问题
  5. react实现上传文件进度条功能_React.js 可拖放文件的上传表单(支持多文件和进度显示)...
  6. windows linux—unix 跨平台通信集成控制系统
  7. 差速移动机器人之位姿整定
  8. 在Migration中操作新添加的字段
  9. 小程序----API
  10. SystemC Study
  11. 10个技巧,帮你改进UI设计
  12. r去掉向量中的空字符串 在R里如何去掉字符串矩阵中的空字符串 r r 识别字符串中的双引号 识别字符串中的双引号 str_detect
  13. 耳机插头3.5与2.5三段与四段i版与n版等详解
  14. 图片的合成(个人练习,不喜勿喷!)
  15. 大学生计算机PHP实训报告,大学生计算机实训心得体会
  16. excel2016中绘制多条折线的散点图
  17. 分门别类刷leetcode——高级数据结构(字典树,前缀树,trie树,并查集,线段树)
  18. 《做最好的员工》第一章:好员工才会成功
  19. iOS中把故事板中视功能和美工结合在1起
  20. Java SE学习之【网络编程JavaSocket】

热门文章

  1. kafka的消费者客户端偏移的维护
  2. “芯”视野主题系列—— 加密芯片在医疗、美容行业内的应用
  3. VB一个可以改变箭头方向的气泡提示
  4. 叶氏量能大抄底(通达信副图)
  5. 国内NLP领域单轮融资新纪录,达观数据获1.6亿元B轮投资
  6. 寻找优秀的AI公司与受人尊敬的资本助推者 | 量子位年度评选进行时
  7. 上岗乌镇大会安防的智慧警眼“云镜”,是谁家的AR眼镜?
  8. 南大首届AI本科课程曝光:周志华为第一批00后,准备了大剂量烧脑数学
  9. 与神经网络相比,你对P图一无所知
  10. Apache RocketMQ 发布 v4.4.0,新添权限控制和消息轨迹特性