web-dev-qa-db-fra.com

Comment exporter DataTable vers Excel

Comment exporter une DataTable vers Excel en C #? J'utilise Windows Forms. La DataTable est associée à un contrôle DataGridView. Je dois exporter les enregistrements de DataTable vers Excel.

86
user1057221

Je recommanderais ClosedXML

Vous pouvez transformer un DataTable en une feuille de calcul Excel avec du code lisible very:

XLWorkbook wb = new XLWorkbook();
DataTable dt = GetDataTableOrWhatever();
wb.Worksheets.Add(dt,"WorksheetName");

Le développeur est réactif et utile. Le projet est activement développé et la documentation est superbe.

113
hmqcnoesy

Essayez un code simple, pour convertir DataTable en fichier Excel en tant que csv:

var lines = new List<string>();

string[] columnNames = dataTable.Columns.Cast<DataColumn>().
                                  Select(column => column.ColumnName).
                                  ToArray();

var header = string.Join(",", columnNames);
lines.Add(header);

var valueLines = dataTable.AsEnumerable()
                   .Select(row => string.Join(",", row.ItemArray));            
lines.AddRange(valueLines);

File.WriteAllLines("Excel.csv",lines);

Ceci écrira un nouveau fichier Excel.csv dans le "répertoire de travail en cours", qui correspond généralement à l'emplacement où se trouve le fichier .exe ou à l'emplacement de lancement. 

Notez que la sortie place des virgules (",") entre les données déjà contenues dans le dataTable. Puisqu'il n'échappe pas aux virgules dans les données, les virgules dans les données seront mal interprétées par le programme qui lit le fichier.

55
cuongle

Une option élégante consiste à écrire une méthode d’extension (voir ci-dessous) pour la classe DataTable du framework .net.

Cette méthode d'extension peut être appelée comme suit:

using System;
using System.Collections.Generic;
using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using System.Data;
using System.Data.OleDb;

DataTable dt;
// fill table data in dt here 
...

// export DataTable to Excel
// save Excel file without ever making it visible if filepath is given
// don't save Excel file, just make it visible if no filepath is given
dt.ExportToExcel(ExcelFilePath);

Méthode d'extension pour la classe DataTable:

public static class My_DataTable_Extensions
{

    // Export DataTable into an Excel file with field names in the header line
    // - Save Excel file without ever making it visible if filepath is given
    // - Don't save Excel file, just make it visible if no filepath is given
    public static void ExportToExcel(this DataTable tbl, string excelFilePath = null) {
        try {
            if (tbl == null || tbl.Columns.Count == 0)
                throw new Exception("ExportToExcel: Null or empty input table!\n");

            // load Excel, and create a new workbook
            var excelApp = new Excel.Application();
            excelApp.Workbooks.Add();

            // single worksheet
            Excel._Worksheet workSheet = excelApp.ActiveSheet;

            // column headings
            for (var i = 0; i < tbl.Columns.Count; i++) {
                workSheet.Cells[1, i + 1] = tbl.Columns[i].ColumnName;
            }

            // rows
            for (var i = 0; i < tbl.Rows.Count; i++) {
                // to do: format datetime values before printing
                for (var j = 0; j < tbl.Columns.Count; j++) {
                    workSheet.Cells[i + 2, j + 1] = tbl.Rows[i][j];
                }
            }

            // check file path
            if (!string.IsNullOrEmpty(excelFilePath)) {
                try {
                    workSheet.SaveAs(excelFilePath);
                    excelApp.Quit();
                    MessageBox.Show("Excel file saved!");
                }
                catch (Exception ex) {
                    throw new Exception("ExportToExcel: Excel file could not be saved! Check filepath.\n"
                                        + ex.Message);
                }
            } else { // no file path is given
                excelApp.Visible = true;
            }
        }
        catch (Exception ex) {
            throw new Exception("ExportToExcel: \n" + ex.Message);
        }
    }
}
37
tuncalik

Solution basée sur tuncalik (merci pour idée) article, mais dans le cas de grandes tables travaille beaucoup plus rapidement (et est un peu moins clair).

