C#读取Excel 几种方法的体会

(1) OleDb: 用这种方法读取Excel速度还是非常的快的,但这种方式读取数据的时候不太灵活,不过可以在 DataTable 中对数据进行一些删减修改

这种方式将Excel作为一个数据源,直接用Sql语句获取数据了。所以读取之前要知道此次要读取的Sheet(当然也可以用序号,类似dt.Row[0][0]。这样倒是不需要知道Sheet)

if (fileType == ".xls")

   connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + fileName + ";" + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1\"";

else

   connStr = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + fileName + ";" + ";Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";

OleDbConnection conn new OleDbConnection(connStr);

DataTable dtSheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });

以上是读取Excel的Sheet名,xls和xlsx的连接字符串也不一样的,可以根据文件的后缀来区别。这里需要注意的一点,Excel里面只有一个Sheet,但通过这种方式读取Sheet可能会大于一个。原因已经有人在别的网站说过了,偷一下懒O(∩_∩)O,下面文段来自【cdwolfling

【在使用过程中发现取出的Sheet和实际excel不一致, 会多出不少。目前总结后有两种情况:

1. 取出的名称中,包括了XL命名管理器中的名称(参见XL2007的公式--命名管理器, 快捷键Crtl+F3);

2. 取出的名称中,包括了FilterDatabase后缀的, 这是XL用来记录Filter范围的, 参见http://www.mrexcel.com/forum/showthread.php?t=27225

对于第一点比较简单, 删除已有命名管理器中的内容即可;第二点处理起来比较麻烦, Filter删除后这些名称依然保留着,简单的做法是新增sheet然后将原sheet Copy进去】

---------------------------------

但实际情况并不能为每个Excel做以上检查,【cdwolfling】也给出了过滤的方案,当时还是有点问题,本来补充了一点。总之先看代码吧

for (int i = 0; i < dtSheetName.Rows.Count; i++)

{

SheetName = (string)dtSheetName.Rows[i]["TABLE_NAME"];

if (SheetName .Contains("$") && !SheetName .Replace("‘", "").EndsWith("$"))continue;//过滤无效SheetName完毕....

da.SelectCommand = new OleDbCommand(String.Format(sql_F, tblName), conn);
DataSet dsItem = new DataSet();
da.Fill(dsItem, tblName);

}

因为读取出来无效SheetName一般情况最后一个字符都不会是$。如果SheetName有一些特殊符号,读取出来的SheetName会自动加上单引号,比如在Excel中将SheetName编辑成:MySheet(1),此时读取出来的SheetName就为:‘MySheet(1)$‘,所以判断最后一个字符是不是$之前最好过滤一下单引号。

优点:读取方式简单、读取速度快

缺点:除了读取过程不太灵活之外,这种读取方式还有个弊端就是,当Excel数据量很大时。会非常占用内存,当内存不够时会抛出内存溢出的异常。

不过一般情况下还是非常不错的

读取Excel完整代码:

/// <summary>

        /// 读取Excel文件到DataSet中

        /// </summary>

        /// <param name="filePath">文件路径</param>

        /// <returns></returns>

        public static DataSet ToDataTable(string filePath)

        {

            string connStr = "";           

            string fileType = System.IO.Path.GetExtension(fileName);

            if (string.IsNullOrEmpty(fileType)) return null;

            if (fileType == ".xls")

                connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + filePath+ ";" + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1\"";

            else

                connStr = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + filePath+ ";" + ";Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";

            string sql_F = "Select * FROM [{0}]";

            OleDbConnection conn = null;

            OleDbDataAdapter da = null;

            DataTable dtSheetName= null;

            DataSet ds = new DataSet();

            try

            {

                // 初始化连接,并打开

                conn = new OleDbConnection(connStr);

                conn.Open();

                // 获取数据源的表定义元数据                       

                string SheetName = "";

                dtSheetName= conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });

                // 初始化适配器

                da = new OleDbDataAdapter();

                for (int i = 0; i < dtSheetName.Rows.Count; i++)

                {

                    SheetName = (string)dtSheetName.Rows[i]["TABLE_NAME"];

                    if (SheetName .Contains("$") && !SheetName .Replace("‘", "").EndsWith("$"))

                    {

                        continue;

                    }

                    da.SelectCommand = new OleDbCommand(String.Format(sql_F, SheetName ), conn);

                    DataSet dsItem = new DataSet();

                    da.Fill(dsItem, tblName);

                    ds.Tables.Add(dsItem.Tables[0].Copy());

                }

            }

            catch (Exception ex)

            {

            }

            finally

            {

                // 关闭连接

                if (conn.State == ConnectionState.Open)

                {

                    conn.Close();

                    da.Dispose();

                    conn.Dispose();

                }

            }

            return ds;

        }

  

