ASP.NET(C#) 讀取EXCEL問題彙總

使用OLEDB能夠對excel文件進行讀取,咱們只要把該excel文件做爲數據源便可。數據庫

一 在D盤建立excel文件test.xls:數組

  

二 將工做表Sheet1的內容讀取到DataSet
  string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+
      "Extended Properties='Excel 8.0'";
  DataSet ds = new DataSet();
  OleDbDataAdapter oada = new OleDbDataAdapter("select * from [Sheet1$]", strConn);
  oada.Fill(ds);asp.net

 

讀取的DataSet爲:ide

  

從圖中能夠看出excel文件中的第一行變成了DataSet中的列名,這正是系統的默認設置。ui

若是想把第一行也做爲數據行,那咱們能夠給鏈接字符串添加一個HDR=No屬性如:
  string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+
      "Extended Properties='Excel 8.0;HDR=No'";
  DataSet ds = new DataSet();
  OleDbDataAdapter oada = new OleDbDataAdapter("select * from [Sheet1$]", strConn);
  oada.Fill(ds);
  結果也許會讓你有點想不到:spa

  

第一行的第一列和第三列都變成空的了,這是由於系統把第一列識別成了數字,把第三列識別成了日期,.net

而第一行的數據不符合格式的要求,因此就變成空的了。excel

四 咱們還能夠把全部列都作爲字符串來讀取,只要添加屬性IMEX=1便可orm

  string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+
      "Extended Properties='Excel 8.0;HDR=No;IMEX=1'";
  DataSet ds = new DataSet();
  OleDbDataAdapter oada = new OleDbDataAdapter("select * from [Sheet1$]", strConn);
  oada.Fill(ds);
  結果又會如何呢?blog

  

是否是再次出乎你的意料,第三行的日期怎麼變成數字了,其實excel在轉換格式的時候就自動把日期變成數字了,

那這個數字是怎麼來的呢 ? 若是你把日期改爲1900年1月1日,那麼你能夠看到他的轉換結果是1,以此類推,39902是哪一天就明白了吧。

這裏解決辦法:

方法一:
  public static string getDateStr(string strValue)
      {
          int i = Convert.ToInt32(strValue);
          DateTime d1 = Convert.ToDateTime("1900-1-1");
          DateTime d2 = d1.AddDays(i - 2);
          string strTemp = d2.ToString("d");

          return strTemp;
      }
  方法二:
  DateTime.FromOADate(Convert.ToInt32(strValue)).ToString("d");

五 也許你並不想讀取整個excel的內容

若是隻想讀取前兩列能夠用:select * from [Sheet1$A:B]

若是隻想讀取A1到B2的內容,就用:select * from [Sheet1$A1:B2]

六 若是不知道工做表的名字或名字被人爲修改了該怎麼辦呢?

咱們能夠經過索引來獲取指定工做表的名字,如下方法能夠用來獲取工做表名稱的數組:


  ArrayList al = new ArrayList();
  string strConn;
  strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+
      "Extended Properties=Excel 8.0;";
  OleDbConnection conn = new OleDbConnection(strConn);
  conn.Open();
  DataTable sheetNames = conn.GetOleDbSchemaTable
      (OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
  conn.Close();
  foreach (DataRow dr in sheetNames.Rows)
  {
      al.Add(dr[2]);
  }
  return al;

 

IMEX=1的時候並非全都會做爲字符串來處理,根據系統的默認設置,一般若是前8行有字符串,則該列會做爲字符串來處理,若是全都爲數字,則該列爲數字列,日期也是同樣。

若是你以爲8行不夠或者太多了,則只能修改註冊表HKEY_LOCAL_MACHINE/Software/Microsoft/Jet/4.0/Engines/Excel/TypeGue***ows,若是此值爲0,則會根據全部行來判斷使用什麼類型,一般不建議這麼作,除非你的數據量確實比較少。 

 

沒法讀取EXCEL中的數據單元格。有數據,可是讀出來全是空值。

解決方法:

1.在導入數據鏈接字符串中,將IMEX=1加入,「Provider=Microsoft.Jet.OLEDB.4.0;Data Source="C:\Data.xls";Extended Properties="Excel 8.0;HDR=Yes;IMEX=1; 」,這樣就能夠。

注:

「HDR=Yes;」指示第一行中包含列名,而不是數據;

「IMEX=1;」通知驅動程

序始終將「互混」數據列做爲文本讀取。

二者必須一塊兒使用。

本覺得這樣就OK了。但在實際使用過程當中,這樣設置仍是不行,查閱了很多資料才發現,原來還有一個註冊表裏的信息須要修改,這樣帶能讓excel再也不使用前8行的內容來肯定該列的類型。

註冊表修改內容以下:

在HKEY_LOCAL_MACHINE\Software\Microsoft\Jet\4.0\Engines\Excel有一個TypeGue***ows值,預設是8,表示會先讀取前8列來決定每個欄位的型態,因此若是前8列的資料都是數字,到了第9列之後出現的文字資料都會變成null,因此若是要解決這個問題,只要把TypeGue***ows機碼值改爲0,就能夠解這個問題了。

 

asp.net 解決使用OLEDB導入excel數據時同時包含文本和數字的列沒法正常讀取狀況


1.鏈接語句中必須包含IMEX=1

         EXCEL2003:Provider=Microsoft.Jet.OLEDB.4.0;Data Source='文件路徑';Extended Properties=Excel 8.0;HDR=Yes;IMEX=1

         EXCEL2007:Provider=Microsoft.ACE.OLEDB.12.0;Data Source='文件路徑';Extended Properties=Excel 12.0;HDR=Yes;IMEX=1

 2.設置註冊表信息:【HKEY_LOCAL_MACHINE/Software/Microsoft/Jet/4.0/Engines/Excel/】

        ImportMixedType :Text (注:值爲Text,則該列爲文本;值爲Majority Type,則取數據多的類型)

        TypeGue***ows :0  (注:0表示要讀取全部數據再來判斷是不是混合類型)

OLEDB 鏈接 Excel 中的 HDR 與 IMEX 解釋

 Microsoft.Jet.OleDb 鏈接 Excel,就像數據庫同樣操做 Excel,如下是一個示例的鏈接字符串:

string connString = "Provider=Microsoft.Jet.OleDb.4.0;Data Source=" + filePath +";Extended Properties='Excel    8.0;HDR=NO;IMEX=1;'";

HDR

HDR 表示第一行是不是標題行。

  • 若爲 YES,則第一行是標題行(即列名稱),不是數據;

  • 若爲 NO,則第一行不是標題行,跟後面的行同樣,是數據。

IMEX

即 intermixed,表示混合數據類型時如何處理。Excel 不像 Access 樣,Access 每一字段(列)具備數據類型,Excel 不具備,因此 Excel 第一行第一列能夠存儲字符串,第二行第一列又能夠存儲數字……一樣的列,存儲不一樣的數據類型,這就造成了混合數據類型。

若是咱們的 Excel 不存在混合數據類型,則能夠省略 IMEX;若是咱們的 Excel 存在混合數據類型,則須要正確指定 IMEX,不然 OLEDB 極可能錯誤地判斷數據類型,致使讀取出來的數據是空白,甚至讀取不到行等錯誤。

  • 若爲 0,則爲輸出模式,此狀況下只能用做寫入 Excel;

  • 若爲 1,則爲輸入模式,此狀況下只能用做讀取 Excel,而且始終將 Excel 數據做爲文本類型讀取;

  • 若爲 2,則爲鏈接模式,此狀況下既可用做寫入、也可用做讀取。

因此若要讀取混合數據類型,應該將 IMEX 設置爲 1;若誤設置爲 0,則讀取不到任何行;若誤設置爲 2 或省略,則有些數據讀取出來是空白。

注意:輸出模式對應寫入、輸入模式對應讀取。

 Microsoft.Jet.OleDb 鏈接 Excel,就像數據庫同樣操做 Excel,如下是一個示例的鏈接字符串:

string connString = "Provider=Microsoft.Jet.OleDb.4.0;Data Source=" + filePath +";Extended Properties='Excel 8.0;HDR=NO;IMEX=1;'";

HDR

HDR 表示第一行是不是標題行。

  • 若爲 YES,則第一行是標題行(即列名稱),不是數據;

  • 若爲 NO,則第一行不是標題行,跟後面的行同樣,是數據。

IMEX

即 intermixed,表示混合數據類型時如何處理。Excel 不像 Access 樣,Access 每一字段(列)具備數據類型,Excel 不具備,因此 Excel 第一行第一列能夠存儲字符串,第二行第一列又能夠存儲數字……一樣的列,存儲不一樣的數據類型,這就造成了混合數據類型。

若是咱們的 Excel 不存在混合數據類型,則能夠省略 IMEX;若是咱們的 Excel 存在混合數據類型,則須要正確指定 IMEX,不然 OLEDB 極可能錯誤地判斷數據類型,致使讀取出來的數據是空白,甚至讀取不到行等錯誤。

  • 若爲 0,則爲輸出模式,此狀況下只能用做寫入 Excel;

  • 若爲 1,則爲輸入模式,此狀況下只能用做讀取 Excel,而且始終將 Excel 數據做爲文本類型讀取;

  • 若爲 2,則爲鏈接模式,此狀況下既可用做寫入、也可用做讀取。

因此若要讀取混合數據類型,應該將 IMEX 設置爲 1;若誤設置爲 0,則讀取不到任何行;若誤設置爲 2 或省略,則有些數據讀取出來是空白。

注意:輸出模式對應寫入、輸入模式對應讀取。

 Microsoft.Jet.OleDb 鏈接 Excel,就像數據庫同樣操做 Excel,如下是一個示例的鏈接字符串:

string connString = "Provider=Microsoft.Jet.OleDb.4.0;Data Source=" + filePath +";Extended Properties='Excel 8.0;HDR=NO;IMEX=1;'";

HDR

HDR 表示第一行是不是標題行。

  • 若爲 YES,則第一行是標題行(即列名稱),不是數據;

  • 若爲 NO,則第一行不是標題行,跟後面的行同樣,是數據。

IMEX

即 intermixed,表示混合數據類型時如何處理。Excel 不像 Access 樣,Access 每一字段(列)具備數據類型,Excel 不具備,因此 Excel 第一行第一列能夠存儲字符串,第二行第一列又能夠存儲數字……一樣的列,存儲不一樣的數據類型,這就造成了混合數據類型。

若是咱們的 Excel 不存在混合數據類型,則能夠省略 IMEX;若是咱們的 Excel 存在混合數據類型,則須要正確指定 IMEX,不然 OLEDB 極可能錯誤地判斷數據類型,致使讀取出來的數據是空白,甚至讀取不到行等錯誤。

  • 若爲 0,則爲輸出模式,此狀況下只能用做寫入 Excel;

  • 若爲 1,則爲輸入模式,此狀況下只能用做讀取 Excel,而且始終將 Excel 數據做爲文本類型讀取;

  • 若爲 2,則爲鏈接模式,此狀況下既可用做寫入、也可用做讀取。

因此若要讀取混合數據類型,應該將 IMEX 設置爲 1;若誤設置爲 0,則讀取不到任何行;若誤設置爲 2 或省略,則有些數據讀取出來是空白。

注意:輸出模式對應寫入、輸入模式對應讀取。

相關文章
相關標籤/搜索