public static class My_DataTable_Extensions
{
    /// <summary>
    /// Export DataTable to Excel file
    /// </summary>
    /// <param name="DataTable">Source DataTable</param>
    /// <param name="ExcelFilePath">Path to result file name</param>
    public static void ExportToExcel(this System.Data.DataTable DataTable, string ExcelFilePath = null)
    {
        try
        {
            int ColumnsCount;

            if (DataTable == null || (ColumnsCount = DataTable.Columns.Count) == 0)
                throw new Exception("ExportToExcel: Null or empty input table!\n");

            // load Excel, and create a new workbook
            Microsoft.Office.Interop.Excel.Application Excel = new Microsoft.Office.Interop.Excel.Application();
            Excel.Workbooks.Add();

            // single worksheet
            Microsoft.Office.Interop.Excel._Worksheet Worksheet = Excel.ActiveSheet;

            object[] Header = new object[ColumnsCount];

            // column headings               
            for (int i = 0; i < ColumnsCount; i++)
                Header[i] = DataTable.Columns[i].ColumnName;

            Microsoft.Office.Interop.Excel.Range HeaderRange = Worksheet.get_Range((Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[1, 1]), (Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[1, ColumnsCount]));
            HeaderRange.Value = Header;
            HeaderRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray);
            HeaderRange.Font.Bold = true;

            // DataCells
            int RowsCount = DataTable.Rows.Count;
            object[,] Cells = new object[RowsCount, ColumnsCount];

            for (int j = 0; j < RowsCount; j++)
                for (int i = 0; i < ColumnsCount; i++)
                    Cells[j, i] = DataTable.Rows[j][i];

            Worksheet.get_Range((Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[2, 1]), (Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[RowsCount + 1, ColumnsCount])).Value = Cells;

            // check fielpath
            if (ExcelFilePath != null && ExcelFilePath != "")
            {
                try
                {
                    Worksheet.SaveAs(ExcelFilePath);
                    Excel.Quit();
                    System.Windows.MessageBox.Show("Excel file saved!");
                }
                catch (Exception ex)
                {
                    throw new Exception("ExportToExcel: Excel file could not be saved! Check filepath.\n"
                        + ex.Message);
                }
            }
            else    // no filepath is given
            {
                Excel.Visible = true;
            }
        }
        catch (Exception ex)
        {
            throw new Exception("ExportToExcel: \n" + ex.Message);
        }
    }
}
19
Tomasz Wiśniewski

Essayez cette fonction en passant le datatable et le chemin du fichier où vous voulez exporter 

public void CreateCSVFile(ref DataTable dt, string strFilePath)
{            
    try
    {
        // Create the CSV file to which grid data will be exported.
        StreamWriter sw = new StreamWriter(strFilePath, false);
        // First we will write the headers.
        //DataTable dt = m_dsProducts.Tables[0];
        int iColCount = dt.Columns.Count;
        for (int i = 0; i < iColCount; i++)
        {
            sw.Write(dt.Columns[i]);
            if (i < iColCount - 1)
            {
                sw.Write(",");
            }
        }
        sw.Write(sw.NewLine);

        // Now write all the rows.

        foreach (DataRow dr in dt.Rows)
        {
            for (int i = 0; i < iColCount; i++)
            {
                if (!Convert.IsDBNull(dr[i]))
                {
                    sw.Write(dr[i].ToString());
                }
                if (i < iColCount - 1)
                {
                    sw.Write(",");
                }
            }

            sw.Write(sw.NewLine);
        }
        sw.Close();
    }
    catch (Exception ex)
    {
        throw ex;
    }
}
13
Mayur Borad

Le meilleur et le plus simple

private void exportToExcel(DataTable dt)
    {

        /*Set up work book, work sheets, and Excel application*/
        Microsoft.Office.Interop.Excel.Application oexcel = new Microsoft.Office.Interop.Excel.Application();
        try
        {
            string path = AppDomain.CurrentDomain.BaseDirectory;
            object misValue = System.Reflection.Missing.Value;
            Microsoft.Office.Interop.Excel.Workbook obook = oexcel.Workbooks.Add(misValue);
            Microsoft.Office.Interop.Excel.Worksheet osheet = new Microsoft.Office.Interop.Excel.Worksheet();


          //  obook.Worksheets.Add(misValue);

            osheet = (Microsoft.Office.Interop.Excel.Worksheet)obook.Sheets["Sheet1"];
            int colIndex = 0;
            int rowIndex = 1;

            foreach (DataColumn dc in dt.Columns)
            {
                colIndex++;
                osheet.Cells[1, colIndex] = dc.ColumnName;
            }
            foreach (DataRow dr in dt.Rows)
            {
                rowIndex++;
                colIndex = 0;

                foreach (DataColumn dc in dt.Columns)
                {
                    colIndex++;
                    osheet.Cells[rowIndex, colIndex] = dr[dc.ColumnName];
                }
            }

            osheet.Columns.AutoFit();
            string filepath = "C:\\Temp\\Book1";

            //Release and terminate Excel

            obook.SaveAs(filepath);
            obook.Close();
            oexcel.Quit();
            releaseObject(osheet);

            releaseObject(obook);

            releaseObject(oexcel);
            GC.Collect();
        }
        catch (Exception ex)
        {
            oexcel.Quit();
            log.AddToErrorLog(ex, this.Name);
        }
    }
