2012-10-15 76 views
4

我不知道是否有一種簡單的方法來讀取Excel 2010 XML?
該XML與我以前閱讀的結構不同。如何閱讀Excel XML(C#)

特別是SS:索引屬性(SS:指數** = 「7」)使事情多一點

編輯複雜: 更好地說明:

  • 我有一個XML文件可以很容易地在Excel中打開的擴展名
  • 我正在尋找一種方法來閱讀此表(例如複製到DataTable)
  • 注意到這是不常用的XML我曾經工作
  • XML在開始時定義字段,而不是使用ROW,CELL和DATA標記
  • 令我驚訝的是,當有例如3個字段(單元格)但第2個字段沒有值時,此字段在XML中被「跳過」但第三字段具有一些額外的「索引」屬性例如:SS:指數** =「3」(這表明,即使它是在第二位置右索引應該是「3」片段例如XML

 <Row ss:AutoFitHeight="0"> 
     <Cell><Data ss:Type="String">Johny</Data></Cell> 
     <Cell ss:Index="3"><Data ss:Type="String">NY</Data></Cell> 
+0

好吧,我可以在您的文章閱讀。你到底在找什麼? – RBarryYoung

+0

尋找簡單的方法讓我們來說,將Excel文件存儲爲XML到DataTable。我知道如何處理XML,但是我遇到了ss問題:索引屬性(在單元格爲空時使用) – Maciej

+0

這可能有助於解釋*那個*問題。 – RBarryYoung

回答

6

OK我終於找到解決辦法嘗試從這裏:http://www.codeproject.com/Articles/32370/Import-Excel-File-to-DataSet#xx

下面的示例代碼很少採用我的需求。

public static class XMLtoDataTable { 
    private static ColumnType getDefaultType() { 
    return new ColumnType(typeof(String)); 
} 

     struct ColumnType { 
      public Type type; 
      private string name; 
      public ColumnType(Type type) { this.type = type; this.name = type.ToString().ToLower(); } 
      public object ParseString(string input) { 
       if (String.IsNullOrEmpty(input)) 
        return DBNull.Value; 
       switch (type.ToString()) { 
        case "system.datetime": 
         return DateTime.Parse(input); 
        case "system.decimal": 
         return decimal.Parse(input); 
        case "system.boolean": 
         return bool.Parse(input); 
        default: 
         return input; 
       } 
      } 
     } 


    private static ColumnType getType(XmlNode data) { 
    string type = null; 
    if (data.Attributes["ss:Type"] == null || data.Attributes["ss:Type"].Value == null) 
     type = ""; 
    else 
     type = data.Attributes["ss:Type"].Value; 

    switch (type) { 
     case "DateTime": 
      return new ColumnType(typeof(DateTime)); 
     case "Boolean": 
      return new ColumnType(typeof(Boolean)); 
     case "Number": 
      return new ColumnType(typeof(Decimal)); 
     case "": 
      decimal test2; 
      if (data == null || String.IsNullOrEmpty(data.InnerText) || decimal.TryParse(data.InnerText, out test2)) { 
       return new ColumnType(typeof(Decimal)); 
      } else { 
       return new ColumnType(typeof(String)); 
      } 
     default://"String" 
      return new ColumnType(typeof(String)); 
    } 
} 

    public static DataSet ImportExcelXML (string fileName, bool hasHeaders, bool autoDetectColumnType) { 
     StreamReader sr = new StreamReader(fileName); 
     Stream st = (Stream) sr.BaseStream; 
     return ImportExcelXML(st, hasHeaders, autoDetectColumnType); 
    } 

    private static DataSet ImportExcelXML(Stream inputFileStream, bool hasHeaders, bool autoDetectColumnType) { 
     XmlDocument doc = new XmlDocument(); 
     doc.Load(new XmlTextReader(inputFileStream)); 
     XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); 

     nsmgr.AddNamespace("o", "urn:schemas-microsoft-com:office:office"); 
     nsmgr.AddNamespace("x", "urn:schemas-microsoft-com:office:excel"); 
     nsmgr.AddNamespace("ss", "urn:schemas-microsoft-com:office:spreadsheet"); 

     DataSet ds = new DataSet(); 

     foreach (XmlNode node in 
      doc.DocumentElement.SelectNodes("//ss:Worksheet", nsmgr)) { 
      DataTable dt = new DataTable(node.Attributes["ss:Name"].Value); 
      ds.Tables.Add(dt); 
      XmlNodeList rows = node.SelectNodes("ss:Table/ss:Row", nsmgr); 
      if (rows.Count > 0) { 

       //************************* 
       //Add Columns To Table from header row 
       //************************* 
       List<ColumnType> columns = new List<ColumnType>(); 
       int startIndex = 0; 
       if (hasHeaders) { 
        foreach (XmlNode data in rows[0].SelectNodes("ss:Cell/ss:Data", nsmgr)) { 
         columns.Add(new ColumnType(typeof(string)));//default to text 
         dt.Columns.Add(data.InnerText, typeof(string)); 
        } 
        startIndex++; 
       } 
       //************************* 
       //Update Data-Types of columns if Auto-Detecting 
       //************************* 
       if (autoDetectColumnType && rows.Count > 0) { 
        XmlNodeList cells = rows[startIndex].SelectNodes("ss:Cell", nsmgr); 
        int actualCellIndex = 0; 
        for (int cellIndex = 0; cellIndex < cells.Count; cellIndex++) { 
         XmlNode cell = cells[cellIndex]; 
         if (cell.Attributes["ss:Index"] != null) 
          actualCellIndex = 
           int.Parse(cell.Attributes["ss:Index"].Value) - 1; 

         ColumnType autoDetectType = 
          getType(cell.SelectSingleNode("ss:Data", nsmgr)); 

         if (actualCellIndex >= dt.Columns.Count) { 
          dt.Columns.Add("Column" + 
           actualCellIndex.ToString(), autoDetectType.type); 
          columns.Add(autoDetectType); 
         } else { 
          dt.Columns[actualCellIndex].DataType = autoDetectType.type; 
          columns[actualCellIndex] = autoDetectType; 
         } 

         actualCellIndex++; 
        } 
       } 
       //************************* 
       //Load Data 
       //************************* 
       for (int i = startIndex; i < rows.Count; i++) { 
        DataRow row = dt.NewRow(); 
        XmlNodeList cells = rows[i].SelectNodes("ss:Cell", nsmgr); 
        int actualCellIndex = 0; 
        for (int cellIndex = 0; cellIndex < cells.Count; cellIndex++) { 
         XmlNode cell = cells[cellIndex]; 
         if (cell.Attributes["ss:Index"] != null) 
          actualCellIndex = int.Parse(cell.Attributes["ss:Index"].Value) - 1; 

         XmlNode data = cell.SelectSingleNode("ss:Data", nsmgr); 

         if (actualCellIndex >= dt.Columns.Count) { 
          for (int ii = dt.Columns.Count; ii < actualCellIndex; ii++) { 
           dt.Columns.Add("Column" + actualCellIndex.ToString(), typeof(string));columns.Add(getDefaultType()); 
          } // ii 
          ColumnType autoDetectType = 
           getType(cell.SelectSingleNode("ss:Data", nsmgr)); 
          dt.Columns.Add("Column" + actualCellIndex.ToString(), 
              typeof(string)); 
          columns.Add(autoDetectType); 
         } 
         if (data != null) 
          row[actualCellIndex] = data.InnerText; 

         actualCellIndex++; 
        } 

        dt.Rows.Add(row); 
       } 
      } 
     } 
     return ds; 
    } 


} 
+0

只想說謝謝!這個作品完美無瑕,在我將雙打(ss :)改爲單打(s :)後,由CarlosAq XML Excel Writer Library生成的xml。爲我節省了數小時的工作時間!感謝分享! – Umo

+0

這是所有意圖和目的的一個很好的解決方案,但要注意重複的列名稱,此代碼不會考慮它們,並且需要在遇到它們時進行修改。 –

1

先試用官方API(Microsoft Open XML SDK)。

+0

是否閱讀.XLSX?我正在尋找方式來讀取XML擴展名的文件。試過這個:http://msdn.microsoft.com/en-us/library/hh298534.aspx,但說「文件包含損壞的數據。」 – Maciej

+0

是的,它用於閱讀OOXML容器。但是,您必須做額外的工作來提取原始XML並處理它,爲什麼不避免這些並直接處理容器? –

1

您可以使用此代碼

var textReader = new XmlTextReader("...\\YourFile.xml"); 
    // Read until end of file 
    while (textReader.Read()) 
    { 
     XmlNodeType nType = textReader.NodeType; 
     // If node type us a declaration 
     if (nType == XmlNodeType.XmlDeclaration) 
     { 
      Console.WriteLine("Declaration:" + textReader.Name.ToString()); 
     } 
     // if node type is a comment 
     if (nType == XmlNodeType.Comment) 
     { 
      Console.WriteLine("Comment:" + textReader.Name.ToString()); 
     } 
     // if node type us an attribute 
     if (nType == XmlNodeType.Attribute) 
     { 
      Console.WriteLine("Attribute:" + textReader.Name.ToString()); 
     } 
     // if node type is an element 
     if (nType == XmlNodeType.Element) 
     { 
      Console.WriteLine("Element:" + textReader.Name.ToString()); 
     } 
     // if node type is an entity\ 
     if (nType == XmlNodeType.Entity) 
     { 
      Console.WriteLine("Entity:" + textReader.Name.ToString()); 
     } 
     // if node type is a Process Instruction 
     if (nType == XmlNodeType.Entity) 
     { 
      Console.WriteLine("Entity:" + textReader.Name.ToString()); 
     } 
     // if node type a document 
     if (nType == XmlNodeType.DocumentType) 
     { 
      Console.WriteLine("Document:" + textReader.Name.ToString()); 
     } 
     // if node type is white space 
     if (nType == XmlNodeType.Whitespace) 
     { 
      Console.WriteLine("WhiteSpace:" + textReader.Name.ToString()); 
     } 
    } 
+0

如何得到它:「ss:Index」屬性值? – Maciej

+0

與此塊Value屬性,如果(n類型== XmlNodeType.Attribute) {VAR的結果= textReader.Value} –

+0

不是真的...當我這樣做:當(textReader.Read())\t \t \t Console.WriteLine (textReader.NodeType +「 - >」+ textReader。價值);任何屬性已列出 – Maciej

1

即使沒有coulmn型它的工作也很好。謝謝 !!!

有樣品不coulmn類型:

private static DataSet ImportExcelXML(Stream inputFileStream, bool hasHeaders) 
{ 
    XmlDocument doc = new XmlDocument(); 
    doc.Load(new XmlTextReader(inputFileStream)); 
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); 

    nsmgr.AddNamespace("o", "urn:schemas-microsoft-com:office:office"); 
    nsmgr.AddNamespace("x", "urn:schemas-microsoft-com:office:excel"); 
    nsmgr.AddNamespace("ss", "urn:schemas-microsoft-com:office:spreadsheet"); 

    DataSet ds = new DataSet(); 

    foreach (XmlNode node in 
     doc.DocumentElement.SelectNodes("//ss:Worksheet", nsmgr)) 
    { 
     DataTable dt = new DataTable(node.Attributes["ss:Name"].Value); 
     ds.Tables.Add(dt); 
     XmlNodeList rows = node.SelectNodes("ss:Table/ss:Row", nsmgr); 
     if (rows.Count > 0) 
     { 

      //************************* 
      //Add Columns To Table from header row 
      //************************* 
      List<ColumnType> columns = new List<ColumnType>(); 
      int startIndex = 0; 
      if (hasHeaders) 
      { 
       foreach (XmlNode data in rows[0].SelectNodes("ss:Cell/ss:Data", nsmgr)) 
       { 
        columns.Add(new ColumnType(typeof(string)));//default to text 
        dt.Columns.Add(data.InnerText, typeof(string)); 
       } 
       startIndex++; 
      } 
      //************************* 
      //Update Data-Types of columns if Auto-Detecting 
      //************************* 
      if (rows.Count > 0) 
      { 
       XmlNodeList cells = rows[startIndex].SelectNodes("ss:Cell", nsmgr); 
       int actualCellIndex = 0; 
       for (int cellIndex = 0; cellIndex < cells.Count; cellIndex++) 
       { 
        XmlNode cell = cells[cellIndex]; 
        if (cell.Attributes["ss:Index"] != null) 
         actualCellIndex = 
          int.Parse(cell.Attributes["ss:Index"].Value) - 1; 

        //ColumnType autoDetectType = 
        // getType(cell.SelectSingleNode("ss:Data", nsmgr)); 

        if (actualCellIndex >= dt.Columns.Count) 
        { 
         //dt.Columns.Add("Column" + 
         // actualCellIndex.ToString(), autoDetectType.type); 
         dt.Columns.Add("Column" + actualCellIndex.ToString()); 
         //columns.Add(autoDetectType); 
        } 
        else 
        { 
         //dt.Columns[actualCellIndex].DataType = autoDetectType.type; 
         //columns[actualCellIndex] = autoDetectType; 
        } 

        actualCellIndex++; 
       } 
      } 
      //************************* 
      //Load Data 
      //************************* 
      for (int i = startIndex; i < rows.Count; i++) 
      { 
       DataRow row = dt.NewRow(); 
       XmlNodeList cells = rows[i].SelectNodes("ss:Cell", nsmgr); 
       int actualCellIndex = 0; 
       for (int cellIndex = 0; cellIndex < cells.Count; cellIndex++) 
       { 
        XmlNode cell = cells[cellIndex]; 
        if (cell.Attributes["ss:Index"] != null) 
         actualCellIndex = int.Parse(cell.Attributes["ss:Index"].Value) - 1; 

        XmlNode data = cell.SelectSingleNode("ss:Data", nsmgr); 

        if (actualCellIndex >= dt.Columns.Count) 
        { 
         for (int ii = dt.Columns.Count; ii < actualCellIndex; ii++) 
         { 
          //dt.Columns.Add("Column" + actualCellIndex.ToString(), typeof(string)); columns.Add(getDefaultType()); 
          dt.Columns.Add("Column" + actualCellIndex.ToString()); 
          //columns.Add(getDefaultType()); 
         } // ii 
         //ColumnType autoDetectType = getType(cell.SelectSingleNode("ss:Data", nsmgr)); 
         dt.Columns.Add("Column" + actualCellIndex.ToString(), 
             typeof(string)); 
         // columns.Add(autoDetectType); 
        } 
        if (data != null) 
         row[actualCellIndex] = data.InnerText; 

        actualCellIndex++; 
       } 

       dt.Rows.Add(row); 
      } 
     } 
    } 
    return ds; 
} 
0
public class ExcelXMLtoDataTable 
{ 
    private static ColumnType getDefaultType() 
    { 
     return new ColumnType(typeof(String)); 
    } 

