Какой самый простой способ импортировать System.Data.DataSet в Excel? - PullRequest
2 голосов
/ 07 февраля 2009

В .NET 2.0 (в данном случае VB) существует ли стандартный API, который будет сериализовывать объект DataSet в поток, который можно сохранить как файл с разделителями табуляции и открыть непосредственно в Excel? Или нужно вручную создать файл с разделителями, просматривая элементы коллекции таблиц?

В этом случае небольшой набор данных, состоящий из примерно 10 таблиц данных, каждая из которых содержит от одной до нескольких десятков строк. Мне просто интересно, есть ли встроенный механизм для обработки этого сценария, поскольку я полагаю, что он относительно распространен.

В идеале я хотел бы иметь возможность вернуть все это одним щелчком мыши - например, клиент нажимает кнопку «Создать отчет», я собираю отчет и возвращаю объект Response, содержащий отформатированные данные, запрашивая сохранить или открыть и т. д. (Я бы предпочел, чтобы они не загружали файл, а затем импортировали его, поскольку это кажется излишне громоздким с точки зрения удобства использования.)

Ответы [ 4 ]

4 голосов
/ 29 марта 2009

Существует поставщик ADO.NET для Excel. Это означает, что если у вас есть набор данных, вы можете использовать два адаптера данных для перемещения данных из одного места в другое: из Oracle в Excel, из SQL в Excel, из Excel в Oracle и т. Д.

Заполните DataSet из источника первым DA, затем обновите место назначения вторым DA. DataAdapters не обязательно должны быть одного типа - вы можете использовать любой из OleDbDataAdapter, SqlDataAdapter, OracleDataAdapter и т. Д. Как для чтения, так и для обновления.

Нет необходимости возиться с форматированием CSV или XML. Нет необходимости использовать Office Automation, поэтому нет PIA и он работает на серверах. Это просто ADO.NET.

Для подключения к Excel используйте Microsoft.Jet.OLEDB oledb провайдера.

Полный пример источника .

Выдержка:

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 будет довольно ванильным / простым. Нет форматирования, цветов, формул и тд.

0 голосов
/ 28 мая 2009

Вы также можете создать таблицу в своем HTML на своей странице .aspx, используя простые теги таблицы HTML (или представление сетки), а затем в своем коде включить эту строку в свою страницу. Load:

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

наслаждайся:)

0 голосов
/ 08 февраля 2009

Сериализация набора данных в 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

0 голосов
/ 07 февраля 2009

DataSet.writeXML (Stream) Затем вы можете импортировать файл XML в Excel

Вы также можете посмотреть на эту утилиту , чтобы сделать это за вас.

...