2015-02-03 7 views
0

OpenXML 라이브러리를 통해 시트 이름을 얻기 위해 Excel 데이터로 DataSet을 채우려고 시도하지만 일부 경우에는 오류가 발생합니다. "외부 테이블이 예상 된 형식이 아닙니다"."외부 테이블이 예상 된 형식이 아닙니다."

그래서 동일한 파일 = * .xlsx (Excel 2010을 통해 * .xls에서 * .xlsx로 변환 됨)를 사용합니다.

어제는 그것을 잘 작동하지만 작동하지 않습니다 지금 - :

public DataTable CreateTable(string sheetName) 
    { 
     sheetName = sheetName + "$"; 
     bool hasHeaders = false; 
     string HDR = hasHeaders ? "Yes" : "No"; 
     string strConn; 
     if (_filePath.Substring(_filePath.LastIndexOf('.')).ToLower() == ".xlsx") 
      strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" 
       + _filePath + ";Extended Properties=\"Excel 12.0;HDR=" + HDR + ";IMEX=0\""; 
     //  strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + _filePath + ";Extended Properties=Excel 12.0;"; 
     else 
      strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + _filePath + ";Extended Properties=\"Excel 8.0;HDR=" + HDR + ";IMEX=0\""; 

     try 
     { 
      OleDbConnection conn = new OleDbConnection(strConn); 


      System.Data.DataSet dtSet; 
      System.Data.OleDb.OleDbDataAdapter oleCommand; 
      oleCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [" + sheetName + "]", conn); 
      oleCommand.TableMappings.Add("Table", sheetName); 
      dtSet = new System.Data.DataSet(); 

      oleCommand.Fill(dtSet); 
      oleCommand.Dispose(); 
      conn.Close(); 
      return dtSet.Tables[0]; 
     } 
     catch (Exception ex) 
     { 
      //log here 
     } 

     throw new NullReferenceException(); 

    } 

내가 Excel 파일에서 시트 이름을 가져, 여기에 $를 추가하고 데이터 세트를 기입하십시오.

하지만 라인에서

:

oleCommand.Fill(dtSet); it throw exception. 

그러나 일부 시간은 다음 라인으로 이동합니다. 다른 소스에서이 파일을 다시 복사하려고 시도했지만 작동합니다.

저를 고치는 법을 알려주세요.

P. OpenXML로이 파일을 열면 파일이 손상 될 수 있습니까?

OPENXML 부분 (클래스 ExcelHelper) :

public ExcelHelper(String filePath, bool isEditable) 
    { 
     _filePath = filePath; 
     _isEditable = isEditable; 
    } 

public List<String> GetSheetNameColl() 
    { 
     if (_spreadSheetDoc == null) 
      throw new NullReferenceException("_spreadSheetDoc is null!"); 

     List<String> sheetNameColl=new List<string>(); 

     int sheetIndex = 0; 
     WorkbookPart workbookPart = _spreadSheetDoc.WorkbookPart; 
     foreach (WorksheetPart worksheetpart in _spreadSheetDoc.WorkbookPart.WorksheetParts) 
     { 
      Worksheet worksheet = worksheetpart.Worksheet; 

      // Grab the sheet logFileName each time through your loop 
      string sheetName = workbookPart.Workbook.Descendants<Sheet>().ElementAt(sheetIndex).Name; 
      sheetNameColl.Add(sheetName); 
      Console.WriteLine(sheetName+" "+sheetIndex); 

      sheetIndex++; 
     } 
     return sheetNameColl; 
    } 

public SpreadsheetDocument Open() 
    { 
     try 
     { 
      _spreadSheetDoc = SpreadsheetDocument.Open(_filePath, _isEditable); 

      isLoaded = true; 
      return _spreadSheetDoc; 
     } 
     catch (Exception ex) 
     { 
      //log here 
     } 
     throw new NullReferenceException("Error at Open() method"); 
    } 

    public void Close() 
    { 
     if (_spreadSheetDoc != null) 
     { 
      _spreadSheetDoc.Close(); 
      isLoaded = false; 
     } 

    } 

Program.cs :

ExcelHelper excel = 
       new ExcelHelper(@"MyFile.xlsx", false); 
      excel.Open(); 
      var sheetNameColl = excel.GetSheetNameColl(); 

      List<DataTable> dtColl = new List<DataTable> (sheetNameColl.Count); 

      foreach (var sheetName in sheetNameColl) 
      { 
       var table = excel.CreateTable(sheetName); 
       DataTableHelper dtHelper = new DataTableHelper(table); 
       table = dtHelper.RenameColumns(); 
       dtColl.Add(table); 
      } 
      excel.Close(); 
