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

C#使用NPOI生成多工作表时第二个工作表无数据问题求助

NPOI创建多工作表Excel时第二个工作表无数据问题

我用NPOI构建包含多个工作表的Excel工作簿,首个工作表数据写入正常,第二个工作表能创建但没有数据。调试时看起来已经添加了数据,但打开表格后第二个工作表是空的。以下是我的代码:

foreach (string strServer in servers)
{
    ISheet excelSheet = workbook.CreateSheet(strServer);

    dtDatabases.Clear();
    columns.Clear();
    lbDatabases.Items.Clear();

    strConnectionDatabases = strConnectionDatabasesPart1 + strServer + strConnectionDatbasesPart2;

    using (SqlConnection con = new SqlConnection(strConnectionDatabases))
    {
        try
        {
            SqlDataAdapter adapter = new SqlDataAdapter("SELECT name FROM sys.databases", con);
            adapter.Fill(dtDatabases);

            foreach (DataRow row in dtDatabases.Rows)
            {
                lbDatabases.Items.Add(row[0].ToString());
            }
        }
        catch (Exception ex)
        {

        }
    }

    foreach (string strDatabaseName in lbDatabases.Items)
    {
        strConnectionTables = strConnectionTablesPart1 + strServer + strConnectionTablesPart2 + strDatabaseName + strConnectionTablesPart3;

        //ISheet excelSheet = workbook.CreateSheet(strDatabaseName);

        IRow row1 = excelSheet.CreateRow(intRow);

        row1.CreateCell(0).SetCellValue(strDatabaseName);

        int columnIndex = 1;
        intRow++;

        dtTables.Clear();
        dtTables.Columns.Clear();

        columns.Clear();
        //MessageBox.Show(strDatabaseName + " " + dtTables.Columns.ToString());

        using (SqlConnection con = new SqlConnection(strConnectionTables))
        {
            try
            {
                SqlDataAdapter adapter = new SqlDataAdapter("SELECT name FROM sys.tables", con);
                adapter.Fill(dtTables);

                //foreach (DataRow row in dtTables.Rows)
                //{
                //    lbTables.Items.Add(row[0].ToString());
                //}
            }
            catch (Exception ex)
            {

            }
        }

        //MessageBox.Show(strDatabaseName + " " + columns.Count().ToString());

        foreach (System.Data.DataColumn column in dtTables.Columns)
        {
            //MessageBox.Show(strDatabaseName + " " + column.ColumnName + " " + columnIndex.ToString());
            columns.Add(column.ColumnName);
            row1.CreateCell(columnIndex).SetCellValue(column.ColumnName);
            columnIndex++;
        }

        //MessageBox.Show(strDatabaseName + " " + dtTables.Rows.Count.ToString());

        foreach (DataRow row in dtTables.Rows)
        {
            //MessageBox.Show(strDatabaseName + " " + columnIndex.ToString() + " " + intRow);
            row1 = excelSheet.CreateRow(intRow);
            int cellIndex = 1;
            foreach (String col in columns)
            {
                row1.CreateCell(cellIndex).SetCellValue(row[col].ToString());
                //excelSheet.AutoSizeColumn(cellIndex);
                cellIndex++;
            }

            intRow++;
        }
    }
}

strFileName = @"\\janfs03\Public\DatabaseInventory.xls";

var fs = new FileStream(strFileName, FileMode.Create, FileAccess.ReadWrite);

using (fs)
{
    workbook.Write(fs);
    fs.Close();
}

问题原因

问题出在intRow变量上:这个变量是全局复用的,第一个工作表写完后,intRow已经累计到了一个较大的数值。当创建第二个工作表时,代码直接从这个大数值开始创建行,导致数据都被写到了工作表非常靠后的位置(前面全是空行),打开Excel时看不到这些数据,误以为工作表是空的。

修复方案

每次创建新的工作表时,将intRow重置为0,确保每个工作表的行都从第0行开始写入:

foreach (string strServer in servers)
{
    ISheet excelSheet = workbook.CreateSheet(strServer);
    intRow = 0; // 新增:重置行索引,每个工作表从头开始写

    dtDatabases.Clear();
    columns.Clear();
    lbDatabases.Items.Clear();

    // 后续代码保持不变...
}

额外建议

  • 不要忽略异常:当前代码中的catch块是空的,建议添加日志输出或错误提示,方便排查数据库连接、查询失败的问题。
  • 可以考虑使用局部变量存储行索引,避免全局变量带来的意外问题,比如在工作表循环内部声明int currentRow = 0;,替代全局的intRow。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 18:50:55