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

使用Excel Interop类从SQL数据库生成Excel文件问题求助

解决Excel Interop无法从DataSet写入数据到Excel的问题

我看了你的代码,马上发现了核心问题——你创建了SqlDataAdapter但没有把查询结果填充到DataSet里,导致ds是空的,遍历ds.Tables的循环根本不会执行,自然没有数据写入Excel。下面是修复后的完整代码,顺便帮你优化了几个潜在问题:

private void linkLabel10_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
    using (var fbd = new FolderBrowserDialog())
    {
        DialogResult result = fbd.ShowDialog();
        if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
        {
            // 简化文件名拼接,避免索引越界风险
            string comboBox1Text = comboBox1.Text.Substring(0, comboBox1.Text.IndexOf("*") - 1);
            string comboBox2Part1 = comboBox2.Text.Substring(0, comboBox2.Text.IndexOf("(") - 1);
            string comboBox2Part2 = comboBox2.Text.Substring(comboBox2.Text.IndexOf("(") + 1, 10);
            string fileTest = Path.Combine(fbd.SelectedPath, $"{comboBox1Text}-{comboBox2Part1}-{comboBox2Part2}.xlsx");

            MessageBox.Show(fileTest);
            if (File.Exists(fileTest))
            {
                File.Delete(fileTest);
            }

            // 使用参数化查询避免SQL注入风险!
            string sqlQuery = @"select PersonelKodu= ztSinifEgitimiDurum.KisiID, 
                                   İsim= dbo.cdCurrAcc.FullName, 
                                   Katılım = CASE WHEN Katilim = 1 THEN 'Katıldı' ELSE 'Katılmadı' END, 
                                   ztSinifEgitimiDurum.ID 
                               FROM dbo.ztSinifEgitimiDurum 
                               INNER JOIN dbo.cdCurrAcc ON cdCurrAcc.CurrAccCode = ztSinifEgitimiDurum.KisiID 
                                   AND cdCurrAcc.CurrAccTypeCode = ztSinifEgitimiDurum.KisiTipiID 
                               WHERE AtamaID = @AtamaID";

            SqlDataAdapter da = new SqlDataAdapter(sqlQuery, baglan);
            da.SelectCommand.Parameters.AddWithValue("@AtamaID", AtamaIDBul()); // 参数化传递ID

            DataSet ds = new DataSet();
            da.Fill(ds); // 关键!把查询结果填充到DataSet中

            Excel.Application excelApp = null;
            Excel.Workbook excelWorkBook = null;
            Excel.Worksheet excelWorkSheet = null;

            try
            {
                excelApp = new Excel.Application();
                excelWorkBook = excelApp.Workbooks.Add();
                excelWorkSheet = (Excel.Worksheet)excelWorkBook.Worksheets.Item[1];
                excelWorkSheet.Name = "Ali";

                // 写入表头
                if (ds.Tables.Count > 0)
                {
                    DataTable table = ds.Tables[0];
                    for (int i = 1; i <= table.Columns.Count; i++)
                    {
                        excelWorkSheet.Cells[1, i] = table.Columns[i - 1].ColumnName;
                        // MessageBox.Show(table.Columns[i - 1].ColumnName.ToString());
                    }

                    // 写入数据行
                    for (int j = 0; j < table.Rows.Count; j++)
                    {
                        for (int k = 0; k < table.Columns.Count; k++)
                        {
                            excelWorkSheet.Cells[j + 2, k + 1] = table.Rows[j].ItemArray[k].ToString();
                        }
                    }
                }

                excelWorkBook.SaveAs(fileTest);
                MessageBox.Show("Excel文件生成成功!");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"生成Excel时出错:{ex.Message}");
            }
            finally
            {
                // 正确释放COM资源,避免Excel进程残留
                if (excelWorkBook != null)
                {
                    excelWorkBook.Close();
                    Marshal.ReleaseComObject(excelWorkBook);
                }
                if (excelApp != null)
                {
                    excelApp.Quit();
                    Marshal.ReleaseComObject(excelApp);
                }
                if (excelWorkSheet != null)
                {
                    Marshal.ReleaseComObject(excelWorkSheet);
                }
            }
        }
    }
}

关键修复和优化点:

  • 填充DataSet:添加了da.Fill(ds),这是把SQL查询结果加载到DataSet的核心步骤,没有这一步你的DataSet是空的
  • 参数化查询:把原来的字符串拼接SQL改成参数化查询,彻底避免SQL注入风险,这是数据库操作的最佳实践
  • 资源释放:使用finally块手动释放Excel的COM对象,防止后台残留Excel进程(这是Excel Interop常见的坑)
  • 异常处理:添加了try-catch块,能捕获并提示生成过程中的错误,方便调试
  • 文件名拼接优化:用Path.Combine拼接路径,避免手动拼接字符串时的路径分隔符问题,同时拆分了字符串截取逻辑,提高可读性

额外提示:

如果你的数据量较大,Excel Interop的性能会比较差,建议考虑使用EPPlus、NPOI等开源库来生成Excel,它们不需要安装Excel,性能也更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:21:55