1. 程式人生 > >C#各種導入Excel文件的數據的方法總結

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

context tab 過程 all dap 添加列 map lease 內存

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

protected void btnImport_Click(object sender,EventArgs e)

{

Random random=new Random();

ImportClass Import=new ImportClass();

//保存文件的虛擬路徑

string path="Import/";

//獲取選擇的文件名

string fileName=FileUpload.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;

}

}

第一種:

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;
        }
除了讀取過程不太靈活之外,這種讀取方式還有個弊端就是,當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;
int colIndex=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];
dr[l]=range.Text.ToString();
}
dt.Tables.Add(dt);
}
}
catch(Exception ex)
{
throw;
}
finally
{
workbook.Close();
excel.Quit();
Marshal.ReleaseComObject(worksheet);
Marshal.ReleaseComObject(workbook);
Marshal.ReleaseComObject(excel);
worksheet=null;
workbook=null;
excel=null;
GC.Collect();
}
return ds;
}
這種方法首先需要安裝有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;
}
我這裏用的是.xlsx格式的,也就是Excel2007及以上版本,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 cell=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;
workbokk=null;
}
catch(Exception ex)
{
throw;
}
return ds;
}
這種方法操作比較方便,跟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.Dimenson.Start.Row;
//起始列為1
int colIndex=worksheet.Dimension.Start.Colimn;
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();
}
ds.Tables.Add(dt);
}
package.Dispose();
worksheet=null;
worksheets=null;
package=null;
fileStream.Close();
fileStream.Dispose();
}
catch(Exception ex)
{
throw;
}
return ds;
}
這種方法讀取Excel數據性能還不錯,但是要註意的是,sheet、row、col的起始值都是從1開始的



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