首页 文章

如何将DataTable导出到Excel

提问于
浏览
84

如何在C#中将 DataTable 导出到Excel?我正在使用Windows窗体 . DataTableDataGridView 控件相关联 . 我必须将 DataTable 的记录导出到Excel .

17 回答

  • 0

    我会推荐ClosedXML -

    您可以使用一些非常易读的代码将DataTable转换为Excel工作表:

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

    开发人员响应迅速,乐于助人 . 该项目正在积极开发,文档非常精湛 .

  • 0

    尝试简单的代码,将DataTable转换为excel文件为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);
    

    这会将一个新文件 excel.csv 写入"current working directory",这通常是.exe所在的位置或启动它的位置 .

    请注意,输出会在dataTable中已包含的数据之间放置逗号( "," ) . 因为它不会在数据中转义逗号,所以程序读取文件时会报告 commas in the data will be mis-interpreted .

  • 52

    一个优雅的选择是为.net框架的DataTable类编写扩展方法(见下文) .

    这种扩展方法可以如下调用:

    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);
    

    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);
            }
        }
    }
    
  • 13

    解决方案基于tuncalik(感谢您的想法)文章,但在大表的情况下工作得更快(并且不太清楚) .

    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);
            }
        }
    }
    
  • 36

    尝试此函数传递要导出的数据表和文件路径

    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;
        }
    }
    
  • 4

    最好最简单的方法

    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);
            }
        }
    
  • 0

    您可以使用EasyXLS这是一个用于导出Excel文件的库 .

    检查此代码:

    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");
    

    另请参阅此示例有关如何export datatable to excel in C# .

  • 0

    注意:如果您尝试将值从数据表传递到对象然后传递到Excel,您也应该进行数据类型错误处理 . 例如,Guids将使用HRESULT:0x800A03EC异常终止您的赋值 . 没有测试数据类型的一种解决方法是在填充对象时使用“ToString()” . Excel会自动将数字转换回数字格式 . FlashTrev解决了日期/时间的相关问题 .

  • 0

    关于 tuncalik 的回答,这很好,特别是如果你想对代码进行一些游戏:)但它将我的日期以美国格式投入Excel,即2014年3月2日在英国是02/03/2014但是在美国它的03/02/2014与第1个月,然后是一周后的一天 . 我需要用英国格式,有什么想法吗?

    我已经检查过它是以英国格式存储在我的DataTable中,而且我的Excel设置为英国但是出于某种原因,当它生成Excel文档时它认为它是美国(这是因为微软是一家美国公司:)

    我会尝试尝试使用文化代码但不知道在哪里放置文化代码 . 试过但这没有效果 .

    附:

    我确实需要更改一行以通过添加'cast'来使其工作,如下所示

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

    更新:我通过转换为LongDateTime格式实现了英国日期格式,但它只是一个解决方案 .

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

    干杯 .

  • 106

    Excel Interop:

    此方法可防止日期从dd-mm-yyyy翻转到mm-dd-yyyy

    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;
    }
    

    如果您不关心日期被翻转,请使用查看链接,该链接显示如何在一行代码中填充Excel电子表格中的所有单元格:

    Excel Interop - Efficiency and 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;
    }
    
  • 19

    旧线程 - 但我想我会在这里抛出我的代码 . 我写了一个小函数来将数据表写入指定路径(位置)的新Excel工作表 . 此外,您还需要添加对microsoft excel 14.0库的引用 .

    我在撰写任何东西时都从这个帖子中脱颖而出 - How to write some data to excel file(.xlsx)

    我用它来推断如何编写数据表

    *注意在catch语句中我有一个errorhandler静态类引用(你可以忽略那些)

    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

    一种方法是使用ACE OLEDB Provider(另见connection strings for Excel) . 当然,您必须安装和注册提供程序 . 如果安装了Excel,则应该拥有它,但在部署应用程序时必须考虑这一点 .

    这是从 ExportHelper 调用辅助方法的示例: ExportHelper.CreateXlsFromDataTable(myDataTable, @"C:\tmp\export.xls");

    使用ACE OLEDB导出到Excel文件的帮助程序:

    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();
        }
    }
    
  • 1

    使用以下课程

    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);
            }
        }
    }
    

    }

  • 1

    这个解决方案基本上是将List <Object>数据推送到Excel,它使用DataTable来实现这个,我实现了一个扩展方法,所以基本上有两件事需要 . 1.扩展方法 .

    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;
        }       
    }
    

    使用Attribute [ReportHeaderAttribute(“Column Name”)]装饰您的DTO类

    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";
                }
            }}
    

    Excel中需要成为列的所有内容都必须使用 [ReportHeaderAttribute("Column Name")] 进行修饰

    然后简单

    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

    要将数据导出到Excel,可以使用ClosedXML.Report库(https://github.com/ClosedXML/ClosedXML.Report) . 相信我,这是一个很棒的图书馆,很容易让她使用 . 该库不需要Excel Interop . ClosedXML.Report基于您可以使用任何格式在Excel中创建的模板生成Excel文件 . 例如:

    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

    只需使用CloseMXL.Excel库 . 它也很简单快捷 .

    Class

    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;
                        }
                    }
                }
            }
    

    Then another method which get the Dataset

    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;
              }
    

    Now you Button Click Event

    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
    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
    

相关问题