解析Excel表格列数异常

版本:23.8
编程语言:java

问题现象:
第二个sheet检测出来16000+列,实际没有这么多列

源文件:
2024.11-原材料栾(2.18铁选矿污泥清理) (1).xlsx.zip (287.6 KB)

测试代码:

public static void main(String[] args) throws Exception{
        FileInputStream fileInputStream = new FileInputStream("C:\\Users\\lijiabao\\Downloads\\2024.11-原材料栾(2.18铁选矿污泥清理) (1).xlsx");
        byte[] stream = IOUtils.readStreamAsByteArray(fileInputStream);
        checkExcelColumn(stream);
        }
    private  static void checkExcelColumn(byte[] bytes) throws Exception{
        int excelColumn = 200;
        int excelRow = 10000;

        Workbook workbook = new Workbook(new ByteArrayInputStream(bytes));
        Worksheet worksheet;
        int maxColumn = 0;
        int maxRow = 0;
        try {
            Iterator<Worksheet> iterator = workbook.getWorksheets().iterator();
            int i = 1;
            while (iterator.hasNext()) {
                worksheet = iterator.next();
                maxColumn = worksheet.getCells().getMaxColumn() + 1;
                maxRow = worksheet.getCells().getMaxRow() + 1;
                //校验行数
                if (maxRow > excelRow){
                    System.out.println( "sheet:   " + i  +  "  maxRow: " + maxRow);
                }
                //校验列数
                if (maxColumn > excelColumn){
                    System.out.println("sheet:   " + i  +  "  maxColumn: " + maxColumn);
                }
                i++;
            }
        }catch (Exception e){
            if(e.getMessage().contains("上传的excel文件行或列超过oss后台设置的值")){
                throw e;
            }
        }
    }```

@ZhonghaoSun

在处理Excel文件时,如果您发现第二个工作表的列数异常(例如检测到16000+列),这可能是由于文件中存在一些隐藏的或格式化的内容。以下是一些可能的解决方案和建议:

  1. 检查隐藏列:确保没有隐藏的列在工作表中。您可以在Excel中手动检查并显示所有列。

  2. 使用LoadOptions:在加载Excel文件时,您可以使用LoadOptions类来设置最大列数和行数的限制。通过设置setMaxColumnCount(int value)setMaxRowCount(int value),您可以控制导入的列和行的数量。例如:

    LoadOptions loadOptions = new LoadOptions();
    loadOptions.setMaxColumnCount(16384); // 设置最大列数为Excel的限制
    loadOptions.setMaxRowCount(1048576); // 设置最大行数为Excel的限制
    Workbook workbook = new Workbook(new ByteArrayInputStream(bytes), loadOptions);
    
  3. 检查数据有效性:确保Excel文件中的数据是有效的,特别是对于长字符串或特殊格式的数据。您可以使用setCheckDataValid(boolean value)来验证数据的有效性。

  4. 调试代码:在您的代码中,您可以添加一些调试信息,以便更好地理解列数异常的原因。例如,打印出每个工作表的列数和行数,查看是否有异常值。

  5. 文件格式问题:确保您处理的文件是正确的Excel格式(如.xlsx),并且没有损坏。尝试使用Excel打开并重新保存文件,看看是否能解决问题。

如果以上方法仍然无法解决问题,您可能需要进一步分析文件内容,或者考虑将文件简化为更小的部分进行测试。

希望这些建议能帮助您解决问题!如果您有其他问题,请随时询问。

@ZhonghaoSun
通过使用以下样例代码在最新版本v25.3上进行测试,我们可以得到正确的结果。我们发现隐藏的工作表包含了大量设置了样式的列。请参考以下样例代码。

int excelColumn = 200;
int excelRow = 10000;

Workbook workbook = new Workbook(filePath + "2024.11-原材料栾(2.18铁选矿污泥清理) (1).xlsx");
Worksheet worksheet;
int maxColumn = 0;
int maxRow = 0;
try {
    Iterator<Worksheet> iterator = workbook.getWorksheets().iterator();
    int i = 1;
    while (iterator.hasNext()) {
        worksheet = iterator.next();
        maxColumn = worksheet.getCells().getMaxColumn() + 1;
        maxRow = worksheet.getCells().getMaxRow() + 1;
        System.out.println("max row/column: " + worksheet.getName() + " " + maxRow + "   " + maxColumn);
        //校验行数
        if (maxRow > excelRow){
            System.out.println( "sheet:   " + i  +  "  maxRow: " + maxRow);
        }
        //校验列数
        if (maxColumn > excelColumn){
            System.out.println("sheet:   " + i  +  "  maxColumn: " + maxColumn);
        }
        i++;
    }
}catch (Exception e){
    if(e.getMessage().contains("上传的excel文件行或列超过oss后台设置的值")){
        throw e;
    }
}

输出结果:

max row/column: 原材料结算单 6   17
max row/column: 阳泉冀东水泥原材料(金石少) 2561   16375
sheet:   2  maxColumn: 16375
max row/column: 双良 589   20
max row/column: 金石双良 588   54
max row/column: 金石净(未付款) 13   60
max row/column: 阳泉冀东物流贸易有限公司-金隅台泥(代县)环保-铁选矿污泥 16   14

@ZhonghaoSun
如果你只想检测包含数据的列,请参考以下样例代码。

int excelColumn = 200;
int excelRow = 10000;

Workbook workbook = new Workbook(filePath + "2024.11-原材料栾(2.18铁选矿污泥清理) (1).xlsx");
Worksheet worksheet;
int maxColumn = 0;
int maxRow = 0;
try {
    Iterator<Worksheet> iterator = workbook.getWorksheets().iterator();
    int i = 1;
    while (iterator.hasNext()) {
        worksheet = iterator.next();
        
        maxColumn = worksheet.getCells().getMaxDataColumn() + 1;
        maxRow = worksheet.getCells().getMaxDataRow() + 1;
        System.out.println("max data row/column: " + worksheet.getName() + " " + maxRow + "   " + maxColumn);
        //校验行数
        if (maxRow > excelRow){
            System.out.println( "sheet:   " + i  +  "  maxRow: " + maxRow);
        }
        //校验列数
        if (maxColumn > excelColumn){
            System.out.println("sheet:   " + i  +  "  maxColumn: " + maxColumn);
        }
        i++;
    }
}catch (Exception e){
    if(e.getMessage().contains("上传的excel文件行或列超过oss后台设置的值")){
        throw e;
    }
}

输出结果:

max data row/column: 原材料结算单 6   17
max data row/column: 阳泉冀东水泥原材料(金石少) 2   19
max data row/column: 双良 589   20
max data row/column: 金石双良 588   54
max data row/column: 金石净(未付款) 13   60
max data row/column: 阳泉冀东物流贸易有限公司-金隅台泥(代县)环保-铁选矿污泥 15   14

这些隐藏了格式的16000+列,能否用Excel文件打开后,识别出来,并且手动删除嘛,如果可以的话,如何操作呢

@ZhonghaoSun,

我认为您可以尝试使用 worksheet.getCells().deleteBlankColumns() 方法来手动删除那些不必要的空白列以满足您的要求。