代码之家  ›  专栏  ›  技术社区  ›  Matt

C#SQL查询输出到Excel,输出中不包括新添加的字段

  •  1
  • Matt  · 技术社区  · 6 年前

    我有一个小按钮点击代码输出一个SQL查询到Excel。

    在我在它所查询的表中添加了一个新字段之前,这个方法工作得很好,现在它仍然输出相同的字段,而不包括新字段。

    代码:

     private void button4_Click(object sender, EventArgs e)
            {
                string SQLQuery = "SELECT * FROM Services";
                SqlConnection conn = new SqlConnection("CONNECTION STRING");
                DataSet ds = new DataSet();
                SqlDataAdapter da = new SqlDataAdapter(SQLQuery, conn);
                da.Fill(ds);
                Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
                Workbook ExcelWorkBook = null;
                Worksheet ExcelWorkSheet = null;
                ExcelApp.Visible = true;
                ExcelApp.WindowState = XlWindowState.xlMinimized;
                ExcelApp.WindowState = XlWindowState.xlMaximized;
                ExcelWorkBook = ExcelApp.Workbooks.Add(XlWBATemplate.xlWBATWorksheet);
                List<string> SheetNames = new List<string>();
                SheetNames.Add("Services Details");
                ExcelApp.ActiveWindow.Activate();
                try
                {
                    for (int i = 1; i < ds.Tables.Count; i++)
                        ExcelWorkBook.Worksheets.Add();
                    for (int i = 0; i < ds.Tables.Count; i++)
                    {
                        int r = 1;
                        ExcelWorkSheet = ExcelWorkBook.Worksheets[i + 1];
                        ExcelWorkSheet.Name = "Services";
                        for (int col = 1; col < ds.Tables[i].Columns.Count; col++)
                            ExcelWorkSheet.Cells[r, col] = ds.Tables[i].Columns[col - 1].ColumnName;
                        r++;
                        for (int row = 0; row < ds.Tables[i].Rows.Count; row++)
                        {
                            for (int col = 1; col < ds.Tables[i].Columns.Count; col++)
                                ExcelWorkSheet.Cells[r, col] = ds.Tables[i].Rows[row][col - 1].ToString();
                            r++;
                        }
                        ExcelWorkSheet.Rows[1].EntireRow.Font.Bold = true;
                        ExcelApp.Columns.AutoFit();
                    }
                    ExcelApp.Quit();
                    Marshal.ReleaseComObject(ExcelWorkSheet);
                    Marshal.ReleaseComObject(ExcelWorkBook);
                    Marshal.ReleaseComObject(ExcelApp);
                }
                catch (Exception exHandle)
                {
                    Console.WriteLine("Exception: " + exHandle.Message);
                    Console.ReadLine();
                }
            }
    

    我还尝试显式查询新字段 SELECT ABC FROM Services 什么都不输出。

    新字段中有值。

    如果我在Azure查询编辑器预览版上运行相同的查询,我会得到正确的结果。

    编辑

    好的,我把查询改为 SELECT *,1 FROM Services 然后我得到所有字段(除了新的“1”字段)如何更改循环以得到所有字段?

    使用EPPlus编辑2解决方案

    只是为了让以后看到这个的人更新一下,我用了 NuGet Package Manager ( Project &燃气轮机; Manage NuGet Packages )并已安装 EPPlus

    我接着补充说:

    using OfficeOpenXml;
    using OfficeOpenXml.Style;
    using System.Data.SqlClient;
    using System.IO;
    

    并在按钮上使用了以下代码:

        private void button4_Click(object sender, EventArgs e)
        {
            string SQLQuery = "SELECT * FROM Services";
            SqlConnection conn = new SqlConnection("CONNECTION STRING");
            DataSet ds = new DataSet();
            SqlDataAdapter da = new SqlDataAdapter(SQLQuery, conn);
            DataTable dt = new DataTable();
            da.Fill(dt);
            using (var p = new ExcelPackage())
            {
                var ws = p.Workbook.Worksheets.Add("Service");
                ws.Cells["A1"].LoadFromDataTable(dt, true);
                int totalRows = ws.Dimension.End.Row;
                int totalCols = ws.Dimension.End.Column;
                var headerCells = ws.Cells[1, 1, 1, totalCols];
                var headerFont = headerCells.Style.Font;
                headerFont.Bold = true;
                var allCells = ws.Cells[1, 1, totalRows, totalCols];
                allCells.AutoFitColumns();
                p.SaveAs(new FileInfo(@"d:\excel\Service" + DateTime.Now.ToFileTime() + ".xlsx"));
            }
        }
    

    这是一个文件的即时输出,感谢@ Caius Jard

    2 回复  |  直到 6 年前
        1
  •  4
  •   Caius Jard    6 年前

    首先,我支持关于使用EPPlus的评论。我认为它甚至有一个方法可以将一个datatable转换为一个sheet,所以这个click事件处理程序可以归结为大约4行代码。看看这个问题- Export DataTable to excel with EPPlus

    第二,我认为你的实际问题是一个简单的一错再错

    你说(我的解释)

    select abc from services ,没有输出

    下面是如何进行列输出:

    for(int col = 1; col < table.Columns.Count; col++)
    

    您的表有一列。因此,运行循环的比较是: is 1 less than 1?

    循环不运行

    如果表有10列,循环将运行9次。最后一列永远不会输出。如果查询的末尾有一个新列,您希望看到它,它不在那里是因为您的c#没有输出它,而不是因为列中的数据有点奇怪。。

    关于如何处理它,请更改您在“应循环运行”部分中所做的比较:

    for(int col = 1; col <= table.Columns.Count; col++)
    

    或者更改索引的方式(按0索引,而不是按1索引):

    for(int col = 0; col < table.Columns.Count; col++)
      excel[row, col+1] = table[row][col]; //excel is 1 based, c# is 0 based
    

    :)

    但认真地说;使用EPPlus;)它很有趣,简单,直接创建xlsx文件(它们只是zip中的xml文件,重命名为xlsx),而且非常简单。excelcom是一个非常令人头痛的问题,你不必为自己制造一个技术支持的噩梦。使用EPPlus(使用nuget包管理器添加对EPPlus的引用),您的代码看起来更像:

    using(SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM services", "PUT YOUR CONN STRING IN A CONFIG FILE")){
        DataTable dt = new DataTable();
        da.Fill(dt);
        using (ExcelPackage ep = new ExcelPackage(newFile))
        {
          ExcelWorksheet ws = ep.Workbook.Worksheets.Add("Sheetname");
          ws.Cells["A1"].LoadFromDataTable(dt, true);
          ep.SaveAs(new FileInfo("YOUR SAVE PATH HERE"));
        }
    }
    
        2
  •  2
  •   Kevin Olree    6 年前

    “服务”是表还是视图?您可能看到来自过时架构的结果(在进行更改之前缓存)。这是一个危险的“选择*”。尝试显式字段列表而不是“*”。