[alibaba/easyexcel]利用新sheet页做下拉选项,Attempting to write a row[0] in the range [0,136] that is already written to disk.

2023-03-29 213 views
4
触发场景描述

多个下拉选字段,创建最后一个下拉时报错

触发Bug的代码
   ![image](https://user-images.githubusercontent.com/40199577/228405533-7333487e-40fc-4f54-8cda-d39c61c013d2.png)
提示的异常或者没有达到的效果

如果去掉最后一列下拉,程序正常执行,是否是数据量影响;另外:目前每个下拉字典单独放一个sheet是可以正常运行的;

回答

1

public class ProductCellWriteHandler implements SheetWriteHandler { private Map<Integer,String[]> map = null; private int index; private char[] alphabet = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; public ProductCellWriteHandler(Map<Integer,String[]> map){ this.map = map; this.index = 0; }

@Override
public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
}

@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
    // 这里可以对cell进行任何操作
    Sheet sheet = writeSheetHolder.getSheet();
    DataValidationHelper helper = sheet.getDataValidationHelper();
    // 需要设置下拉框的sheet页
    String dictSheetName = "字典sheet";

    Workbook workbook = writeWorkbookHolder.getWorkbook();

    // 数据字典的sheet页
    Sheet dictSheet = workbook.createSheet(dictSheetName);
    // 从第二个工作簿开始隐藏,为了用户的友好性,将字典sheet隐藏掉
    this.index++;
    // 设置隐藏
    workbook.setSheetHidden(this.index, true);
    // k 为存在下拉数据集的单元格下表 v为下拉数据集
    map.forEach((k, v) -> {
        int rowLen = v.length;
        // 设置字典sheet页的值 每一列一个字典项
        for (int i = 0; i < rowLen; i++) {
            Row row = dictSheet.getRow(i);
            if (row == null) {
                row = dictSheet.createRow(i);
            }
            row.createCell(k).setCellValue(v[i]);
        }
        String excelColumn = getExcelColumn(k);
        // 下拉框数据来源 eg:字典sheet!$B1:$B2
        String refers = dictSheetName + "!$" + excelColumn + "$1:$" + excelColumn + "$" + rowLen;
        // 创建可被其他单元格引用的名称
        Name name = workbook.createName();
        // 设置名称的名字
        name.setNameName("dict" + k);
        // 设置公式
        name.setRefersToFormula(refers);
        // 下拉列表约束数据
        DataValidationConstraint constraint = helper.createFormulaListConstraint("dict" + k);
        // 设置下拉单元格的首行 末行 首列 末列
        CellRangeAddressList rangeList = new CellRangeAddressList(1, 65536, k, k);
        // 设置约束
        DataValidation validation = helper.createValidation(constraint, rangeList);
        // 阻止输入非下拉选项的值

// validation.setErrorStyle(DataValidation.ErrorStyle.STOP); validation.setShowErrorBox(true); validation.setSuppressDropDownArrow(true); validation.createErrorBox("提示","此值与单元格定义格式不一致"); // validation.createPromptBox("填写说明:","填写内容只能为下拉数据集中的单位,其他单位将会导致无法入仓"); sheet.addValidationData(validation); }); } /**

  • 将数字列转化成为字母列
  • @param num
  • @return */ private String getExcelColumn(int num) { String column = ""; int len = alphabet.length - 1; int first = num / len; int second = num % len; if (num <= len) { column = alphabet[num] + ""; } else { column = alphabet[first - 1] + ""; if (second == 0) { column = column + alphabet[len] + ""; } else { column = column + alphabet[second - 1] + ""; } } return column;

    } }

    image

7

报错报什么错?我测试没问题

7

把导出代码和报错信息帖全

4

如果你需要对每一个位置都添加校验,你需要在CellHandler添加校验

7

这个问题解决了吗?多个下拉框设置到一个sheet页时,第一个下拉框dictSheet.createRow(i),下一个下拉框 获取同一行row, 为null,再次创建却报错

2

@mkdChen @mkdChen 您好 这个问题解决了吗?遇到同样的问题,下拉框太多,不想一个下拉框一个sheet