C# 各種導入 Excel 文件的數據的方法總結


在導入之前都需要將上傳的文件保存到服務器,所以避免重復的寫這些代碼,先貼出上傳文件並保存到服務器指定路徑的代碼。

protected void btnImport_Click(object sender, EventArgs e)
        {
            Random random = new Random();
            ImportClass Import = new ImportClass();

            //保存文件的虛擬路徑
            string path = "Import/";

            //獲取選擇的文件名
            string fileName = FileUpload1.FileName;

            //獲取文件擴展名稱
            string fileExt = Path.GetExtension(fileName);

            //生成新文件名
            string newName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + random.Next(0, 9999).ToString();

            //獲取指定虛機路徑的物理路徑
            string fullPath = HttpContext.Current.Server.MapPath(path);

            //上傳文件保存路徑
            string savePath = fullPath + newName + fileExt;

            //保存文件到服務器
            FileUpload1.SaveAs(savePath);

            try
            {
                //獲取導入的數據
                DataSet ds = Import.ImportExcel(savePath);
                if (ds != null && ds.Tables.Count > 0)
                {
                    //這里可以寫插入數據庫的方法
                }
            }
            catch (Exception ex)
            {

                throw;
            }
        }
View Code

 

第一種:OleDB

public DataSet ImportExcel(string filePath)
        {
            DataSet ds = null;
            OleDbConnection conn;

            string strConn = string.Empty;
            string sheetName = string.Empty;

            try
            {
                // Excel 2003 版本連接字符串
                strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filePath + ";Extended Properties='Excel 8.0; HDR=YES; IMEX=1;'";
                conn = new OleDbConnection(strConn);
                conn.Open();
            }
            catch
            {
                // Excel 2007 以上版本連接字符串
                strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties='Excel 12.0;HDR=Yes;IMEX=1;'";
                conn = new OleDbConnection(strConn);
                conn.Open();
            }

            //獲取所有的 sheet 表
            DataTable dtSheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "Table" });

            ds = new DataSet();

            for (int i = 0; i < dtSheetName.Rows.Count; i++)
            {
                DataTable dt = new DataTable();
                dt.TableName = "table" + i.ToString();

                //獲取表名
                sheetName = dtSheetName.Rows[i]["TABLE_NAME"].ToString();

                OleDbDataAdapter oleda = new OleDbDataAdapter("select * from [" + sheetName + "]", conn);

                oleda.Fill(dt);

                ds.Tables.Add(dt);
            }

            //關閉連接,釋放資源
            conn.Close();
            conn.Dispose();

            return ds;
        }
View Code

除了讀取過程不太靈活之外,這種讀取方式還有個弊端就是,當 Excel 數據量很大時。會非常占用內存,當內存不夠時會拋出內存溢出的異常,不過一般都能適用了。

 

第二種:Microsoft.Office.Interop.Excel.dll

