2011-01-10 2 views
2

Microsoft 데이터 액세스 엔진을 사용하여 Excel 2007 파일을 읽을 수있는 코드를 작성했습니다. 아래 코드 조각은 대부분의 파일에서 제대로 작동하지만 대부분의 경우 작동합니다. 즉, .xlsx, .xls 파일을 제외하고 objConn.Open()에서 실패 할 경우. 엑셀 서식에 문제가 엑셀 파일이 오류 외부 테이블을 알리는 OLE DB 연결을 열지 못했습니다 것이다Microsoft OLEDB 오류 외부 테이블이 예상 된 형식이 아닙니다.

Excel file with formatting errors

아래의 이미지를 참조하시기 바랍니다에 대한 예상되는 형식 아닙니다. 이 가져 오기 절차에 또 하나의 문제는

  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을 수정하고 위해 OleDbDataAdapter가 없기 때문에 위에서 언급 한 오류가 나오면 일단 당신이 엑셀을 사용하지 않고 수동으로 또는 프로그래밍 방식 XLSX 파일을 수정할 때 문제가 존재 찾을 일이 수정 된 파일을 처리하고 Excel 자체가 손상된 파일을 고칠 수있는 파일을 예상대로 보여줍니다.

+0

프로그래밍 방식으로 파일을 Excel로 다시 저장하는 방법이 있는지 알고 있습니까? 그래서이 문제를 해결하기 위해 사용자 개입이 필요하지 않습니까? – ProfessionalAmateur

관련 문제