2011-01-10 67 views
2

我已經編寫了一個可以使用Microsoft數據訪問引擎讀取Excel 2007文件的代碼,下面的代碼片段適用於大多數文件,但它恰好適用於大多數excel文件,即.xlsx, .xls但在objConn.Open()時失敗;爲讓Excel格式問題的Excel文件,請參閱下面的圖像Microsoft OLEDB錯誤外部表格未處於預期格式

Excel file with formatting errors

這將無法打開OLE DB連接指出錯誤外部表不是預期的格式。還有一個問題,這個導入過程是

  OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM "+ SelectionSheet, objConn); 

是無法讀取開始用空格與解決這一問題的任何幫助,將不勝感激張。

 public DataTable ReadExcel(string Path, ArrayList IgnoreString, ArrayList IgnoreColumn) 
     { 
      DataTable dtReturn = new DataTable(); 
      DataTable dtPrintable = new DataTable(); 
      DataTable dtTemp = new DataTable(); 
      try 
      { 
       string sConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" + 
             "Data Source=" + Path + ";" + "Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1;\""; 

       OleDbConnection objConn = new OleDbConnection(sConnectionString); 




       objConn.Open(); 
       DataTable dtSheetnames = objConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null); 

       DataTable dtTesting = objConn.GetOleDbSchemaTable(OleDbSchemaGuid.DbInfoLiterals, new object[] {}); 
       DataTable dtTesting2 = objConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables_Info, new object[] { }); 


       string SelectionSheet = dtSheetnames.Rows[0][2].ToString(); 

       if (SelectionSheet.Contains("'")) 
       { 
        SelectionSheet = SelectionSheet.Remove(0, 1); 
        SelectionSheet = "[" + SelectionSheet; 
        SelectionSheet = SelectionSheet.Remove(SelectionSheet.Length - 1, 1); 
        // -- Mod by zeemz on 23 dec 
        // string PrintArea = SelectionSheet + "Print_Area]"; 

        SelectionSheet = SelectionSheet + "]"; 
       } 
       else 
       { 
        SelectionSheet = "["+ SelectionSheet + "]"; 
       } 


       //OleDbCommandBuilder objCmdBuilder = new OleDbCommandBuilder(


       OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM "+ SelectionSheet, objConn); 




       OleDbDataAdapter objAdapter = new OleDbDataAdapter(); 
       DataSet objDataSet = new DataSet(); 

       DataSet PrintAreads = new DataSet(); 

       objAdapter.SelectCommand = objCmdSelect; 
       objAdapter.Fill(objDataSet); 

       // -- Mod by zeemz on 23 dec 
       //objCmdSelect.CommandText = "SELECT * FROM " + PrintArea; 
       //objAdapter.Fill(PrintAreads); 




       objConn.Close(); 

       dtReturn = objDataSet.Tables[0].Copy(); 
       // dtPrintable = PrintAreads.Tables[0].Copy(); 

       // -- Mod by zeemz on 23 dec 
       //if (dtPrintable.Columns.Count != dtReturn.Columns.Count) 
       //{ 
       // int TotalPrintable = dtPrintable.Columns.Count; 
       // int TotalComing = dtReturn.Columns.Count; 
       // int StartRemovingPos = TotalComing - TotalPrintable; 

       // for (int i = TotalPrintable; dtPrintable.Columns.Count != dtReturn.Columns.Count; i++) 
       // { 

       //  dtReturn.Columns.RemoveAt(i); 
       //  i = i - 1 ; 
       // } 


       //} 


       int iCount = 0; 
       while (iCount <= dtReturn.Rows.Count - 1) 
       { 
        if (isRowEmpty(dtReturn.Rows[iCount])) 
        { 
         dtReturn.Rows.RemoveAt(iCount); 
        } 
        else 
        { 
         iCount += 1; 
        } 
       } 


       //now applying the filters 

       //column ignore 
       for (int i = IgnoreColumn.Count - 1; i >= 0; i--) 
       { 
        dtReturn.Columns.RemoveAt((int)IgnoreColumn[i]); 
       } 

       //string ignore 
       for (int i = IgnoreString.Count - 1; i >= 0; i--) 
       { 
        for (int j = dtReturn.Rows.Count - 1; j >= 0; i--) 
        { 
         foreach (DataColumn dCol in dtReturn.Columns) 
         { 
          if (dtReturn.Rows[j][dCol.ColumnName].ToString().ToLower().Contains(IgnoreString[i].ToString().ToLower())) 
          { 
           dtReturn.Rows.RemoveAt(j); 
           break; 
          } 
         } 
        } 
       } 


       /* Hack to get rid of DateTime Columns */ 
       // added by zeemz 
       dtTemp = dtReturn.Clone(); 
       dtTemp.Clear(); 
       foreach (DataColumn tempColumn in dtTemp.Columns) 
       { 
       // if (tempColumn.DataType == typeof(DateTime)) 
//     { 
         tempColumn.DataType = typeof(String); 
    //     } 
       } 
       foreach (DataRow tempRow in dtReturn.Rows) 
       { 
        DataRow insRow = dtTemp.NewRow(); 
        foreach (DataColumn tempColumn in dtReturn.Columns) 
        { 

         if (tempColumn.DataType == typeof(DateTime)) 
         { 
          if (!String.IsNullOrEmpty(tempRow[tempColumn.ColumnName.ToString()].ToString())) 
          { 
           insRow[tempColumn.ColumnName.ToString()] = Convert.ToDateTime(tempRow[tempColumn.ColumnName.ToString()].ToString()).ToString("yyyyMMddhhmmss"); 
          } 
          else 
          { 
           insRow[tempColumn.ColumnName.ToString()] = ""; 
          } 
         } 
         else 
         { 

          insRow[tempColumn.ColumnName.ToString()] = tempRow[tempColumn.ColumnName.ToString()].ToString(); 
         } 

        } 
        dtTemp.Rows.Add(insRow); 
       } 



      } 
      catch (Exception ex) 
      { 
       throw ex; 
      } 

      return dtTemp; 
     } 

回答

2

我碰巧發現當你手動或編程修改XLSX文件,而無需使用Excel,一旦你修改的xlsx格式不保持不變,並在上面提到的錯誤出現,因爲OleDbDataAdapter的是無法存在的問題處理修改後的文件和Excel它自己可以修復損壞的文件按預期顯示文件。

+0

你知道是否有方法以編程方式重新保存Excel文件?所以它不需要用戶干預來解決這個問題? – ProfessionalAmateur 2013-05-21 22:18:08

相關問題