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

Excel合并单元格在GridView中无法正常显示问题

问题描述

我有一个Excel文件,包含Emp.Id、Employee Name、Designation三列,这三列各自存在两个合并单元格,其余列均未合并。将该Excel导入并在GridView中展示时出现两个异常:

  • 原Excel中的合并单元格在GridView中显示为两个独立单元格,值仅出现在第一个单元格,第二个单元格为空
  • 原本全为空的Sunday列反而被自动合并了
尝试的代码
protected DataTable YourExcelFileProcessingMethod(Stream excelFileStream)
{
    ExcelPackage.LicenseContext = LicenseContext.Commercial;

    using (ExcelPackage package = new ExcelPackage(excelFileStream))
    {
        ExcelWorksheet worksheet = package.Workbook.Worksheets[0];

        DataTable dt = new DataTable();

        for (int col = 1; col <= worksheet.Dimension.End.Column; col++)
        {
            dt.Columns.Add("Column" + col);
        }

        for (int row = 1; row <= worksheet.Dimension.End.Row; row++)
        {
            DataRow newRow = dt.NewRow();

            for (int col = 1; col <= worksheet.Dimension.End.Column; col++)
            {
                ExcelRange cell = worksheet.Cells[row, col];

                if (cell.Merge)
                {
                    
                    newRow[col - 1] = cell.Merge && cell.Start.Row == row ? cell.Text : cell.Text;
                }
                else
                {
                    
                    newRow[col - 1] = cell.Text;
                }
            }

            dt.Rows.Add(newRow);
        }

        return dt;
    }
}

protected void btnImportData_Click(object sender, EventArgs e)
{
    if (FileUploadAttendance.HasFile)
    {
        HttpPostedFile file = FileUploadAttendance.PostedFile;

        if (file.FileName.EndsWith(".xls") || file.FileName.EndsWith(".xlsx") || file.FileName.EndsWith(".xlsm"))
        {
            DataTable dt = YourExcelFileProcessingMethod(file.InputStream);

            GridAttendance.DataSource = dt;
            GridAttendance.DataBind();
        }
        else
        {
            ScriptManager.RegisterStartupScript(this, this.GetType(), "FailureAlert", "alert('Only Excel files are accepted');", true);
        }
    }
    else
    {
        ScriptManager.RegisterStartupScript(this, this.GetType(), "FailureAlert", "alert('Please Select a file to import');", true);
    }
}


protected void GridAttendance_RowDataBound(object sender, GridViewRowEventArgs e)
{
    for (int rowIndex = GridAttendance.Rows.Count - 2; rowIndex >= 0; rowIndex--)
    {
        GridViewRow gvRow = GridAttendance.Rows[rowIndex];
        GridViewRow gvPreviousRow = GridAttendance.Rows[rowIndex + 1];
        for (int cellCount = 0; cellCount < gvRow.Cells.Count;
                                                      cellCount++)
        {
            if (gvRow.Cells[cellCount].Text ==
                                   gvPreviousRow.Cells[cellCount].Text)
            {
                if (gvPreviousRow.Cells[cellCount].RowSpan < 2)
                {
                    gvRow.Cells[cellCount].RowSpan = 2;
                }
                else
                {
                    gvRow.Cells[cellCount].RowSpan =
                        gvPreviousRow.Cells[cellCount].RowSpan + 1;
                }
                gvPreviousRow.Cells[cellCount].Visible = false;
            }
        }
    }
}   
解决方案

问题根源在于两个环节:Excel读取时未将合并单元格的值填充到所有合并区域,以及GridView合并逻辑错误匹配空值。

1. 修复Excel读取逻辑

原代码仅读取合并区域起始单元格的值,其他合并单元格位置为空。修改后直接获取合并区域的起始单元格值,填充到当前单元格对应的DataTable位置:

protected DataTable YourExcelFileProcessingMethod(Stream excelFileStream)
{
    ExcelPackage.LicenseContext = LicenseContext.Commercial;

    using (ExcelPackage package = new ExcelPackage(excelFileStream))
    {
        ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
        DataTable dt = new DataTable();

        // 创建DataTable列
        for (int col = 1; col <= worksheet.Dimension.End.Column; col++)
        {
            dt.Columns.Add("Column" + col);
        }

        // 遍历所有行,填充数据
        for (int row = 1; row <= worksheet.Dimension.End.Row; row++)
        {
            DataRow newRow = dt.NewRow();
            for (int col = 1; col <= worksheet.Dimension.End.Column; col++)
            {
                ExcelRange cell = worksheet.Cells[row, col];
                // 如果是合并单元格,取合并区域起始单元格的文本
                if (cell.Merge)
                {
                    newRow[col - 1] = worksheet.Cells[cell.MergeRange.Start.Row, cell.MergeRange.Start.Column].Text;
                }
                else
                {
                    newRow[col - 1] = cell.Text;
                }
            }
            dt.Rows.Add(newRow);
        }
        return dt;
    }
}

2. 修复GridView合并逻辑

原逻辑会把所有文本相同的单元格合并,包括空值,导致空列被错误合并。修改后仅合并非空且文本一致的单元格,同时跳过表头行:

protected void GridAttendance_RowDataBound(object sender, GridViewRowEventArgs e)
{
    // 只处理数据行,忽略表头和页脚
    if (e.Row.RowType != DataControlRowType.DataRow) return;

    for (int rowIndex = GridAttendance.Rows.Count - 2; rowIndex >= 0; rowIndex--)
    {
        GridViewRow gvRow = GridAttendance.Rows[rowIndex];
        GridViewRow gvPreviousRow = GridAttendance.Rows[rowIndex + 1];
        
        for (int cellCount = 0; cellCount < gvRow.Cells.Count; cellCount++)
        {
            string currentText = gvRow.Cells[cellCount].Text.Trim();
            string prevText = gvPreviousRow.Cells[cellCount].Text.Trim();
            
            // 仅合并非空且文本相同的单元格
            if (!string.IsNullOrEmpty(currentText) && currentText == prevText)
            {
                if (gvPreviousRow.Cells[cellCount].RowSpan < 2)
                {
                    gvRow.Cells[cellCount].RowSpan = 2;
                }
                else
                {
                    gvRow.Cells[cellCount].RowSpan = gvPreviousRow.Cells[cellCount].RowSpan + 1;
                }
                gvPreviousRow.Cells[cellCount].Visible = false;
            }
        }
    }
}

效果说明

  • 修复Excel读取后,DataTable中每个合并单元格的位置都会填充对应的值,不会出现空单元格
  • 修改GridView合并逻辑后,只会合并有实际内容且文本一致的单元格,彻底避免空列被错误合并

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 16:29:51