(2):Com组件的方式读取Excel

这种方式需要先引用 Microsoft.Office.Interop.Excel 。首选说下这种方式的优缺点

优点:可以非常灵活的读取Excel中的数据

缺点:如果是Web站点部署在IIS上时,还需要服务器机子已安装了Excel,有时候还需要为配置IIS权限。最重要的一点因为是基于单元格方式读取的,所以数据很慢(曾做过试验,直接读取千行、200多列的文件,直接读取耗时15分钟。即使采用多线程分段读取来提高CPU的利用率也需要8分钟。PS:CPU I3)

需要读取大文件的的童鞋们慎重。。。

附上单线程和多线程读取类:

public class ExcelOptions

    {

        private Stopwatch wath = new Stopwatch();

        /// <summary>

        /// 使用COM读取Excel

        /// </summary>

        /// <param name="excelFilePath">路径</param>

        /// <returns>DataTabel</returns>

        public System.Data.DataTable GetExcelData(string excelFilePath)

        {

            Excel.Application app = new Excel.Application();

            Excel.Sheets sheets;

            Excel.Workbook workbook = null;

            object oMissiong = System.Reflection.Missing.Value;

            System.Data.DataTable dt = new System.Data.DataTable();

            wath.Start();

            try

            {

                if (app == null)

                {

                    return null;

                }

                workbook = app.Workbooks.Open(excelFilePath, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong);

                //将数据读入到DataTable中——Start  

                sheets = workbook.Worksheets;

                Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1);//读取第一张表

                if (worksheet == null)

                    return null;

                string cellContent;

                int iRowCount = worksheet.UsedRange.Rows.Count;

                int iColCount = worksheet.UsedRange.Columns.Count;

                Excel.Range range;

                //负责列头Start

                DataColumn dc;

                int ColumnID = 1;

                range = (Excel.Range)worksheet.Cells[1, 1];

                while (range.Text.ToString().Trim() != "")

                {

                    dc = new DataColumn();

                    dc.DataType = System.Type.GetType("System.String");

                    dc.ColumnName = range.Text.ToString().Trim();

                    dt.Columns.Add(dc);

                    range = (Excel.Range)worksheet.Cells[1, ++ColumnID];

                }

                //End

                for (int iRow = 2; iRow <= iRowCount; iRow++)

                {

                    DataRow dr = dt.NewRow();

                    for (int iCol = 1; iCol <= iColCount; iCol++)

                    {

                        range = (Excel.Range)worksheet.Cells[iRow, iCol];

                        cellContent = (range.Value2 == null) ? "" : range.Text.ToString();

                        //if (iRow == 1)

                        //{

                        //    dt.Columns.Add(cellContent);

                        //}

                        //else

                        //{

                            dr[iCol - 1] = cellContent;

                        //}

                    }

                    //if (iRow != 1)

                    dt.Rows.Add(dr);

                }

                wath.Stop();

                TimeSpan ts = wath.Elapsed;

                //将数据读入到DataTable中——End

                return dt;

            }

            catch

            {

                

                return null;

            }

            finally

            {

                workbook.Close(false, oMissiong, oMissiong);

                System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);

                workbook = null;

                app.Workbooks.Close();

                app.Quit();

                System.Runtime.InteropServices.Marshal.ReleaseComObject(app);

                app = null;

                GC.Collect();

                GC.WaitForPendingFinalizers();

            }

        }

        /// <summary>

        /// 使用COM,多线程读取Excel(1 主线程、4 副线程)

        /// </summary>

        /// <param name="excelFilePath">路径</param>

        /// <returns>DataTabel</returns>

        public System.Data.DataTable ThreadReadExcel(string excelFilePath)

        {

            Excel.Application app = new Excel.Application();

            Excel.Sheets sheets = null;

            Excel.Workbook workbook = null;

            object oMissiong = System.Reflection.Missing.Value;

            System.Data.DataTable dt = new System.Data.DataTable();

            wath.Start();

            try

            {

                if (app == null)

                {

                    return null;

                }

                workbook = app.Workbooks.Open(excelFilePath, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong);

                //将数据读入到DataTable中——Start  

                sheets = workbook.Worksheets;

                Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1);//读取第一张表

                if (worksheet == null)

                    return null;

                string cellContent;

                int iRowCount = worksheet.UsedRange.Rows.Count;

                int iColCount = worksheet.UsedRange.Columns.Count;

                Excel.Range range;

                //负责列头Start

                DataColumn dc;

                int ColumnID = 1;

                range = (Excel.Range)worksheet.Cells[1, 1];

                //while (range.Text.ToString().Trim() != "")

                while (iColCount >= ColumnID)

                {

                    dc = new DataColumn();

                    dc.DataType = System.Type.GetType("System.String");

                    string strNewColumnName = range.Text.ToString().Trim();

                    if (strNewColumnName.Length == 0) strNewColumnName = "_1";

                    //判断列名是否重复

                    for (int i = 1; i < ColumnID; i++)

                    {

                        if (dt.Columns[i - 1].ColumnName == strNewColumnName)

                            strNewColumnName = strNewColumnName + "_1";

                    }

                    dc.ColumnName = strNewColumnName;

                    dt.Columns.Add(dc);

                    range = (Excel.Range)worksheet.Cells[1, ++ColumnID];

                }

                //End

                //数据大于500条,使用多进程进行读取数据

                if (iRowCount - 1 > 500)

                {

                    //开始多线程读取数据

                    //新建线程

                    int b2 = (iRowCount - 1) / 10;

                    DataTable dt1 = new DataTable("dt1");

                    dt1 = dt.Clone();

                    SheetOptions sheet1thread = new SheetOptions(worksheet, iColCount, 2, b2 + 1, dt1);

                    Thread othread1 = new Thread(new ThreadStart(sheet1thread.SheetToDataTable));

                    othread1.Start();

                    //阻塞 1 毫秒,保证第一个读取 dt1

                    Thread.Sleep(1);

                    DataTable dt2 = new DataTable("dt2");

                    dt2 = dt.Clone();

                    SheetOptions sheet2thread = new SheetOptions(worksheet, iColCount, b2 + 2, b2 * 2 + 1, dt2);

                    Thread othread2 = new Thread(new ThreadStart(sheet2thread.SheetToDataTable));

                    othread2.Start();

                    DataTable dt3 = new DataTable("dt3");

                    dt3 = dt.Clone();

                    SheetOptions sheet3thread = new SheetOptions(worksheet, iColCount, b2 * 2 + 2, b2 * 3 + 1, dt3);

                    Thread othread3 = new Thread(new ThreadStart(sheet3thread.SheetToDataTable));

                    othread3.Start();

                    DataTable dt4 = new DataTable("dt4");

                    dt4 = dt.Clone();

                    SheetOptions sheet4thread = new SheetOptions(worksheet, iColCount, b2 * 3 + 2, b2 * 4 + 1, dt4);

                    Thread othread4 = new Thread(new ThreadStart(sheet4thread.SheetToDataTable));

                    othread4.Start();

                    //主线程读取剩余数据

                    for (int iRow = b2 * 4 + 2; iRow <= iRowCount; iRow++)

                    {

                        DataRow dr = dt.NewRow();

                        for (int iCol = 1; iCol <= iColCount; iCol++)

                        {

                            range = (Excel.Range)worksheet.Cells[iRow, iCol];

                            cellContent = (range.Value2 == null) ? "" : range.Text.ToString();

                            dr[iCol - 1] = cellContent;

                        }

                        dt.Rows.Add(dr);

                    }

                    othread1.Join();

                    othread2.Join();

                    othread3.Join();

                    othread4.Join();

                    //将多个线程读取出来的数据追加至 dt1 后面

                    foreach (DataRow dr in dt.Rows)

                        dt1.Rows.Add(dr.ItemArray);

                    dt.Clear();

                    dt.Dispose();

                    foreach (DataRow dr in dt2.Rows)

                        dt1.Rows.Add(dr.ItemArray);

                    dt2.Clear();

                    dt2.Dispose();

                    foreach (DataRow dr in dt3.Rows)

                        dt1.Rows.Add(dr.ItemArray);

                    dt3.Clear();

                    dt3.Dispose();

                    foreach (DataRow dr in dt4.Rows)

                        dt1.Rows.Add(dr.ItemArray);

                    dt4.Clear();

                    dt4.Dispose();

                    return dt1;

                }

                else

                {

                    for (int iRow = 2; iRow <= iRowCount; iRow++)

                    {

                        DataRow dr = dt.NewRow();

                        for (int iCol = 1; iCol <= iColCount; iCol++)

                        {

                            range = (Excel.Range)worksheet.Cells[iRow, iCol];

                            cellContent = (range.Value2 == null) ? "" : range.Text.ToString();

                            dr[iCol - 1] = cellContent;

                        }

                        dt.Rows.Add(dr);

                    }

                }

                wath.Stop();

                TimeSpan ts = wath.Elapsed;

                //将数据读入到DataTable中——End

                return dt;

            }

            catch

            {

                return null;

            }

            finally

            {

                workbook.Close(false, oMissiong, oMissiong);

                System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);

                System.Runtime.InteropServices.Marshal.ReleaseComObject(sheets);

                workbook = null;

                app.Workbooks.Close();

                app.Quit();

                System.Runtime.InteropServices.Marshal.ReleaseComObject(app);

                app = null;

                GC.Collect();

                GC.WaitForPendingFinalizers();

                

                /*

                object objmissing = System.Reflection.Missing.Value;

Excel.ApplicationClass application = new ApplicationClass();

Excel.Workbook book = application.Workbooks.Add(objmissing);

Excel.Worksheet sheet = (Excel.Worksheet)book.Worksheets.Add(objmissing,objmissing,objmissing,objmissing);

//操作过程 ^&%&×&……&%&&……

//释放

sheet.SaveAs(path,objmissing,objmissing,objmissing,objmissing,objmissing,objmissing,objmissing,objmissing);

System.Runtime.InteropServices.Marshal.ReleaseComObject((object)sheet);

System.Runtime.InteropServices.Marshal.ReleaseComObject((object)book);

application.Quit();

System.Runtime.InteropServices.Marshal.ReleaseComObject((object)application);

System.GC.Collect();

                 */

            }

        }

        /// <summary>

        /// 删除Excel行

        /// </summary>

        /// <param name="excelFilePath">Excel路径</param>

        /// <param name="rowStart">开始行</param>

        /// <param name="rowEnd">结束行</param>

        /// <param name="designationRow">指定行</param>

        /// <returns></returns>

        public string DeleteRows(string excelFilePath, int rowStart, int rowEnd, int designationRow)

        {

            string result = "";

            Excel.Application app = new Excel.Application();

            Excel.Sheets sheets;

            Excel.Workbook workbook = null;

            object oMissiong = System.Reflection.Missing.Value;

            try

            {

                if (app == null)

                {

                    return "分段读取Excel失败";

                }

                workbook = app.Workbooks.Open(excelFilePath, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong);

                sheets = workbook.Worksheets;

                Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1);//读取第一张表

                if (worksheet == null)

                    return result;

                Excel.Range range;

                //先删除指定行,一般为列描述

                if (designationRow != -1)

                {

                    range = (Excel.Range)worksheet.Rows[designationRow, oMissiong];

                    range.Delete(Excel.XlDeleteShiftDirection.xlShiftUp);

                }

                Stopwatch sw = new Stopwatch();

                sw.Start();

                int i = rowStart;

                for (int iRow = rowStart; iRow <= rowEnd; iRow++, i++)

                {

                    range = (Excel.Range)worksheet.Rows[rowStart, oMissiong];

                    range.Delete(Excel.XlDeleteShiftDirection.xlShiftUp);

                }

                sw.Stop();

                TimeSpan ts = sw.Elapsed;

                workbook.Save();

                //将数据读入到DataTable中——End

                return result;

            }

            catch

            {

                return "分段读取Excel失败";

            }

            finally

            {

                workbook.Close(false, oMissiong, oMissiong);

                System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);

                workbook = null;

                app.Workbooks.Close();

                app.Quit();

                System.Runtime.InteropServices.Marshal.ReleaseComObject(app);

                app = null;

                GC.Collect();

                GC.WaitForPendingFinalizers();

            }

        }

        public void ToExcelSheet(DataSet ds, string fileName)

        {

            Excel.Application appExcel = new Excel.Application();

            Excel.Workbook workbookData = null;

            Excel.Worksheet worksheetData;

            Excel.Range range;

            try

            {

                workbookData = appExcel.Workbooks.Add(System.Reflection.Missing.Value);

                appExcel.DisplayAlerts = false;//不显示警告

                //xlApp.Visible = true;//excel是否可见

                //

                //for (int i = workbookData.Worksheets.Count; i > 0; i--)

                //{

                //    Microsoft.Office.Interop.Excel.Worksheet oWorksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbookData.Worksheets.get_Item(i);

                //    oWorksheet.Select();

                //    oWorksheet.Delete();

                //}

                for (int k = 0; k < ds.Tables.Count; k++)

                {

                    worksheetData = (Excel.Worksheet)workbookData.Worksheets.Add(System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value);

                    // testnum--;

                    if (ds.Tables[k] != null)

                    {

                        worksheetData.Name = ds.Tables[k].TableName;

                        //写入标题

                        for (int i = 0; i < ds.Tables[k].Columns.Count; i++)

                        {

                            worksheetData.Cells[1, i + 1] = ds.Tables[k].Columns[i].ColumnName;

                            range = (Excel.Range)worksheetData.Cells[1, i + 1];

                            //range.Interior.ColorIndex = 15;

                            range.Font.Bold = true;

                            range.NumberFormatLocal = "@";//文本格式

                            range.EntireColumn.AutoFit();//自动调整列宽

                            // range.WrapText = true; //文本自动换行  

                            range.ColumnWidth = 15;

                        }

                        //写入数值

                        for (int r = 0; r < ds.Tables[k].Rows.Count; r++)

                        {

                            for (int i = 0; i < ds.Tables[k].Columns.Count; i++)

                            {

                                worksheetData.Cells[r + 2, i + 1] = ds.Tables[k].Rows[r][i];

                                //Range myrange = worksheetData.get_Range(worksheetData.Cells[r + 2, i + 1], worksheetData.Cells[r + 3, i + 2]);

                                //myrange.NumberFormatLocal = "@";//文本格式

                                //// myrange.EntireColumn.AutoFit();//自动调整列宽

                                ////   myrange.WrapText = true; //文本自动换行  

                                //myrange.ColumnWidth = 15;

                            }

                            //  rowRead++;

                            //System.Windows.Forms.Application.DoEvents();

                        }

                    }

                    worksheetData.Columns.EntireColumn.AutoFit();

                    workbookData.Saved = true;

                }

            }

            catch (Exception ex) { }

            finally

            {

                workbookData.SaveCopyAs(fileName);

                workbookData.Close(false, System.Reflection.Missing.Value, System.Reflection.Missing.Value);

                appExcel.Quit();

                GC.Collect();

            }

        }

    

    }

  