public DataSet ImportExcel(string filePath)
        {
            DataSet ds = null;
            DataTable dt = null;

            Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
            Microsoft.Office.Interop.Excel.Workbook workbook = null;
            Microsoft.Office.Interop.Excel.Worksheet worksheet = null;
            Microsoft.Office.Interop.Excel.Sheets sheets = null;
            Microsoft.Office.Interop.Excel.Range range = null;
            object missing = System.Reflection.Missing.Value;

            try
            {
                if (excel == null)
                {
                    return null;
                }

                //打開 Excel 文件
                workbook = excel.Workbooks.Open(filePath, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);

                //獲取所有的 sheet 表
                sheets = workbook.Worksheets;

                ds = new DataSet();

                for (int i = 1; i <= sheets.Count; i++)
                {
                    //獲取第一個表
                    worksheet = (Microsoft.Office.Interop.Excel.Worksheet)sheets.get_Item(i);

                    int rowCount = worksheet.UsedRange.Rows.Count;
                    int colCount = worksheet.UsedRange.Columns.Count;

                    int rowIndex = 1;   //起始行為 1
                    int colIndex = 1;   //起始列為 1

                    DataColumn dc;
                    dt = new DataTable();
                    dt.TableName = "table" + i.ToString();

                    //讀取列名
                    for (int j = 0; j < colCount; j++)
                    {
                        range = worksheet.Cells[rowIndex, colIndex + j];

                        dc = new DataColumn();
                        dc.DataType = Type.GetType("System.String");
                        dc.ColumnName = range.Text.ToString().Trim();

                        //添加列
                        dt.Columns.Add(dc);
                    }

                    //讀取行數據
                    for (int k = 1; k < rowCount; k++)
                    {
                        DataRow dr = dt.NewRow();
                        for (int l = 0; l < colCount; l++)
                        {
                            range = worksheet.Cells[rowIndex + k, colIndex + l];

                            //使用 range.Value.ToString(); 或 range.Value2.ToString(); 或 range.Text.ToString(); 都可以獲取單元格的值
                            dr[l] = range.Text.ToString();
                        }
                        dt.Rows.Add(dr.ItemArray);
                    }

                    ds.Tables.Add(dt);
                }
            }
            catch (Exception ex)
            {
                throw;
            }
            finally
            {
                workbook.Close();

                //關閉退出
                excel.Quit();

                //釋放 COM 對象
                Marshal.ReleaseComObject(worksheet);
                Marshal.ReleaseComObject(workbook);
                Marshal.ReleaseComObject(excel);

                worksheet = null;
                workbook = null;
                excel = null;

                GC.Collect();
            }

            return ds;
        }
View Code

這種方法首先需要安裝有 office Excel,並且是一個單元格一個單元格的讀取,所以性能會比較差。

 

第三種:NPOI

public DataSet ImportExcel(string filePath)
        {
            DataSet ds = null;

            try
            {
                //打開文件
                FileStream fileStream = new FileStream(filePath, FileMode.Open);

                XSSFWorkbook workbook = new XSSFWorkbook(fileStream);

                ISheet sheet = null;
                IRow row = null;

                ds = new DataSet();
                DataTable dt = null;

                for (int i = 0; i < workbook.Count; i++)
                {
                    dt = new DataTable();
                    dt.TableName = "table" + i.ToString();

                    //獲取 sheet 表
                    sheet = workbook.GetSheetAt(i);

                    //起始行索引
                    int rowIndex = sheet.FirstRowNum;

                    //獲取行數
                    int rowCount = sheet.LastRowNum;

                    //獲取第一行
                    IRow firstRow = sheet.GetRow(rowIndex);

                    //起始列索引
                    int colIndex = firstRow.FirstCellNum;

                    //獲取列數
                    int colCount = firstRow.LastCellNum;

                    DataColumn dc = null;

                    //獲取列名
                    for (int j = colIndex; j < colCount; j++)
                    {
                        dc = new DataColumn(firstRow.GetCell(j).StringCellValue);
                        dt.Columns.Add(dc);
                    }

                    //跳過第一行列名
                    rowIndex++;

                    for (int k = rowIndex; k <= rowCount; k++)
                    {
                        DataRow dr = dt.NewRow();
                        row = sheet.GetRow(k);

                        for (int l = colIndex; l < colCount; l++)
                        {
                            if (row.GetCell(l) == null)
                            {
                                continue;
                            }
                            dr[l] = row.GetCell(l).StringCellValue;
                        }

                        dt.Rows.Add(dr);
                    }

                    ds.Tables.Add(dt);
                }

                sheet = null;
                workbook = null;

                fileStream.Close();
                fileStream.Dispose();
            }
            catch (Exception ex)
            {
                throw;
            }

            return ds;
        }
View Code

我這里用的是 .xlsx 格式的,也就是 Excel 2007 及以上版本,2003 版本的話方法類似,只是打開文件的操作類不一樣。

