Какой самый простой способ импортировать System.Data.DataSet в Excel?

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

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

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

4 ответа

Решение

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

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

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

Для подключения к Excel используйте поставщик oledb Microsoft.Jet.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 будет довольно ванильным / простым. Нет форматирования, цветов, формул и тд.

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

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

наслаждаться:)

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

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

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

Другие вопросы по тегам