java使用POI做多级联动导出excel

主要解决excel动态模板下拉联动问题:

如图:

下拉联动处理代码:

下拉长度在255以内:

private static DataValidation setDataValidation(Sheet sheet, String[] textList, int firstRow, int endRow, int firstCol, int endCol) {
        DataValidationHelper helper = sheet.getDataValidationHelper();
        //加载下拉列表内容
        DataValidationConstraint constraint = helper.createExplicitListConstraint(textList);
        constraint.setExplicitListValues(textList);
        //设置数据有效性加载在哪个单元格上。四个参数分别是:起始行、终止行、起始列、终止列
        CellRangeAddressList regions = new CellRangeAddressList((short) firstRow, (short) endRow, (short) firstCol, (short) endCol);
        //数据有效性对象
        DataValidation data_validation = helper.createValidation(constraint, regions);
        return data_validation;
    }

长度在255以上:

private static DataValidation setDataValidations(Sheet sheet, String[] textList, int firstRow, int endRows, int firstCol, int endCol, HSSFWorkbook book) {
		String hiddenSheet = "dd123";
		DVConstraint constraint = null;
		CellRangeAddressList addressList = null;
		DataValidation validation = null; // 数据验证
		HSSFSheet category1Hidden = book.createSheet(hiddenSheet); // 创建隐藏域
		for (int i = 0, length = textList.length; i < length; i++) { // 循环赋值(为了防止下拉框的行数与隐藏域的行数相对应来获取>=选中行数的数组,将隐藏域加到结束行之后)
			sheet.createRow(endRows + i).createCell(8).setCellValue(textList[i]);
		}
		Name category1Name = book.createName();
		category1Name.setNameName(hiddenSheet);
		category1Name.setRefersToFormula(hiddenSheet + "!I1:A" + (textList.length + endRows));
		constraint = DVConstraint.createFormulaListConstraint(hiddenSheet);
		addressList = new CellRangeAddressList((short) firstRow, (short) endRows, (short) firstCol, (short) endCol);
		validation = new HSSFDataValidation(addressList, constraint);
		book.setSheetHidden(1, true); // 1隐藏、0显示
		return validation;
	}

调用全例:

参数分别为:fileName--导出的文件名称  titleList--标题行  downData--下拉数据  downRows--下拉行  dateRows--日期格式行  textRows文本格式行