4
Tim

Vous pouvez utiliser EasyXLS , une bibliothèque permettant d’exporter des fichiers Excel.

Vérifiez ce code:

DataSet ds = new DataSet();
ds.Tables.Add(dataTable);

ExcelDocument xls = new ExcelDocument();
xls.easy_WriteXLSFile_FromDataSet("datatable.xls", ds, 
           new ExcelAutoFormat(Styles.AUTOFORMAT_EASYXLS1), "DataTable");

Voir aussi cet exemple sur la façon de exporter des données datables au format Excel en C # .

1
alex.pulver

Cette solution consiste essentiellement à transférer des données List<Object> vers Excel. Elle utilise DataTable pour y parvenir. J'ai implémenté une méthode d'extension. Il existe donc essentiellement deux choses nécessaire. 1. Une méthode d'extension.

public static class ReportHelper
{
    public static string ToExcel<T>(this IList<T> data)
    {
        PropertyDescriptorCollection properties =
            TypeDescriptor.GetProperties(typeof(T));
        DataTable table = new DataTable();
        foreach (PropertyDescriptor prop in properties)
        {
            //table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
            if (prop.Attributes[typeof(FGMS.Entity.Extensions.ReportHeaderAttribute)] != null)
            {
                table.Columns.Add(GetColumnHeader(prop), Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
            }
        }

        //So it seems like when there is only one row of data the headers do not appear
        //so adding a dummy blank row which fixed the issues
        //Add a blank Row - Issue # 1471
        DataRow blankRow = table.NewRow();
        table.Rows.Add(blankRow);

        foreach (T item in data)
        {
            DataRow row = table.NewRow();
            foreach (PropertyDescriptor prop in properties)
                //row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
                if (prop.Attributes[typeof(FGMS.Entity.Extensions.ReportHeaderAttribute)] != null)
                {
                    row[GetColumnHeader(prop)] = prop.GetValue(item) ?? DBNull.Value;
                }
            table.Rows.Add(row);
        }
        table.TableName = "Results";
        var filePath = System.IO.Path.GetTempPath() + "\\" + System.Guid.NewGuid().ToString() + ".xls";
        table.WriteXml(filePath);

        return filePath;
    }

    private static string GetColumnHeader(PropertyDescriptor prop)
    {
        return ((FGMS.Entity.Extensions.ReportHeaderAttribute)(prop.Attributes[typeof(FGMS.Entity.Extensions.ReportHeaderAttribute)])).ReportHeaderText;
    }       
}
  1. Décorez vos classes DTO avec l'attribut [ReportHeaderAttribute("Column Name")]
public class UserDTO
    {
        public int Id { get; set; }
        public int SourceId { get; set; }
        public string SourceName { get; set; }

        [ReportHeaderAttribute("User Type")]
        public string UsereType { get; set; }

        [ReportHeaderAttribute("Address")]
        public string Address{ get; set; }

        [ReportHeaderAttribute("Age")]
        public int Age{ get; set; }

        public bool IsActive { get; set; }

        [ReportHeaderAttribute("Active")]
        public string IsActiveString
        {
            get
            {
                return IsActive ? "Yes" : "No";
            }
        }}

Tout ce qui doit être une colonne dans Excel doit être décoré avec [ReportHeaderAttribute("Column Name")] 

Alors simplement 

Var userList = Service.GetUsers() //Returns List of UserDTO;
var excelFilePath = userList.ToExcel();

HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
            var stream = new FileStream(excelFilePath, FileMode.Open);
            result.Content = new StreamContent(stream);
            result.Content.Headers.ContentType =
                new MediaTypeHeaderValue("application/vnd.ms-Excel");
            result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "UserList.xls" };

            return result;
0
Melu

Excel Interop:

Cette méthode évite que les dates ne passent du jj-mm-aaaa à mm-jj-aaaa

