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
相关产品推荐
相关产品推荐

