【问题标题】:What's the simplest way to import a System.Data.DataSet into Excel?将 System.Data.DataSet 导入 Excel 的最简单方法是什么?
【发布时间】:2010-10-06 04:34:19
【问题描述】:

在 .NET 2.0(在本例中为 VB)中,是否有标准 API 可以将 DataSet 对象序列化为可以保存为制表符分隔文件并直接在 Excel 中打开的流?还是必须通过遍历表集合的成员来手动创建分隔文件?

在这种情况下,DataSet 很小,由大约 10 个 DataTables 组成,每个 DataTables 有一到几十行。我只是想知道是否有处理这种情况的内置机制,因为我想这是一个相对常见的机制。

理想情况下,我也希望能够通过单击返回所有内容 - 例如,客户端单击“生成报告”按钮,我组装报告,并返回包含格式化数据的 Response 对象,提示保存或打开等(我宁愿不让他们下载文件然后导入它,因为这在可用性方面似乎是不必要的麻烦。)

【问题讨论】:

    标签: .net excel serialization dataset


    【解决方案1】:

    有一个用于 Excel 的 ADO.NET 提供程序。 这意味着,如果您有一个数据集,您可以使用两个 DataAdapter 将数据从一个地方移动到另一个地方:从 Oracle 到 Excel,从 SQL 到 Excel,从 Excel 到 Oracle,等等。

    使用第一个 DA 从源填充 DataSet,然后使用第二个 DA 更新目标。 DataAdapter 不需要是同一类型 - 您可以使用任何 OleDbDataAdapter、SqlDataAdapter、OracleDataAdapter 等进行读取和更新。

    无需摆弄 CSV 或 XML 格式。无需使用办公自动化,因此无需 PIA,它可以在服务器上运行。它只是 ADO.NET。

    要连接到 Excel,请使用 Microsoft.Jet.OLEDB oledb 提供程序。

    Full Example source

    摘录:

    System.Data.DataSet ds1;
    
    const string ConnStringSql= "Provider=sqloledb;Data Source=dinoch-8;Initial Catalog=Northwind;Integrated Security=SSPI;" ;
    const string OutputFilename= "ExtractToExcel.xls";
    
    const string ConnStringExcel= 
    "Provider=Microsoft.Jet.OLEDB.4.0;" + 
    "Data Source=" + OutputFilename + ";" + 
    "Extended Properties=\"Excel 8.0;HDR=yes;\"";  // FIRSTROWHASNAMES=1;READONLY=false\"
    
    const string sqlSelect="SELECT top 10 ProductId, ProductName, QuantityPerUnit, UnitPrice, UnitsInStock, GETDATE() as Extracted  from Products order by UnitPrice";
    const string sqlInsert="INSERT INTO Extracto (ProductId, ProductName, QuantityPerUnit, UnitPrice, UnitsInStock, Extracted) VALUES (@ProductId, @ProductName, @QuantityPerUnit, @UnitPrice, @UnitsInStock, @Extracted)"; 
    
    private void ReadFromSql()
    {
        var ConnSql= new System.Data.OleDb.OleDbConnection(ConnStringSql);
    
        var da1 = new System.Data.OleDb.OleDbDataAdapter();
        da1.SelectCommand=  new System.Data.OleDb.OleDbCommand(sqlSelect);
        da1.SelectCommand.Connection= ConnSql;
    
        ds1= new System.Data.DataSet();
        da1.Fill(ds1, "Extracto");
    }
    
    
    
    private void InsertIntoExcel()
    {
        // need to update the row so the DA does the insert...
        foreach (System.Data.DataRow r in ds1.Tables[0].Rows)
        { 
          r.SetModified(); // mark the row as updated to force an insert
        }
    
        var da2 = new System.Data.OleDb.OleDbDataAdapter();
    
        da2.UpdateCommand= new System.Data.OleDb.OleDbCommand(sqlInsert);
        da2.UpdateCommand.Connection= ConnExcel;
    
        da2.UpdateCommand.Parameters.Add("@ProductId", System.Data.OleDb.OleDbType.Integer, 4, "ProductId");
        da2.UpdateCommand.Parameters.Add("@ProductName", System.Data.OleDb.OleDbType.VarWChar, 40, "ProductName");
        da2.UpdateCommand.Parameters.Add("@QuantityPerUnit", System.Data.OleDb.OleDbType.VarWChar, 20, "QuantityPerUnit");
        da2.UpdateCommand.Parameters.Add("@UnitPrice", System.Data.OleDb.OleDbType.Currency, 8, "UnitPrice");
        da2.UpdateCommand.Parameters.Add("@UnitsInStock", System.Data.OleDb.OleDbType.SmallInt, 2, "UnitsInStock");
        da2.UpdateCommand.Parameters.Add("@Extracted", System.Data.OleDb.OleDbType.Date, 8, "Extracted");
    
        da2.Update(ds1, "Extracto");
    }
    

    这不是 Excel 自动化,因此适用于在服务器上使用 Excel 自动化的注意事项不适用。

    您可以从现有的 XLS 文件(或 XLSX)开始,然后填写一个命名范围。这使您有机会在插入 ilve 数据之前应用格式等。本质上,现有的 XLS 文件是一个模板。
    或者,您可以从零开始,在运行时完全动态地创建 XLS 文件和 XLS 文件中的表/范围。在这种情况下,XLS 文件将非常普通/普通。没有格式、颜色、公式等。

    【讨论】:

      【解决方案2】:

      您还可以使用简单的 HTML 表格标签(或网格视图)在您的 .aspx 页面上的 HTML 中创建一个表格,然后在您的代码隐藏中将这一行包含在您的 page.load 中:

      Response.ContentType = "application/vnd.ms-excel"
      

      享受:)

      【讨论】:

        【解决方案3】:

        将数据集序列化为 xml DataSet.WriteXML,您可以创建一个 Xsl 将其转换为 CSV(您可以使用 XslTransform 以使用 xsl 转换 xml)

        编辑:其他选项是直接将其转换为 CSV

        Sub DataTable2CSV(ByVal table As DataTable, ByVal filename As String)
            DataTable2CSV(table, filename, vbTab)
        End Sub
        Sub DataTable2CSV(ByVal table As DataTable, ByVal filename As String, _
            ByVal sepChar As String)
            Dim writer As System.IO.StreamWriter
            Try
                writer = New System.IO.StreamWriter(filename)
        
                ' first write a line with the columns name
                Dim sep As String = ""
                Dim builder As New System.Text.StringBuilder
                For Each col As DataColumn In table.Columns
                    builder.Append(sep).Append(col.ColumnName)
                    sep = sepChar
                Next
                writer.WriteLine(builder.ToString())
        
                ' then write all the rows
                For Each row As DataRow In table.Rows
                    sep = ""
                    builder = New System.Text.StringBuilder
        
                    For Each col As DataColumn In table.Columns
                        builder.Append(sep).Append(row(col.ColumnName))
                        sep = sepChar
                    Next
                    writer.WriteLine(builder.ToString())
                Next
            Finally
                If Not writer Is Nothing Then writer.Close()
            End Try
        End Sub
        

        除非你真的想要纯 Excel 格式

        【讨论】:

        • 这远不是最简单的,转换成XML是最简单的。 XML可以直接在Excel中打开
        • 这不会正确地用引号/换行符引用值......但非常接近;-p
        • @Malfist:我不太确定,但我相信不是每个版本的 Excel 都可以打开 xml,如果我错了,请纠正我
        • 最新版可以,老的不知道,open office也可以
        【解决方案4】:

        DataSet.writeXML(Stream)然后就可以将XML文件导入Excel了

        你也可以看this utility为你做。

        【讨论】:

        • @Malfist:根据工具提示,这个答案显然没有帮助。
        • @Malfist:投票过程的哪一部分你不明白?
        • 我的回答怎么没有帮助?
        • 我同意 -1 在回答 OQ 时值得评论。 OQ 没有指定输出必须是二进制 XLS,只是它可以在 Excel 中打开。
        • +1 是迄今为止最简单的方法,这也是我的答案
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-13
        • 2010-09-14
        • 2010-10-06
        • 1970-01-01
        • 2012-11-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多