    struct ColumnType 
    { 
     public Type type; 
     private string name; 

     public ColumnType(Type type) 
     { 
      this.type = type; this.name = type.ToString().ToLower(); 

     } 
     public object ParseString(string input) 
     { 
      if (String.IsNullOrEmpty(input)) 
       return DBNull.Value; 
      switch (type.ToString()) 
      { 
       case "system.datetime": 
        return DateTime.Parse(input); 
       case "system.decimal": 
        return decimal.Parse(input); 
       case "system.boolean": 
        return bool.Parse(input); 
       default: 
        return input; 
      } 
     } 
    } 


    private static ColumnType getType(XmlNode data) 
    { 
     string type = null; 
     //if (data == null) 
     // type = ""; 
     // else 
     if (data.Attributes["ss:Type"] == null || data.Attributes["ss:Type"].Value == "") 
      type = ""; 
     else 
      type = data.Attributes["ss:Type"].Value; 

     switch (type) 
     { 
      case "DateTime": 
       return new ColumnType(typeof(DateTime)); 
      case "Boolean": 
       return new ColumnType(typeof(Boolean)); 
      case "Number": 
       return new ColumnType(typeof(Decimal)); 
      case "": 
       decimal test2; 
       if (data == null || String.IsNullOrEmpty(data.InnerText) || decimal.TryParse(data.InnerText, out test2)) 
       { 
        return new ColumnType(typeof(Decimal)); 
        return new ColumnType(typeof(String)); 
       } 
       else 
       { 
        return new ColumnType(typeof(String)); 
       } 
      default://"String" 
       return new ColumnType(typeof(String)); 
     } 
    } 