(3)NPOI方式读取Excel,NPOI是一组开源的组件,类似Java的 POI。包括:NPOI、NPOI.HPSF、NPOI.HSSF、NPOI.HSSF.UserModel、NPOI.POIFS、NPOI.Util,下载的时候别只下一个噢

优点:读取Excel速度较快,读取方式操作灵活性

缺点:只支持03的Excel,xlsx的无法读取。由于这点,使用这种方式的人不多啊,没理由要求客户使用03版Excel吧,再说03版Excel对于行数还有限制,只支持65536行。

(听他们的开发人员说会在2012年底推出新版,支持xlsx的读取。但一直很忙没时间去关注这个事情,有兴趣的同学可以瞧瞧去)

NPOI读取Excel类:

using System;

using System.Data;

using System.IO;

using System.Web;

using NPOI;

using NPOI.HPSF;

using NPOI.HSSF;

using NPOI.HSSF.UserModel;

using NPOI.POIFS;

using NPOI.Util;

using System.Text;

using System.Configuration;

public class NPOIHelper

{

    private static int ExcelMaxRow = Convert.ToInt32(ConfigurationManager.AppSettings["ExcelMaxRow"]);

    /// <summary>

    /// 由DataSet导出Excel

    /// </summary>

    /// <param name="sourceTable">要导出数据的DataTable</param>   