public bool DataTableToExcelFile(DataTable dt, string targetFile)
{
    const bool dontSave = false;
    bool success = true;

    //Exit if there is no rows to export
    if (dt.Rows.Count == 0) return false;

    object misValue = System.Reflection.Missing.Value;
    List<int> dateColIndex = new List<int>();
    Excel.Application excelApp = new Excel.Application();
    Excel.Workbook excelWorkBook = excelApp.Workbooks.Add(misValue);
    Excel.Worksheet excelWorkSheet = excelWorkBook.Sheets("sheet1");

    //Iterate through the DataTable and populate the Excel work sheet
    try {
        for (int i = -1; i <= dt.Rows.Count - 1; i++) {
            for (int j = 0; j <= dt.Columns.Count - 1; j++) {
                if (i < 0) {
                    //Take special care with Date columns
                    if (dt.Columns(j).DataType is typeof(DateTime)) {
                        excelWorkSheet.Cells(1, j + 1).EntireColumn.NumberFormat = "d-MMM-yyyy;@";
                        dateColIndex.Add(j);
                    } 
                    //else if ... Feel free to add more Formats

                    else {
                        //Otherwise Format the column as text
                        excelWorkSheet.Cells(1, j + 1).EntireColumn.NumberFormat = "@";
                    }
                    excelWorkSheet.Cells(1, j + 1) = dt.Columns(j).Caption;
                } 
                else if (dateColIndex.IndexOf(j) > -1) {
                    excelWorkSheet.Cells(i + 2, j + 1) = Convert.ToDateTime(dt.Rows(i).ItemArray(j)).ToString("d-MMM-yyyy");
                } 
                else {
                    excelWorkSheet.Cells(i + 2, j + 1) = dt.Rows(i).ItemArray(j).ToString();
                }
            }
        }

        //Add Autofilters to the Excel work sheet  
        excelWorkSheet.Cells.AutoFilter(1, Type.Missing, Excel.XlAutoFilterOperator.xlAnd, Type.Missing, true);
        //Autofit columns for neatness
        excelWorkSheet.Columns.AutoFit();
        if (File.Exists(exportFile)) File.Delete(exportFile);
        excelWorkSheet.SaveAs(exportFile);
    } catch {
        success = false;
    } finally {
        //Do this irrespective of whether there was an exception or not. 
        excelWorkBook.Close(dontSave);
        excelApp.Quit();
        releaseObject(excelWorkSheet);
        releaseObject(excelWorkBook);
        releaseObject(excelApp);
    }
    return success;
}

Si vous ne vous souciez pas des dates retournées, utilisez le lien voir qui montre comment remplir toutes les cellules de la feuille de calcul Excel en une seule ligne de code:

Excel Interop - Efficacité et performance

CSV:

public string DataTableToCSV(DataTable dt, bool includeHeader, string rowFilter, string sortFilter, bool useCommaDelimiter = false, bool truncateTimesFromDates = false)
{
    dt.DefaultView.RowFilter = rowFilter;
    dt.DefaultView.Sort = sortFilter;
    DataView dv = dt.DefaultView;
    string csv = DataTableToCSV(dv.ToTable, includeHeader, useCommaDelimiter, truncateTimesFromDates);
    //reset the Filtering
    dt.DefaultView.RowFilter = string.Empty;
    return csv;
}

public string DataTableToCsv(DataTable dt, bool includeHeader, bool useCommaDelimiter = false, bool truncateTimesFromDates = false)
{
    StringBuilder sb = new StringBuilder();
    string delimter = Constants.vbTab;
    if (useCommaDelimiter)
        delimter = ",";

    if (includeHeader) {
        foreach (DataColumn dc in dt.Columns) {
            sb.AppendFormat("{0}" + Constants.vbTab, dc.ColumnName);
        }

        //remove the last Tab
        sb.Remove(sb.ToString.Length - 1, 1);
        sb.Append(Environment.NewLine);
    }

    foreach (DataRow dr in dt.Rows) {
        foreach (DataColumn dc in dt.Columns) {
            if (Information.IsDate(dr(dc.ColumnName).ToString()) & dr(dc.ColumnName).ToString().Contains(".") == false & truncateTimesFromDates) {
                sb.AppendFormat("{0}" + delimter, Convert.ToDateTime(dr(dc.ColumnName).ToString()).Date.ToShortDateString());
            } else {
                sb.AppendFormat("{0}" + delimter, CheckDBNull(dr(dc.ColumnName).ToString().Replace(",", "")));
            }
        }
        //remove the last Tab
        sb.Remove(sb.ToString.Length - 1, 1);
        sb.Append(Environment.NewLine);
    }
    return sb.ToString;
}