+1

제목을 편집했습니다. "[제목에"태그 "가 포함되어 있어야합니까?] (http://meta.stackexchange.com/questions/19190/)"합의가 "아니오, 그렇지 않아야합니다"로 표시되어야합니다. –

+0

이 솔루션을 사용해보십시오. http://stackoverflow.com/questions/28923158/external-table-is-not-in-the-expected-format – Shady

답변

2

이에 대한 나의 솔루션 :

스위치 EPPlus API에 대한이 - 그것은 무료로 쉽게 사용하기 ,이 문제가 없습니다.

/// <summary> 
/// Manipulate an excel file using the EPPlus API, free from http://epplus.codeplex.com/ 
/// License terms (Public) on http://epplus.codeplex.com/license 
/// 
/// </summary> 
public class ExcelWriter : IDisposable 
{ 
    ExcelPackage _pck; 

    /// <summary> 
    /// Open a new or existing file for editing. 
    /// </summary> 
    /// <param name="fileName"></param> 
    public ExcelWriter(string fileName) 
    { 
     _pck = new ExcelPackage(new FileInfo(fileName)); 
    } 

    /// <summary> 
    /// Open a new or existing file for editing, and add a new worksheet with the data 
    /// </summary> 
    /// <param name="fileName"></param> 
    /// <param name="newWorksheetName">new sheet to add</param> 
    /// <param name="dtData">data to add</param> 
    public ExcelWriter(string fileName, string newWorksheetName, DataTable dtData):this(fileName) 
    { 
     var ws = this.AddWorksheet(newWorksheetName); 
     this.SetValues(ws, dtData); 
    } 

    /// <summary> 
    /// Add a new worksheet. Names must be unique. 
    /// </summary> 
    /// <param name="name"></param> 
    /// <returns></returns> 
    public ExcelWorksheet AddWorksheet(string name) 
    { 
     return _pck.Workbook.Worksheets.Add(name); 
    } 

    /// <summary> 
    /// Add a new picture. Names must be unique. 
    /// </summary> 
    /// <param name="image"></param> 
    /// <param name="imageName"></param> 
    /// <param name="ws"></param> 
    /// <param name="row"></param> 
    /// <param name="col"></param> 
    public ExcelPicture AddPicture(Image image, string imageName, ExcelWorksheet ws, int row, int col) 
    { 
     var pic = ws.Drawings.AddPicture(imageName, image); 
     pic.SetPosition(row, 0, col, 0); 
     pic.Border.LineStyle = eLineStyle.Solid; 
     return pic; 
    } 

    /// <summary> 
    /// Note: this will only perform as well as 'SetValues' if you load/write data from left to right, top to bottom. Otherwise it may perform poorly. 
    /// </summary> 
    /// <param name="ws"></param> 
    /// <param name="row"></param> 
    /// <param name="col"></param> 
    /// <param name="value"></param> 
    public void SetValue(ExcelWorksheet ws, int row, int col, object value) 
    { 
     ws.Cells[row, col].Value = value; 
    } 

    /// <summary> 
    /// Populate a large number of cells at once 
    /// </summary> 
    /// <param name="ws"></param> 
    /// <param name="value">Data to load</param> 
    public void SetValues(ExcelWorksheet ws, List<object[]> value) 
    { 
     ws.Cells.LoadFromArrays(value); 
    } 

    /// <summary> 
    /// Populate a large number of cells at once 
    /// </summary> 
    /// <param name="ws"></param> 
    /// <param name="value">Data to load</param> 
    public void SetValues(ExcelWorksheet ws, DataTable dt) 
    { 
     ws.Cells.LoadFromDataTable(dt, true); 
    } 

    public void SetDefaultRowHeight(ExcelWorksheet ws, int rowHeight) 
    { 
     ws.DefaultRowHeight = rowHeight; 
    } 

    /// <summary> 
    /// Saves to file and dispos 
    /// </summary> 
    public void Save() 
    { 
     _pck.Save(); 
    } 

    /// <summary> 
    /// Release all resources 
    /// </summary> 
    public void Dispose() 
    { 
     if (_pck != null) 
      _pck.Dispose(); 
    } 
} // class