将System.Data.DataSet导入Excel的最简单方法是什么?

时间:2009-02-07 20:47:54

标签: .net excel serialization dataset

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

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

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

4 个答案:

答案 0 :(得分:4)

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

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

无需摆弄CSV或XML格式。无需使用Office Automation,因此没有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 Automation的警告不适用。

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

答案 1 :(得分:0)

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

您还可以查看this utility为您完成此操作。

答案 2 :(得分:0)

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

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

享受:)

答案 3 :(得分:-2)

将数据集发送到xml DataSet.WriteXML,您可以创建一个Xsl,将其转换为CSV(您可以使用XslTransform将xml转换为XSL)

编辑:其他选项是直接将其转换为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格式