    /// <param name="sheetName">工作表名称</param>

    /// <returns>Excel工作表</returns>   

    private static Stream ExportDataSetToExcel(DataSet sourceDs)

    {

        HSSFWorkbook workbook = new HSSFWorkbook();

        MemoryStream ms = new MemoryStream();

        for (int i = 0; i < sourceDs.Tables.Count; i++)

        {

            HSSFSheet sheet = (HSSFSheet)workbook.CreateSheet(sourceDs.Tables[i].TableName);

            HSSFRow headerRow = (HSSFRow)sheet.CreateRow(0);

            // handling header.           

            foreach (DataColumn column in sourceDs.Tables[i].Columns)

                headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);

            // handling value.           

            int rowIndex = 1;

            foreach (DataRow row in sourceDs.Tables[i].Rows)

            {

                HSSFRow dataRow = (HSSFRow)sheet.CreateRow(rowIndex);

                foreach (DataColumn column in sourceDs.Tables[i].Columns)

                {

                    dataRow.CreateCell(column.Ordinal).SetCellValue(row[column].ToString());

                }

                rowIndex++;

            }

        }

        workbook.Write(ms);

        ms.Flush();

        ms.Position = 0;

        workbook = null;

        return ms;

    }

    /// <summary>

    /// 由DataSet导出Excel

    /// </summary>  

    /// <param name="sourceTable">要导出数据的DataTable</param>

    /// <param name="fileName">指定Excel工作表名称</param>

    /// <returns>Excel工作表</returns>   

    public static void ExportDataSetToExcel(DataSet sourceDs, string fileName)

    {

        //检查是否有Table数量超过65325

        for (int t = 0; t < sourceDs.Tables.Count; t++)

        {

            if (sourceDs.Tables[t].Rows.Count > ExcelMaxRow)

            {

                DataSet ds = GetdtGroup(sourceDs.Tables[t].Copy());

                sourceDs.Tables.RemoveAt(t);

                //将得到的ds插入 sourceDs中

                for (int g = 0; g < ds.Tables.Count; g++)

                {

                    DataTable dt = ds.Tables[g].Copy();

                    sourceDs.Tables.Add(dt);

                }

                t--;

            }

        }

        MemoryStream ms = ExportDataSetToExcel(sourceDs) as MemoryStream;

        HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + fileName);

        HttpContext.Current.Response.BinaryWrite(ms.ToArray());

        HttpContext.Current.ApplicationInstance.CompleteRequest();

        //HttpContext.Current.Response.End();

        ms.Close();

        ms = null;

    }

    /// <summary>

    /// 由DataTable导出Excel

    /// </summary>

    /// <param name="sourceTable">要导出数据的DataTable</param>

    /// <returns>Excel工作表</returns>   

    private static Stream ExportDataTableToExcel(DataTable sourceTable)

    {

        HSSFWorkbook workbook = new HSSFWorkbook();

        MemoryStream ms = new MemoryStream();

        HSSFSheet sheet = (HSSFSheet)workbook.CreateSheet(sourceTable.TableName);

        HSSFRow headerRow = (HSSFRow)sheet.CreateRow(0);

        // handling header.     

        foreach (DataColumn column in sourceTable.Columns)

            headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);

        // handling value.     

        int rowIndex = 1;

        foreach (DataRow row in sourceTable.Rows)

        {

            HSSFRow dataRow = (HSSFRow)sheet.CreateRow(rowIndex);

            foreach (DataColumn column in sourceTable.Columns)

            {

                dataRow.CreateCell(column.Ordinal).SetCellValue(row[column].ToString());

            }

            rowIndex++;

        }

        workbook.Write(ms);

        ms.Flush();

        ms.Position = 0;

        sheet = null;

        headerRow = null;

        workbook = null;

        return ms;

    }

    /// <summary>

    /// 由DataTable导出Excel

    /// </summary>

    /// <param name="sourceTable">要导出数据的DataTable</param>

    /// <param name="fileName">指定Excel工作表名称</param>

    /// <returns>Excel工作表</returns>

    public static void ExportDataTableToExcel(DataTable sourceTable, string fileName)

    {

        //如数据超过65325则分成多个Table导出

        if (sourceTable.Rows.Count > ExcelMaxRow)

        {

            DataSet ds = GetdtGroup(sourceTable);

            //导出DataSet

            ExportDataSetToExcel(ds, fileName);

        }

        else

        {

            MemoryStream ms = ExportDataTableToExcel(sourceTable) as MemoryStream;

            HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + fileName);

            HttpContext.Current.Response.BinaryWrite(ms.ToArray());

            HttpContext.Current.ApplicationInstance.CompleteRequest();

            //HttpContext.Current.Response.End();

            ms.Close();

            ms = null;

        }

    }

    /// <summary>

    /// 传入行数超过65325的Table,返回DataSet

    /// </summary>

    /// <param name="dt"></param>

    /// <returns></returns>

    public static DataSet GetdtGroup(DataTable dt)

    {

        string tablename = dt.TableName;

        DataSet ds = new DataSet();

        ds.Tables.Add(dt);

        double n = dt.Rows.Count / Convert.ToDouble(ExcelMaxRow);

        //创建表

        for (int i = 1; i < n; i++)

        {

            DataTable dtAdd = dt.Clone();

            dtAdd.TableName = tablename + "_" + i.ToString();

            ds.Tables.Add(dtAdd);

        }

        //分解数据

        for (int i = 1; i < ds.Tables.Count; i++)

        {

            //新表行数达到最大 或 基表数量不足

            while (ds.Tables[i].Rows.Count != ExcelMaxRow && ds.Tables[0].Rows.Count != ExcelMaxRow)

            {

                ds.Tables[i].Rows.Add(ds.Tables[0].Rows[ExcelMaxRow].ItemArray);

                ds.Tables[0].Rows.RemoveAt(ExcelMaxRow);

            }

        }

        return ds;

    }

    /// <summary>

    /// 由DataTable导出Excel

    /// </summary>

    /// <param name="sourceTable">要导出数据的DataTable</param>

    /// <param name="fileName">指定Excel工作表名称</param>

    /// <returns>Excel工作表</returns>

    public static void ExportDataTableToExcelModel(DataTable sourceTable, string modelpath, string modelName, string fileName, string sheetName)

    {

        int rowIndex = 2;//从第二行开始,因为前两行是模板里面的内容

        int colIndex = 0;

        FileStream file = new FileStream(modelpath + modelName + ".xls", FileMode.Open, FileAccess.Read);//读入excel模板

        HSSFWorkbook hssfworkbook = new HSSFWorkbook(file);

        HSSFSheet sheet1 = (HSSFSheet)hssfworkbook.GetSheet("Sheet1");

        sheet1.GetRow(0).GetCell(0).SetCellValue("excelTitle");      //设置表头

        foreach (DataRow row in sourceTable.Rows)

        {   //双循环写入sourceTable中的数据

            rowIndex++;

            colIndex = 0;

            HSSFRow xlsrow = (HSSFRow)sheet1.CreateRow(rowIndex);

            foreach (DataColumn col in sourceTable.Columns)

            {

                xlsrow.CreateCell(colIndex).SetCellValue(row[col.ColumnName].ToString());

                colIndex++;

            }

        }

        sheet1.ForceFormulaRecalculation = true;

        FileStream fileS = new FileStream(modelpath + fileName + ".xls", FileMode.Create);//保存

        hssfworkbook.Write(fileS);

        fileS.Close();

        file.Close();

    }

}

