0 代码量杂谈

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/icarusliu/article/details/80759085

在使用POI导出Excel文件时,如果某个单元格需要设置成下拉选择的方式,并且下拉列表数目大于255时,直接写序列将会报错:

java.lang.IllegalArgumentException: String literals in formulas can't be bigger than 255 characters ASCII

此时可以增加一个隐藏的Sheet,然后在需要设置下拉的单元格中进行引用。也就是说单元格的来源直接这样指定:

=$A$1:$A$5

但这样做没有办法进行模糊匹配,因此再通过Excel的OFFSET等函数可以达到要求。
Java代码实现如下:

CellRangeAddressList regions = new CellRangeAddressList(1, 10000, 0, 0);
DVConstraint constraint = DVConstraint.createFormulaListConstraint("OFFSET(deviceTypeSheet!$A$1,MATCH(A6&\"*\"," +
                    "deviceTypeSheet!$A:$A,0)-1,,COUNTIF(deviceTypeSheet!$A:$A,A6&\"*\"),)");
HSSFDataValidation dataValidation = new HSSFDataValidation(regions, constraint);
// 设置输入无效数据时不显示出错警告
dataValidation.setShowErrorBox(false);
sheet.addValidationData(dataValidation);

其中最关键的就是通过createFormulaListConstraint设置的语句:

OFFSET(deviceTypeSheet!$A$1,MATCH(A6&"*",deviceTypeSheet!$A:$A,0)-1,,COUNTIF(deviceTypeSheet!$A:$A,A6&"*"),)

这几个函数的说明如下:
OFFSET(reference,rows,cols,height,width): 表示对某个区域的引用,refrerence指明的是区域,rows指明需要引用的开始行,cols表示的是需要引用该区域的开始列;height表示的是引用的区域行数;width表示的是引用的区域的列数;
如offset( A 1, 2, 2, 4, 4)表示的是引用从 A 1这个点第3行第3列开始,跨度为3行4列的区域。
MATCH(lookup_value,lookuparray,match-type): 表示从lookuparray中查找满足lookup_value表达式的值的对象,并返回其索引值。
countif(range,criteria): 与match类似,不过返回的是命中的数量

因此上面的语句就很容易理解了: 当在单元格中输入一个值后,会去指定的区域里面查找以输入值开头的值,查找命中的起点并且数目,然后再通过OFFSET函数来获取命中的序列作为下拉的来源。

猜你喜欢

转载自blog.csdn.net/icarusliu/article/details/80759085
0