public enum enumObjectType
{
    StrType = 0,
    IntType = 1,
    DblType = 2
}

public object CheckDBNull(object obj, enumObjectType ObjectType = enumObjectType.StrType)
{
    object objReturn = null;
    objReturn = obj;
    if (ObjectType == enumObjectType.StrType & Information.IsDBNull(obj)) {
        objReturn = "";
    } else if (ObjectType == enumObjectType.IntType & Information.IsDBNull(obj)) {
        objReturn = 0;
    } else if (ObjectType == enumObjectType.DblType & Information.IsDBNull(obj)) {
        objReturn = 0.0;
    }
    return objReturn;
}
0
Jeremy Thompson
Private tmr As System.Windows.Forms.Timer

Private Sub TestExcel() Handles Button1.Click

    '// Initial data: SQL Server table with 6 columns and 293000 rows.


    '// Data table holding all data
    Dim dt As New DataTable("F161")

    '// Create connection
    Dim conn As New SqlConnection("Server=MYSERVER;Database=Test;Trusted_Connection=Yes;")
    Dim fAdapter As New SqlDataAdapter With
    {
        .SelectCommand = New SqlCommand($"SELECT * FROM dbo.MyTable", conn)
    }

    '// Fill DataTable
    fAdapter.Fill(dt)

    '// Create Excel application
    Dim xlApp As New Excel.Application With {.Visible = True}

    '// Temporarily disable screen updating
    xlApp.ScreenUpdating = False

    '// Create brand new workbook
    Dim xlBook As Excel.Workbook = xlApp.Workbooks.Add()
    Dim xlSheet As Excel.Worksheet = DirectCast(xlBook.Sheets(1), Excel.Worksheet)

    '// Get number of rows
    Dim rows_count = dt.Rows.Count
    '// Get number of columns
    Dim cols_count = dt.Columns.Count

    '// Here 's the core idea: after receiving data
    '// you need to create an array and transfer it to sheet.
    '// Why array?
    '// Because it's the fastest way to transfer data to Excel's sheet.
    '// So, we have two tasks:
    '// 1) Create array
    '// 2) Transfer array to sheet

    '// =========================================================
    '// TASK 1: Create array
    '// =========================================================
    '// In order to create array, we need to know that
    '// Excel's Range object expects 2-D array whose lower bounds
    '// of both dimensions start from 1.
    '// This means you can't use C# array.
    '// You need to manually create such array.
    '// Since we already calculated number of rows and columns,
    '// we can use these numbers in creating array.
    Dim arr = Array.CreateInstance(GetType(Object), {rows_count, cols_count}, {1, 1})

    '// Fill array
    For r = 0 To rows_count - 1
        For c = 0 To cols_count - 1
            arr(r + 1, c + 1) = dt.Rows(r)(c)
        Next
    Next

    '// =========================================================
    '// TASK 2: Transfer array to sheet
    '// =========================================================
    '// Now we need to transfer array to sheet.
    '// So, how transfer array to sheet fast?
    '// 
    '// THE FASTEST WAY TO TRANSFER DATA TO SHEET IS TO ASSIGN ARRAY TO RANGE.
    '// We could, of course, hard-code values, but Resize property
    '// makes this work a breeze:
    xlSheet.Range("A1").Resize.Resize(rows_count, cols_count).Value = arr

    '// If we decide to dump data by iterating over array,
    '// it will take LOTS of time.
    '// For r = 1 To rows_count
    '//     For c = 1 To cols_count
    '//         xlSheet.Cells(r, c) = arr(r, c)
    '//     Next
    '// Next

    '// Here are time results:
    '// 1) Assigning array to Range: 3 seconds
    '// 2) Iterating over array: 45 minutes

    '// Turn updating on
    xlApp.ScreenUpdating = True
    xlApp = Nothing
    xlBook = Nothing
    xlSheet = Nothing

    '// Here we have another problem:
    '// creating array took lots of memory (about 150 MB).
    '// Using 'GC.Collect()', by unknown reason, doesn't help here.
    '// However, if you run GC.Collect() AFTER this procedure is finished
    '// (say, by pressing another button and calling another procedure),
    '// then the memory is cleaned up.
    '// I was wondering how to avoid creating some extra button to just release memory,
    '// so I came up with the idea to use timer to call GC.
    '// After 2 seconds GC collects all generations.
    '// Do not forget to dispose timer since we need it only once.

    tmr = New Timer()
    AddHandler tmr.Tick,
        Sub()
            GC.Collect()
            GC.WaitForPendingFinalizers()
            GC.WaitForFullGCComplete()
            tmr.Dispose()
        End Sub
    tmr.Interval = TimeSpan.FromSeconds(2).TotalMilliseconds()
    tmr.Start()