// 2007 及以上版本
XSSFWorkbook xWorkbook = new XSSFWorkbook(fileStream);

// 2003 版本
HSSFWorkbook hWorkbook = new HSSFWorkbook(fileStream);

 

第四種:Aspose.Cells.dll

public DataSet ImportExcel(string filePath)
        {
            DataSet ds = null;

            try
            {
                Aspose.Cells.Workbook workbook = new Aspose.Cells.Workbook();

                //打開文件,參數可以是文件的路徑,也可以直接傳入一個文件流
                workbook.Open(filePath);

                //獲取 sheet 表
                Aspose.Cells.Worksheets worksheets = workbook.Worksheets;

                Aspose.Cells.Worksheet worksheet = null;

                Aspose.Cells.Cells cells = null;

                ds = new DataSet();
                DataTable dt = null;

                int rowIndex = 0;   //起始行
                int colIndex = 0;   //起始列

                for (int i = 0; i < worksheets.Count; i++)
                {
                    dt = new DataTable();
                    dt.TableName = "table" + i.ToString();

                    worksheet = worksheets[i];

                    //獲取每個 sheet 表的所有單元格
                    cells = worksheet.Cells;

                    dt = cells.ExportDataTableAsString(rowIndex, colIndex, cells.MaxDataRow + 1, cells.MaxDataColumn + 1, true);

                    ds.Tables.Add(dt);
                }

                worksheets.Clear();

                worksheet = null;
                worksheets = null;
                workbook = null;
            }
            catch (Exception ex)
            {
                throw;
            }

            return ds;
        }
View Code

 這種方法操作比較方便,跟 OleDB 一樣直接獲取一個 sheet 表的數據,不用一個單元格一個單元格的獲取。而且操作也比較靈活,你可以一行一行的獲取數據,甚至一個單元格一個單元格的獲取數據。

 

第五種:EPPlus

public DataSet ImportExcel(string filePath)
        {
            DataSet ds = null;

            try
            {
                //打開文件
                FileStream fileStream = new FileStream(filePath, FileMode.Open);

                //讀取文件流
                ExcelPackage package = new ExcelPackage(fileStream);

                //獲取 sheet 表
                ExcelWorksheets worksheets = package.Workbook.Worksheets;

                ExcelWorksheet worksheet = null;

                ds = new DataSet();
                DataTable dt = null;

                for (int i = 1; i <= worksheets.Count; i++)
                {
                    dt = new DataTable();
                    dt.TableName = "table" + i.ToString();

                    worksheet = worksheets[i];

                    //獲取行數
                    int rowCount = worksheet.Dimension.End.Row;

                    //獲取列數
                    int colCount = worksheet.Dimension.End.Column;

                    //起始行為 1 
                    int rowIndex = worksheet.Dimension.Start.Row;

                    //起始列為 1 
                    int colIndex = worksheet.Dimension.Start.Column;

                    DataColumn dc = null;

                    for (int j = colIndex; j <= colCount; j++)
                    {
                        dc = new DataColumn(worksheet.Cells[rowIndex, j].Value.ToString());
                        dt.Columns.Add(dc);
                    }

                    rowIndex++;

                    for (int k = rowIndex; k <= rowCount; k++)
                    {
                        DataRow dr = dt.NewRow();

                        for (int l = colIndex; l <= colCount; l++)
                        {
                            if (worksheet.GetValue(k, l) == null)
                            {
                                continue;
                            }

                            dr[l - 1] = worksheet.GetValue(k, l).ToString();
                        }

                        dt.Rows.Add(dr);
                    }

                    ds.Tables.Add(dt);
                }

                package.Dispose();

                worksheet = null;
                worksheets = null;
                package = null;

                fileStream.Close();
                fileStream.Dispose();
            }
            catch (Exception ex)
            {
                throw;
            }

            return ds;
        }
View Code

這種方法讀取 Excel 數據性能還不錯,但是要注意的是,sheet、row、col 的起始值都是從 1 開始的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM