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

Mat*_*att 2 c# sql excel winforms visual-studio-2017

我有一个小按钮单击代码,它将 SQL 查询输出到 Excel。

\n\n

这工作得很好,直到我在它查询的表中添加了一个新字段,现在它仍然输出相同的字段并且不包括新字段。

\n\n

代码:

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

我还尝试显式查询新字段SELECT ABC FROM Services,但没有输出任何内容。

\n\n

新领域有其价值。

\n\n

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

\n\n
\n

编辑

\n
\n\n

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

\n\n
\n

使用 EPPlus 编辑 2 解决方案

\n
\n\n

为了更新将来查看此内容的任何人,我使用了NuGet Package Manager( Project> Manage NuGet Packages) 并由 Jan Kallm\xc3\xa4n 安装EPPlus

\n\n

然后我补充道:

\n\n
using OfficeOpenXml;\nusing OfficeOpenXml.Style;\nusing System.Data.SqlClient;\nusing System.IO;\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

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

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

\n

Cai*_*ard 5

首先,我附议有关使用 EPPlus 的评论。我认为它甚至有一种将数据表转换为工作表的方法,因此这个单击事件处理程序可以归结为大约 4 行代码。看看这个问题 - Export DataTable to excel with EPPlus

其次,我认为你的实际问题是一个简单的差一错误

你说(我的转述)

如果我使用返回一列的查询,例如select abc from services,则不会输出任何内容

以下是您如何进行列输出:

for(int col = 1; col < table.Columns.Count; col++)
Run Code Online (Sandbox Code Playgroud)

您的表只有一列。运行循环的比较如下:is 1 less than 1?

错误的

循环不运行

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

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

for(int col = 1; col <= table.Columns.Count; col++)
Run Code Online (Sandbox Code Playgroud)

或者更改索引方式(按 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
Run Code Online (Sandbox Code Playgroud)

关于“但是数据没有改变,代码没有改变,并且观察到一些不同的东西”的概念 - 几乎从来没有这样的情况。更有可能的是,方程式中的某些内容被人类记错了。也许第一个编写代码的人遇到了同样的问题,只是复制了 SQL 中的最后一列来解决它,然后你/其他人看到了它,尽管“这看起来不对,但我会把它去掉......” ,然后几个月后,你会寻找并说“这曾经有用,我确信它确实有效......”

:)

不过实话说; 使用 EPPlus ;)它令人愉快、简单,直接创建 xlsx 文件(它们只是 zip 中的 xml 文件,重命名为 xlsx)并且超级简单。Excel COM 是一个令人头疼的问题,您将不必要地为自己构建一个技术支持噩梦。使用 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"));
    }
}
Run Code Online (Sandbox Code Playgroud)