时间: 2024-08-28 00:46:50

C#读取Excel 几种方法的体会的相关文章

C#读取Excel五种方式的体会

原地址: http://blog.csdn.net/dapengbusi/article/details/38117817 http://blog.csdn.net/dapengbusi/article/details/38118679 http://blog.csdn.net/dapengbusi/article/details/38118997 C#读取Excel五种方式的体会,布布扣,bubuko.com

delphi 读取excel 两种方法

http://www.cnblogs.com/ywangzi/archive/2012/09/27/2705894.html 两种方法,一是用ADO连接,问题是Excel文件内容要规则,二是用OLE打开,但操作就没有象 操作数据库那么方便了. 一.用ADO连接: 设置属性ConnetionString 选择 Microsoft Jet 4.0 OLE DB provider Select or enter a datasorce name -> 选择你要打开Excel文件 User name默认

Java逐行读取文件有多少种方法?

如果每个线程使用的变量都是其它线程不会读取或修改的,那么就不存在一致性问题.同样,如果变量是只读的,多个线程同时读取该变量也不会有一致性问题.否则,将会出现不一致性问题.为了解决数据不一致问题,必须引入某些机制使线程间同步. 当变量修改时间多于一个存储器访问周期,同时读.写操作又相互交替时,潜在的不一致性就会出现.如下图所示: 此时,线程B读取到的数据是错误的.使用一把锁能够解决上述问题: 下面介绍线程的三种同步机制: 1.互斥量pthread_mutex_t 互斥量就是锁,对某段临界区进行加锁