    public static DataSet ImportExcelXML(string fileName, bool hasHeaders, bool autoDetectColumnType) 
    { 
     StreamReader sr = new StreamReader(fileName); 
     Stream st = (Stream)sr.BaseStream; 
     return ImportExcelXML(st, hasHeaders, autoDetectColumnType); 
    } 
    private static DataSet ImportExcelXML(Stream inputFileStream, bool hasHeaders, bool autoDetectColumnType) 
    { 
     XmlDocument doc = new XmlDocument(); 
     doc.Load(new XmlTextReader(inputFileStream)); 
     XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); 

     nsmgr.AddNamespace("o", "urn:schemas-microsoft-com:office:office"); 
     nsmgr.AddNamespace("x", "urn:schemas-microsoft-com:office:excel"); 
     nsmgr.AddNamespace("ss", "urn:schemas-microsoft-com:office:spreadsheet"); 

     DataSet ds = new DataSet(); 

     foreach (XmlNode node in 
      doc.DocumentElement.SelectNodes("//ss:Worksheet", nsmgr)) 
     { 
      DataTable dt = new DataTable(node.Attributes["ss:Name"].Value); 
      ds.Tables.Add(dt); 
      XmlNodeList rows = node.SelectNodes("ss:Table/ss:Row", nsmgr); 
      if (rows.Count > 0) 
      { 

       //************************* 
       //Add Columns To Table from header row 
       //************************* 
       List<ColumnType> columns = new List<ColumnType>(); 
       int startIndex = 0; 
       if (hasHeaders) 
       { 
        foreach (XmlNode data in rows[0].SelectNodes("ss:Cell/ss:Data", nsmgr)) 
        { 
         columns.Add(new ColumnType(typeof(string)));//default to text 
         dt.Columns.Add(data.InnerText, typeof(string)); 
        } 
        startIndex++; 
       } 
       //************************* 
       //Update Data-Types of columns if Auto-Detecting 
       //************************* 
       if (autoDetectColumnType && rows.Count > 0) 
       { 
        XmlNodeList cells = rows[startIndex].SelectNodes("ss:Cell", nsmgr); 
        int actualCellIndex = 0; 
        for (int cellIndex = 0; cellIndex < cells.Count; cellIndex++) 
        { 
         XmlNode cell = cells[cellIndex]; 
         if (cell.Attributes["ss:Index"] != null) 
          actualCellIndex = 
           int.Parse(cell.Attributes["ss:Index"].Value) - 1; 

         //ColumnType autoDetectType = 
         // getType(cell.SelectSingleNode("ss:Data", nsmgr)); 

         if (actualCellIndex >= dt.Columns.Count) 
         { 
          //dt.Columns.Add("Column" + 
          // actualCellIndex.ToString(), autoDetectType.type); 
          dt.Columns.Add("Column" + actualCellIndex.ToString()); 
          //columns.Add(autoDetectType); 
         } 
         else 
         { 
          //dt.Columns[actualCellIndex].DataType = autoDetectType.type; 
          //columns[actualCellIndex] = autoDetectType; 
         } 

         actualCellIndex++; 
        } 
       } 
       //************************* 
       //Load Data 
       //************************* 
       for (int i = startIndex; i < rows.Count; i++) 
       { 
        DataRow row = dt.NewRow(); 
        XmlNodeList cells = rows[i].SelectNodes("ss:Cell", nsmgr); 
        int actualCellIndex = 0; 
        for (int cellIndex = 0; cellIndex < cells.Count; cellIndex++) 
        { 
         XmlNode cell = cells[cellIndex]; 
         if (cell.Attributes["ss:Index"] != null) 
          actualCellIndex = int.Parse(cell.Attributes["ss:Index"].Value) - 1; 

         XmlNode data = cell.SelectSingleNode("ss:Data", nsmgr); 

         if (actualCellIndex >= dt.Columns.Count) 
         { 
          for (int ii = dt.Columns.Count; ii < actualCellIndex; ii++) 
          { 
           //dt.Columns.Add("Column" + actualCellIndex.ToString(), typeof(string)); columns.Add(getDefaultType()); 
           dt.Columns.Add("Column" + actualCellIndex.ToString()); 
           //columns.Add(getDefaultType()); 
          } // ii 
          //ColumnType autoDetectType = getType(cell.SelectSingleNode("ss:Data", nsmgr)); 
          dt.Columns.Add("Column" + actualCellIndex.ToString(), 
              typeof(string)); 
          // columns.Add(autoDetectType); 
         } 
         if (data != null) 
          row[actualCellIndex] = data.InnerText; 

         actualCellIndex++; 
        } 

        dt.Rows.Add(row); 
       } 
      } 
     } 
     return ds; 
    } 

} 
1
public static class XMLtoDataTable 
{ 
    private static ColumnType getDefaultType() 
    { 
     return new ColumnType(typeof(String)); 
    } 

