You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Syncfusion.XlsIO在C#合并多Excel文件时遇范围越界异常求助

问题描述

使用Syncfusion.XlsIO在C#中合并多个Excel文件到单个工作表时,当累计行数达到一定规模时触发System.ArgumentOutOfRangeException异常。触发异常的代码行如下:

IRange destinationRange = destinationWorksheet.Range[currentDestFirstRow,currentDestFirstCol, currentDestLastRow, currentDestLastCol];

异常触发时的目标范围参数为:[1037502,1,1047586,6],提前终止循环可正常生成文件,所有范围参数均为int类型,无法定位越界原因。

用户实现合并的核心代码如下:

public Test()
{
    Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("my_key");
    destinationFile = outputDataPath + "__merged.xlsx";

    // 获取待合并文件列表
    filesToMerge = Directory.GetFiles(this.inputDatapath, "*.xlsx");

    using (ExcelEngine excelEngine = new ExcelEngine())
    {
        IApplication application = excelEngine.Excel;
        application.DefaultVersion = ExcelVersion.Excel2013;
        // 初始化目标工作簿和工作表
        IWorkbook destinationWorkbook = application.Workbooks.Create(1);
        IWorksheet destinationWorksheet = destinationWorkbook.Worksheets[0];

        int currentDestFirstRow = 1;
        int currentDestFirstCol = 1;
        int currentDestLastRow = 1;
        int currentDestLastCol;

        string currentFile;

        for (int i = 0; i < filesToMerge.Length - 1; i++)
        {
            currentFile = filesToMerge[i];

            FileStream currentStream = new FileStream(currentFile, FileMode.Open, FileAccess.Read);
            IWorkbook currentWorkbook = application.Workbooks.Open(currentStream, ExcelOpenType.Automatic);
            IWorksheet currentWorksheet = currentWorkbook.Worksheets[0];
            IRange currentSourceRange = currentWorksheet.UsedRange;

            if (i == 0)
            {
                currentDestFirstRow = 1;
                currentDestFirstCol = 1;
                currentDestLastRow = currentSourceRange.LastRow;
                currentDestLastCol = currentSourceRange.LastColumn;
            }
            else
            {
                currentDestFirstRow = currentDestLastRow + 1;
                currentDestFirstCol = 1;
                currentDestLastRow = currentDestFirstRow + currentSourceRange.LastRow;
                currentDestLastCol = currentSourceRange.LastColumn;
            }

            IRange destinationRange = destinationWorksheet.Range[currentDestFirstRow, currentDestFirstCol, currentDestLastRow, currentDestLastCol];
            currentSourceRange.CopyTo(destinationRange);
            string line = (i.ToString()).PadLeft(3, '0')+Environment.NewLine;
            line += $"file={currentFile}" + Environment.NewLine;
            line += $"destination range=[{currentDestFirstRow},{currentDestFirstCol},{currentDestLastRow},{currentDestLastCol}]";
            Console.WriteLine(line);
        }

        FileStream stream = new FileStream(destinationFile, FileMode.OpenOrCreate, FileAccess.ReadWrite);
        destinationWorkbook.SaveAs(stream);
        destinationWorkbook.Close();
        stream.Close();
        excelEngine.Dispose();
    }
}
异常原因

Excel 2013版本的单工作表最大行数为1048576行,代码的行数计算逻辑存在错误:

currentDestLastRow = currentDestFirstRow + currentSourceRange.LastRow;

currentSourceRange.LastRow是源工作表已用区域的最后一行号(从1开始计数),比如源表有N行,这个值就是N。直接将目标起始行加上N,相当于重复计算了源表的起始行,导致行数多算1行。当累计行数接近1048576时,这个多算的1行就会让最终行数超过Excel上限,触发越界异常。

修复方案

1. 修正行数计算逻辑

将else分支中的行数计算改为:

else
{
    currentDestFirstRow = currentDestLastRow + 1;
    currentDestFirstCol = 1;
    // 减去1,避免重复计算源表的起始行
    currentDestLastRow = currentDestFirstRow + currentSourceRange.LastRow - 1;
    currentDestLastCol = currentSourceRange.LastColumn;
}

2. 添加行数上限校验

在创建目标范围前,添加校验逻辑避免超出Excel限制:

// 检查是否超出Excel 2013单工作表最大行数
if (currentDestLastRow > 1048576)
{
    // 可根据需求选择抛出异常或创建新工作表继续合并
    throw new InvalidOperationException("合并后行数超出Excel单工作表最大限制(1048576行)");
}

3. 优化资源释放

原代码中currentStream未用using包裹,易导致资源泄漏,修改为:

using (FileStream currentStream = new FileStream(currentFile, FileMode.Open, FileAccess.Read))
{
    IWorkbook currentWorkbook = application.Workbooks.Open(currentStream, ExcelOpenType.Automatic);
    IWorksheet currentWorksheet = currentWorkbook.Worksheets[0];
    IRange currentSourceRange = currentWorksheet.UsedRange;

    // 行数计算等逻辑...

    currentWorkbook.Close();
}

内容的提问来源于stack exchange,提问作者TexWiller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 00:25:10