C#中datatable导出excel(三种方法)

方法一:(拷贝直接可以使用,适合大批量资料, 上万笔)Microsoft.Office.Interop.Excel.Application appexcel = new Microsoft.Office.Interop.Excel.Application();SaveFileDialog savefiledialog = new SaveFileDialog();System.Reflection.Missing miss = System.Reflection.Missing.Value;ap

R中读取EXCEL 数据的方法

最近初学R语言,在R语言读入EXCEL数据格式文件的问题上遇到了困难,经过在网上搜索解决了这一问题,下面归纳几种方法,供大家分享: 第一:R中读取excel文件中的数据的路径: 假定在您的电脑有一个excel文件,原始的文件路径是:D:\work\data\1 如果直接把这个路径拷贝到R中,就会出现错误,原因是: \是escape character(转义符),\\才是真正的\字符,或者用/ 因此,在R中有两种方法读取该路径: 1:在R中输入一下路径:D:\\work\\data\\1     

NPOI操作Excel 002:读取Excel

本文讲述如何通过NPOI来读取Excel.需要准备的dll见:http://blog.csdn.net/yysyangyangyangshan/article/details/42614181环境.net2.0,Excel版本2003.NPOI读取Excel比较简单,只要抓住Excel的几个主要点即可.一般Excel通过这几部分构成的,book,sheet页,然后是sheet页里的行列.读取Excel则是先找到book,然后book内的sheet,之后就根据sheet里的第几行第几列进行读取内容