    struct ColumnType 
    { 
     public Type type; 
     private string name; 
     public ColumnType(Type type) { this.type = type; this.name = type.ToString().ToLower(); } 
     public object ParseString(string input) 
     { 
      if (String.IsNullOrEmpty(input)) 
       return DBNull.Value; 
      switch (type.ToString()) 
      { 
       case "system.datetime": 
        return DateTime.Parse(input); 
       case "system.decimal": 
        return decimal.Parse(input); 
       case "system.boolean": 
        return bool.Parse(input); 
       default: 
        return input; 
      } 
     } 
    } 


    private static ColumnType getType(XmlNode data) 
    { 
     string type = null; 
     if (data.Attributes["ss:Type"] == null || data.Attributes["ss:Type"].Value == null) 
      type = ""; 
     else 
      type = data.Attributes["ss:Type"].Value; 

     switch (type) 
     { 
      case "DateTime": 
       return new ColumnType(typeof(DateTime)); 
      case "Boolean": 
       return new ColumnType(typeof(Boolean)); 
      case "Number": 
       return new ColumnType(typeof(Decimal)); 
      case "": 
       decimal test2; 
       if (data == null || String.IsNullOrEmpty(data.InnerText) || decimal.TryParse(data.InnerText, out test2)) 
       { 
        return new ColumnType(typeof(Decimal)); 
       } 
       else 
       { 
        return new ColumnType(typeof(String)); 
       } 
      default://"String" 
       return new ColumnType(typeof(String)); 
     } 
    } 