End Sub
0
JohnyL

Vieux fil - mais je pensais que je jetterais mon code ici. J'ai écrit une petite fonction pour écrire une table de données dans une nouvelle feuille Excel à un chemin spécifié (emplacement). Vous devrez également ajouter une référence à la bibliothèque Microsoft Excel 14.0. 

J'ai tiré de ce fil sur quoi que ce soit d'écrire dans Excel - Comment écrire des données dans un fichier Excel (.xlsx)

j'ai utilisé cela pour extrapoler comment écrire un datatable

* note dans les instructions catch, j'ai une référence de classe statique errorhandler (vous pouvez les ignorer)

 using Excel = Microsoft.Office.Interop.Excel;
 using System.IO;
 using System.Data;
 using System.Runtime.InteropServices;

 //class and namespace wrapper is not shown in this example 

 private void WriteToExcel(System.Data.DataTable dt, string location)
    {
        //instantiate Excel objects (application, workbook, worksheets)
        Excel.Application XlObj = new Excel.Application();
        XlObj.Visible = false;
        Excel._Workbook WbObj = (Excel.Workbook)(XlObj.Workbooks.Add(""));
        Excel._Worksheet WsObj = (Excel.Worksheet)WbObj.ActiveSheet;

        //run through datatable and assign cells to values of datatable
        try
        {
            int row = 1; int col = 1;
            foreach (DataColumn column in dt.Columns)
            {
                //adding columns
                WsObj.Cells[row, col] = column.ColumnName;
                col++;
            }
            //reset column and row variables
            col = 1;
            row++;
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                //adding data
                foreach (var cell in dt.Rows[i].ItemArray)
                {
                    WsObj.Cells[row, col] = cell;
                    col++;
                }
                col = 1;
                row++;
            }
            WbObj.SaveAs(location);
        }
        catch (COMException x)
        {                
            ErrorHandler.Handle(x);
        }
        catch (Exception ex)
        {               
            ErrorHandler.Handle(ex);
        }
        finally
        {
            WbObj.Close();                
        }
    }
0
Matt Farguson