C# 创建、读取Excel公式

对于数据量较大的表格,需要计算一些特殊数值时,我们通过运用公式能有效提高我们数据处理的速度和效率,对于后期数据的增删改查等的批量操作也很方便.此外,对于某些数值的信息来源,我们也可以通过读取数据中包含的公式来获取.下面的示例中将分享通过C# 来创建.读取Excel公式的方法. 工具使用 Spire.XLS for .NET 8.0下载安装该类库后,注意在程序中添加引用Spire.Xls.dll(dll文件可在安装路径下的Bin文件夹中获取)代码示例(供参考) [示例1]创建Excel公式 C#

读取Excel文件的两种方法

第一种方法:传统方法,采用OleDB读取EXCEL文件, 优点:写法简单,缺点:服务器必须安有此组件才能用,不推荐使用 private DataSet GetConnect_DataSet2(string fileName) { DataSet myDataSet = new DataSet(); //创建一个数据链接 string strCon = " Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = " + fileName +

C# 读取EXCEL文件的三种经典方法

1.方法一:采用OleDB读取EXCEL文件: 把EXCEL文件当做一个数据源来进行数据的读取操作,实例如下: public DataSet ExcelToDS(string Path) { string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" +"Data Source="+ Path +";"+"Extended Properties=Excel 8.0;"; OleDb