    public static DataSet ImportExcelXML(string fileName, bool hasHeaders, bool autoDetectColumnType) 
    { 
     StreamReader sr = new StreamReader(fileName); 
     Stream st = (Stream)sr.BaseStream; 
     return ImportExcelXML(st, hasHeaders, autoDetectColumnType); 
    } 

    private static DataSet ImportExcelXML(Stream inputFileStream, bool hasHeaders, bool autoDetectColumnType) 
    { 
     XmlDocument doc = new XmlDocument(); 
     doc.Load(new XmlTextReader(inputFileStream)); 
     XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); 

     nsmgr.AddNamespace("o", "urn:schemas-microsoft-com:office:office"); 
     nsmgr.AddNamespace("x", "urn:schemas-microsoft-com:office:excel"); 
     nsmgr.AddNamespace("ss", "urn:schemas-microsoft-com:office:spreadsheet"); 

     DataSet ds = new DataSet(); 

     foreach (XmlNode node in 
      doc.DocumentElement.SelectNodes("//ss:Worksheet", nsmgr)) 
     { 
      DataTable dt = new DataTable(node.Attributes["ss:Name"].Value); 
      ds.Tables.Add(dt); 
      XmlNodeList rows = node.SelectNodes("ss:Table/ss:Row", nsmgr); 
      if (rows.Count > 0) 
      { 

       //************************* 
       //Add Columns To Table from header row 
       //************************* 
       List<ColumnType> columns = new List<ColumnType>(); 
       int startIndex = 0; 
       if (hasHeaders) 
       { 
        foreach (XmlNode data in rows[0].SelectNodes("ss:Cell/ss:Data", nsmgr)) 
        { 
         columns.Add(new ColumnType(typeof(string)));//default to text 
         dt.Columns.Add(data.InnerText, typeof(string)); 
        } 
        startIndex++; 
       } 
       //************************* 
       //Update Data-Types of columns if Auto-Detecting 
       //************************* 
       if (autoDetectColumnType && rows.Count > 0) 
       { 
        XmlNodeList cells = rows[startIndex].SelectNodes("ss:Cell", nsmgr); 
        int actualCellIndex = 0; 
        for (int cellIndex = 0; cellIndex < cells.Count; cellIndex++) 
        { 
         XmlNode cell = cells[cellIndex]; 
         if (cell.Attributes["ss:Index"] != null) 
          actualCellIndex = 
           int.Parse(cell.Attributes["ss:Index"].Value) - 1; 

         ColumnType autoDetectType = 
          getType(cell.SelectSingleNode("ss:Data", nsmgr)); 

         if (actualCellIndex >= dt.Columns.Count) 
         { 
          dt.Columns.Add("Column" + 
           actualCellIndex.ToString(), autoDetectType.type); 
          columns.Add(autoDetectType); 
         } 
         else 
         { 
          dt.Columns[actualCellIndex].DataType = autoDetectType.type; 
          columns[actualCellIndex] = autoDetectType; 
         } 

         actualCellIndex++; 
        } 
       } 
       //************************* 
       //Load Data 
       //************************* 
       for (int i = startIndex; i < rows.Count; i++) 
       { 
        DataRow row = dt.NewRow(); 
        XmlNodeList cells = rows[i].SelectNodes("ss:Cell", nsmgr); 
        int actualCellIndex = 0; 
        for (int cellIndex = 0; cellIndex < cells.Count; cellIndex++) 
        { 
         XmlNode cell = cells[cellIndex]; 
         if (cell.Attributes["ss:Index"] != null) 
          actualCellIndex = int.Parse(cell.Attributes["ss:Index"].Value) - 1; 

         XmlNode data = cell.SelectSingleNode("ss:Data", nsmgr); 

         if (actualCellIndex >= dt.Columns.Count) 
         { 
          for (int ii = dt.Columns.Count; ii < actualCellIndex; ii++) 
          { 
           dt.Columns.Add("Column" + actualCellIndex.ToString(), typeof(string)); columns.Add(getDefaultType()); 
          } // ii 
          ColumnType autoDetectType = 
           getType(cell.SelectSingleNode("ss:Data", nsmgr)); 
          dt.Columns.Add("Column" + actualCellIndex.ToString(), 
              typeof(string)); 
          columns.Add(autoDetectType); 
         } 
         if (data != null) 
          row[actualCellIndex] = data.InnerText; 

         actualCellIndex++; 
        } 

        dt.Rows.Add(row); 
       } 
      } 
     } 
     return ds; 
    } 


}