Pour exporter des données vers Excel, vous pouvez utiliser la bibliothèque ClosedXML.Report ( https://github.com/ClosedXML/ClosedXML.Report ). Croyez-moi, cette bibliothèque est merveilleuse et facile à utiliser. La bibliothèque n'a pas besoin d'Excel Interop. ClosedXML.Report génère un fichier Excel basé sur un modèle que vous pouvez créer dans Excel en utilisant n'importe quel formatage. Par exemple:

    var template = new XLTemplate(@".\Templates\report.xlsx");

    using (var db = new DbDemos())
    {
        var cust = db.customers.LoadWith(c => c.Orders).First();
        template.AddVariable(cust);
        template.Generate();
    }

    template.SaveAs(outputFile);
0
b0bi

Utilisez simplement le fichier CloseMXL.Excel Library . C'est facile et assez rapide aussi.

Classe

private DataTable getAllList()
        {
            string constr = ConfigurationManager.ConnectionStrings["RConnection"].ConnectionString;
            using (SqlConnection con = new SqlConnection(constr))
            {
                using (SqlCommand cmd = new SqlCommand("SELECT EmpId, gender, EmpName, pOnHold FROM Employee  WHERE EmpId= '"+ AnyVariable + "' ORDER BY EmpName"))
                {
                    using (SqlDataAdapter da = new SqlDataAdapter())
                    {
                        DataTable dt = new DataTable();
                        cmd.CommandType = CommandType.Text;
                        cmd.Connection = con;
                        da.SelectCommand = cmd;
                        da.Fill(dt);
                        dt.Columns[0].ColumnName = "Employee Id";
                        dt.Columns[1].ColumnName = "Gender";
                        dt.Columns[2].ColumnName = "Employee Name";
                        dt.Columns[3].ColumnName = "On Hold";

                        return dt;
                    }
                }
            }
        }

Puis une autre méthode qui récupère le jeu de données

public DataSet getDataSetExportToExcel()
        {
            DataSet ds = new DataSet();
            DataTable dtEmp = new DataTable("CLOT List");
            dtEmp = getAllList();
             ds.Tables.Add(dtEmp);
             ds.Tables[0].TableName = "Employee"; //If you which to use Mutliple Tabs
             return ds;
          }

Maintenant, vous cliquez sur l'événement de clic

protected void btn_Export_Click(object sender, EventArgs e)
        {
            DataSet ds = getDataSetExportToExcel();

            using (XLWorkbook wb = new XLWorkbook())
            {
                wb.Worksheets.Add(ds);
                wb.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
                wb.Style.Font.Bold = true;

                Response.Clear();
                Response.Buffer = true;
                Response.Charset = "";
                Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                Response.AddHeader("content-disposition", "attachment;filename=EmployeeonHoldList.xlsx");

                using (MemoryStream MyMemoryStream = new MemoryStream())
                {
                    wb.SaveAs(MyMemoryStream);
                    MyMemoryStream.WriteTo(Response.OutputStream);

                    Response.Flush();
                    Response.End();
                }
            }
        }
0
PatsonLeaner

utiliser la classe suivante

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Excel = Microsoft.Office.Interop.Excel;
using EL = ExcelLibrary.SpreadSheet;
using System.Drawing;
using System.Collections;
using System.Runtime.InteropServices;
using System.Windows.Forms;


namespace _basic
{
public class ExcelProcesser
{
    public void WriteToExcel(System.Data.DataTable dt)
    {
        Excel.Application XlObj = new Excel.Application();
        XlObj.Visible = false;
        Excel._Workbook WbObj = (Excel.Workbook)(XlObj.Workbooks.Add(""));
        Excel._Worksheet WsObj = (Excel.Worksheet)WbObj.ActiveSheet;
        object misValue = System.Reflection.Missing.Value;


        try
        {
            int row = 1; int col = 1;
            foreach (DataColumn column in dt.Columns)
            {
                //adding columns
                WsObj.Cells[row, col] = column.ColumnName;
                col++;
            }
            //reset column and row variables
            col = 1;
            row++;
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                //adding data
                foreach (var cell in dt.Rows[i].ItemArray)
                {
                    WsObj.Cells[row, col] = cell;
                    col++;
                }
                col = 1;
                row++;
            }
            WbObj.SaveAs(fileFullName, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        finally
        {
            WbObj.Close(true, misValue, misValue);
        }
    }
}

}

0
Malek Tubaisaht

Une façon de le faire serait aussi avec ACE OLEDB Provider (voir aussi chaînes de connexion pour Excel ). Bien sûr, vous devez avoir installé et enregistré le fournisseur. Vous devriez l'avoir, si vous avez Excel installé, mais c'est quelque chose que vous devez prendre en compte lors du déploiement de l'application. 

Voici l'exemple de l'appel de la méthode d'assistance à partir de ExportHelper: ExportHelper.CreateXlsFromDataTable(myDataTable, @"C:\tmp\export.xls");

L'assistant pour exporter vers un fichier Excel à l'aide d'ACE OLEDB:

public class ExportHelper
{
    private const string ExcelOleDbConnectionStringTemplate = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=YES\";";

    /// <summary>
    /// Creates the Excel file from items in DataTable and writes them to specified output file.
    /// </summary>
    public static void CreateXlsFromDataTable(DataTable dataTable, string fullFilePath)
    {
        string createTableWithHeaderScript = GenerateCreateTableCommand(dataTable);

        using (var conn = new OleDbConnection(String.Format(ExcelOleDbConnectionStringTemplate, fullFilePath)))
        {
            if (conn.State != ConnectionState.Open)
            {
                conn.Open();
            }

            OleDbCommand cmd = new OleDbCommand(createTableWithHeaderScript, conn);
            cmd.ExecuteNonQuery();

            foreach (DataRow dataExportRow in dataTable.Rows)
            {
                AddNewRow(conn, dataExportRow);
            }
        }
    }

    private static void AddNewRow(OleDbConnection conn, DataRow dataRow)
    {
        string insertCmd = GenerateInsertRowCommand(dataRow);

        using (OleDbCommand cmd = new OleDbCommand(insertCmd, conn))
        {
            AddParametersWithValue(cmd, dataRow);
            cmd.ExecuteNonQuery();
        }
    }

    /// <summary>
    /// Generates the insert row command.
    /// </summary>
    private static string GenerateInsertRowCommand(DataRow dataRow)
    {
        var stringBuilder = new StringBuilder();
        var columns = dataRow.Table.Columns.Cast<DataColumn>().ToList();
        var columnNamesCommaSeparated = string.Join(",", columns.Select(x => x.Caption));
        var questionmarkCommaSeparated = string.Join(",", columns.Select(x => "?"));

        stringBuilder.AppendFormat("INSERT INTO [{0}] (", dataRow.Table.TableName);
        stringBuilder.Append(columnNamesCommaSeparated);
        stringBuilder.Append(") VALUES(");
        stringBuilder.Append(questionmarkCommaSeparated);
        stringBuilder.Append(")");
        return stringBuilder.ToString();
    }

    /// <summary>
    /// Adds the parameters with value.
    /// </summary>
    private static void AddParametersWithValue(OleDbCommand cmd, DataRow dataRow)
    {
        var paramNumber = 1;

        for (int i = 0; i <= dataRow.Table.Columns.Count - 1; i++)
        {
            if (!ReferenceEquals(dataRow.Table.Columns[i].DataType, typeof(int)) && !ReferenceEquals(dataRow.Table.Columns[i].DataType, typeof(decimal)))
            {
                cmd.Parameters.AddWithValue("@p" + paramNumber, dataRow[i].ToString().Replace("'", "''"));
            }
            else
            {
                object value = GetParameterValue(dataRow[i]);
                OleDbParameter parameter = cmd.Parameters.AddWithValue("@p" + paramNumber, value);
                if (value is decimal)
                {
                    parameter.OleDbType = OleDbType.Currency;
                }
            }

            paramNumber = paramNumber + 1;
        }
    }

    /// <summary>
    /// Gets the formatted value for the OleDbParameter.
    /// </summary>
    private static object GetParameterValue(object value)
    {
        if (value is string)
        {
            return value.ToString().Replace("'", "''");
        }
        return value;
    }

    private static string GenerateCreateTableCommand(DataTable tableDefination)
    {
        StringBuilder stringBuilder = new StringBuilder();
        bool firstcol = true;

        stringBuilder.AppendFormat("CREATE TABLE [{0}] (", tableDefination.TableName);

        foreach (DataColumn tableColumn in tableDefination.Columns)
        {
            if (!firstcol)
            {
                stringBuilder.Append(", ");
            }
            firstcol = false;

            string columnDataType = "CHAR(255)";

            switch (tableColumn.DataType.Name)
            {
                case "String":
                    columnDataType = "CHAR(255)";
                    break;
                case "Int32":
                    columnDataType = "INTEGER";
                    break;
                case "Decimal":
                    // Use currency instead of decimal because of bug described at 
                    // http://social.msdn.Microsoft.com/Forums/vstudio/en-US/5d6248a5-ef00-4f46-be9d-853207656bcc/localization-trouble-with-oledbparameter-and-decimal?forum=csharpgeneral
                    columnDataType = "CURRENCY";
                    break;
            }

            stringBuilder.AppendFormat("{0} {1}", tableColumn.ColumnName, columnDataType);
        }
        stringBuilder.Append(")");

        return stringBuilder.ToString();
    }
}
0
the berserker

En ce qui concerne la réponse de tuncalik , ce qui est excellent, surtout si vous voulez jouer un peu avec le code :) mais cela met mes dates au format Excel au format américain, c'est-à-dire le 2 mars 2014 au Royaume-Uni 02/03/2014 mais aux Etats-Unis le 03/02/2014 avec le 1er mois, puis le jour de la semaine après. J'ai besoin de l'avoir au format britannique, des idées s'il vous plaît?

J'ai vérifié qu'il est stocké au format UK dans mon DataTable et que mon Excel est défini sur UK mais pour une raison quelconque, lorsque le document Excel est créé, il pense qu'il est aux États-Unis (est-ce parce que Microsoft est une société américaine :)

Je vais essayer d'expérimenter avec des codes de culture, mais je ne sais pas encore où le mettre. Essayé mais cela n'a eu aucun effet.

p.s.

J'ai dû changer une ligne pour que cela fonctionne en ajoutant un "casting" comme ci-dessous

// single worksheet
Excel._Worksheet workSheet = (Excel._Worksheet)excelApp.ActiveSheet;

Mise à jour: J'ai réussi à formater les dates au Royaume-Uni en les convertissant au format LongDateTime, mais ce n'est qu'un moyen de contourner le problème.

DateTime startDate = Convert.ToDateTime(myList[0].ToString());
string strStartDate = startDate.ToLongDateString();
DateTime endDate = Convert.ToDateTime(myList[myListTotalRows].ToString());
string strEndDate = endDate.ToLongDateString();    

à votre santé.

0
FlashTrev