我正在使用 apache poi 生成 excel 文件。我需要一个包含一个大列表的下拉菜单。我已经做到了。它在我的 ubuntu Libra 办公室和谷歌表格上运行良好。但是当我尝试使用该 xlsx 文件时,下拉列表丢失。将我的 poi 版本更新为 5.0.0 后,出现此错误
有效的公式或值列表必须小于或等于 255 字符(包括分隔符)。
我想绕过这个问题。
这是我的代码
Cell cell14 = row.createCell(14);
cell14.setCellValue("Variation - Size");
cell14.setCellStyle(cellStyle);
VariationName sizeVariationName = variationNameFacility.get(2L);
List<VariationValue> sizeVariationValues = variationValueFacility.findByVariationName(sizeVariationName);
DataValidationHelper sizeValidationHelper = sheet.getDataValidationHelper();
String[] sizeList = sizeVariationValues.stream()
.map(value -> value.getValue().replaceAll("[^a-zA-Z0-9 ]", " ") + " - (" + value.getId() + ")")
.toArray(String[]::new);
DataValidationConstraint sizeValidationConstraint = sizeValidationHelper.createExplicitListConstraint(processStringArray(sizeList));
CellRangeAddressList sizeAddressList = new CellRangeAddressList(1, 150, 14, 14);
DataValidation sizeValidation = sizeValidationHelper.createValidation(sizeValidationConstraint, sizeAddressList);
sheet.addValidationData(sizeValidation);
“有效的公式或值列表必须小于或等于 255 个字符(包括分隔符)。”是 Excel 的限制。
在你的代码中的代码行
DataValidationConstraint sizeValidationConstraint = sizeValidationHelper.createExplicitListConstraint(processStringArray(sizeList));
从给定的字符串数组创建一个由逗号分隔的值列表。如果该列表的长度大于 255,则此方法不可用。
与列表长度无关的方法是将列表项放在单独工作表的单元格中,并有一个指向该单元格范围的命名范围。然后可以使用 DataValidationHelper.createFormulaListConstraint,其中
String listFormula
是该命名范围的名称。
完整示例:
import java.io.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.*;
public class CreateExcelDataValidationListNamedRange {
public static void main(String[] args) throws Exception {
int count = 100;
String[] listItems = new String[count];
for (int i = 0; i < count; i++) {
listItems[i] = "Item " + (i+1);
}
Workbook workbook = new XSSFWorkbook();
//create sheet for storing the list items:
Sheet sheet = workbook.createSheet("ListSheet");
sheet.createRow(0).createCell(0).setCellValue("List items");
int r = 1;
for (String listItem : listItems) {
Row row = sheet.createRow(r); r++;
row.createCell(0).setCellValue(listItem);
}
//create a named range usable as list constraint
Name namedRange = workbook.createName();
namedRange.setNameName("ListItems");
String reference = "ListSheet!$A$2:$A$" + r;
namedRange.setRefersToFormula(reference);
sheet.setSelected(false);
//create sheet for using the data validation lists
sheet = workbook.createSheet("Sheet1");
sheet.createRow(0).createCell(14).setCellValue("List cells below");
DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
// following creates formula pointing to named range "ListItems"
DataValidationConstraint dataValidationConstraint = dataValidationHelper.createFormulaListConstraint("ListItems");
CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 150, 14, 14);
DataValidation dataValidation = dataValidationHelper.createValidation(dataValidationConstraint, cellRangeAddressList);
sheet.addValidationData(dataValidation);
//hide the ListSheet
//workbook.setSheetHidden(0, true);
//set Sheet1 active
workbook.setActiveSheet(1);
FileOutputStream out = new FileOutputStream("./CreateExcelDataValidationListNamedRange.xlsx");
workbook.write(out);
out.close();
workbook.close();
}
}
使用
workbook.setSheetHidden(0, true);
可以隐藏列表表。之后,普通用户将看不到它。