public static boolean createExcelTemp(String fileName, String[] titleList, List<String[]> downData, String[] downRows,
                                          String[] dateRows, String textRows[], HttpServletResponse response) {
		try {
			//创建工作簿
			HSSFWorkbook workbook = new HSSFWorkbook();
			//创建sheet表
			HSSFSheet sheet = workbook.createSheet("sheet1");
			// 设置表格默认列宽度为15个字节
			sheet.setDefaultColumnWidth(15);
			// 生成一个样式
			HSSFCellStyle style = workbook.createCellStyle();
			setStyle(style,workbook);
			// 生成并设置另一个样式
			HSSFCellStyle style2 = workbook.createCellStyle();
			setStyle2(style2,workbook);
			// 声明一个画图的顶级管理器
//			HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
			//生成标题行
			HSSFRow row = sheet.createRow(0);
			int Cell = 0;
			for(int i=0;i<titleList.length;i++) {
				HSSFCell cell = row.createCell(Cell);
				cell.setCellStyle(style);
				HSSFRichTextString text = new HSSFRichTextString(titleList[i]);
				cell.setCellValue(text);
				Cell++;
			}
			//添加下拉列表
			for(int i=0;i<downRows.length;i++) {
				int num = Integer.parseInt(downRows[i]);
				if(downData.get(i).length>=255){
					sheet.addValidationData(setDataValidations(sheet,downData.get(i),1,10000,num,num,workbook));
				}else{
					sheet.addValidationData(setDataValidation(sheet,downData.get(i),1,10000,num,num));
				}
			}
			//添加日期格式校验
			for(int i=0;i<dateRows.length;i++) {
				int num = Integer.parseInt(dateRows[i]);
				sheet.addValidationData(setDate(1,10000,num,num));
			}
			//设置文本格式
			CellStyle textStyle = workbook.createCellStyle();
            DataFormat format = workbook.createDataFormat();  
            textStyle.setDataFormat(format.getFormat("@")); 
			for (int j = 1; j < 10000; j++) {
				 Row rowID = sheet.createRow(j); 
				 for(int i=0;i<textRows.length;i++) {
					 int num = Integer.parseInt(textRows[i]);
					 Cell cell1 = rowID.createCell((short) num);  
		             cell1.setCellStyle(textStyle);
				 }
			}
			System.out.println("导出文件名称:"+fileName);
			response.setContentType("application/vnd.ms-excel");
			response.setCharacterEncoding("utf-8");  
			response.setHeader("Content-disposition", "attachment;filename=" + new String(fileName.getBytes("gbk"), "iso8859-1")+".xls");
			OutputStream ouputStream = response.getOutputStream();
			workbook.write(ouputStream);
			ouputStream.flush();   
			ouputStream.close();
			return true;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

 

### 如何使用 EasyExcel 创建包含下拉列表的 Excel 导入模板 创建带有下拉列表的 Excel 文件可以显著提高数据输入效率并减少错误。通过 EasyExcel 库,这一过程变得简单而高效。 #### 准备工作环境 为了能够顺利运行代码片段,确保已经引入了 EasyExcel 的依赖项到项目中: ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.0.5</version> </dependency> ``` #### 定义实体类 定义用于映射表格列的数据模型对象 (DTO),这里假设有一个简单的 `User` 类来表示用户信息表单中的字段,并指定某些列为枚举类型以便后续设置下拉选项[^1]。 ```java import com.alibaba.excel.annotation.ExcelProperty; import lombok.Data; @Data public class User { @ExcelProperty("姓名") private String name; @ExcelProperty(value = "性别", converter = GenderEnumConverter.class) private Integer gender; // 性别采用整数编码 } ``` 注意,在上面的例子中,对于需要设定下拉框的内容(比如性别),应该自定义转换器 `GenderEnumConverter` 来处理字符串与数值之间的相互转化逻辑。 #### 编写自定义转换器 编写一个继承于 `StringToStringConverter` 或者其他合适父类的转换器,重载其方法完成特定业务需求下的值解析操作。 ```java import com.alibaba.excel.converters.Converter; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.property.ContentProperty; public class GenderEnumConverter implements Converter<Integer> { @Override public Class<?> supportJavaTypeKey() { return Integer.class; } @Override public CellData<String> convertToExcelData(Integer value, ContentProperty contentProperty, GlobalConfiguration globalConfiguration) { switch (value){ case 0 : return new CellData<>("男"); case 1 : return new CellData<>("女"); default: throw new IllegalArgumentException(); } } @Override public Integer convertToJavaData(CellData cellData, ContentProperty fieldMetadata, GlobalConfiguration readContext) throws Exception { String textValue = cellData.getStringValue(); if ("男".equals(textValue)){ return 0; }else if("女".equals(textValue)){ return 1; } else{ throw new IllegalArgumentException(); } } } ``` #### 设置验证规则和样式 利用 EasyExcel 提供的支持 API 对目标单元格应用数据有效性约束条件——即所谓的“下拉列表”。 ```java import com.alibaba.excel.write.handler.AbstractCellWriteHandler; import org.apache.poi.ss.usermodel.*; import java.util.List; class DropdownListWriteHandler extends AbstractCellWriteHandler { private final List<String> dropdownOptions; public DropdownListWriteHandler(List<String> options) { this.dropdownOptions = options; } @Override protected void afterCellDispose(WriteSheetHolder writeSheetHolder, List<CellRangeAddress> list, int relativeRowIndex, Boolean isHead) { Sheet sheet = writeSheetHolder.getSheet(); DataValidationHelper helper = sheet.getDataValidationHelper(); // 构建下拉列表范围 CellRangeAddress region = new CellRangeAddress( relativeRowIndex + 1,// 开始行索引 relativeRowIndex + 1,// 结束行索引 1, // 起始列号 1 // 终止列号 ); // 添加下拉列表内容 DataValidationConstraint constraint = helper.createExplicitListConstraint(dropdownOptions.toArray(new String[dropdownOptions.size()])); // 将上述两者关联起来形成完整的校验规则 DataValidation validation = helper.createValidation(constraint, region); try { sheet.addValidationData(validation); } catch (Exception e) { /* Handle exception */ } } } ``` 这段代码实现了当向某一行插入新记录时自动为其第二列配置好预设好的可选条目作为输入提示的功能。 #### 执行导出流程 最后一步就是调用 EasyExcel 的静态方法启动整个文件构建的过程啦! ```java import com.alibaba.excel.EasyExcel; import com.alibaba.excel.support.ExcelTypeEnum; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public static void main(String[] args) { File file = new File("/path/to/output.xlsx"); List<User> users = Arrays.asList(/* ... */); WriteWorkbookBuilder builder = EasyExcel.write(file).excelType(ExcelTypeEnum.XLSX); builder.registerWriteHandler(new DropdownListWriteHandler(Arrays.asList("男","女"))); builder.sheet("Users").doWrite(users); } ``` 以上便是关于怎样借助 Alibaba EasyExcel 工具包快速搭建起支持多级联动选择机制的电子表格资源的相关介绍[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无情丨命运

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值