2013-02-14 56 views
1

我有一個Excel電子表格輸出格式爲XML定義爲這樣的列:閱讀Excel電子表格使用C#,不等列/值

<Row ss:AutoFitHeight="0"> 
     <Cell ss:StyleID="ColumnHead"> 
      <ss:Data ss:Type="String">#</ss:Data> 
     </Cell> 
     <Cell ss:StyleID="ColumnHead"> 
      <ss:Data ss:Type="String">prefix</ss:Data> 
     </Cell> 
     <Cell ss:StyleID="ColumnHead"> 
      <ss:Data ss:Type="String">name</ss:Data> 
     </Cell> 
     <Cell ss:StyleID="ColumnHead"> 
      <ss:Data ss:Type="String">label</ss:Data> 
     </Cell> 
     <Cell ss:StyleID="ColumnHead"> 
      <ss:Data ss:Type="String">totalLabel</ss:Data> 
     </Cell> 
     <Cell ss:StyleID="ColumnHead"> 
      <ss:Data ss:Type="String">base schema</ss:Data> 
     </Cell> 
     <Cell ss:StyleID="ColumnHead"> 
      <ss:Data ss:Type="String">systemid</ss:Data> 
     </Cell> 
     <Cell ss:StyleID="ColumnHead"> 
      <ss:Data ss:Type="String">prohibit</ss:Data> 
     </Cell> 
     </Row> 

這裏是一個例子一行:

<Row ss:AutoFitHeight="0"> 
     <Cell ss:StyleID="NoBorderNumberCell"> 
      <ss:Data ss:Type="Number">1</ss:Data> 
     </Cell> 
     <Cell ss:StyleID="NoBorderCell"> 
      <ss:Data ss:Type="String">ifrs</ss:Data> 
     </Cell> 
     <Cell ss:StyleID="NoBorderCell"> 
      <ss:Data ss:Type="String">AccountingProfit</ss:Data> 
     </Cell> 
     <Cell ss:StyleID="NoBorderCell"> 
      <ss:Data ss:Type="String">Accounting profit</ss:Data> 
     </Cell> 
     <Cell ss:StyleID="NoBorderCell"/> 
     <Cell ss:StyleID="NoBorderCell"> 
      <ss:Data ss:Type="String">full_entry_point</ss:Data> 
     </Cell> 
     </Row> 

的問題是,我如何檢測哪些單元丟失了哪些列?是否需要源對於所有空單元格都有一個空白自閉標記,以便我能夠每次將每列與每個值配對?

我該如何管理C#中的這種情況?我擁有最低限度的權利,不知道如何將其分開以彌補缺失的列。

if (reader.Name == "ss:Data") 
     {          

      while (reader.Read()) 
       Response.Write(reader.Value); 
     } 
+0

排在第五單元是空白的,你可以告訴,因爲它確實有一個結束標記'/>' – 2013-02-15 00:07:07

+0

但最後兩列也下落不明,systemid和禁止。它是否只是將顯示在中間的標籤剔除?我還有其他結束標籤顯示的工作表。 – 2013-02-15 00:10:00

+0

它一直是(大約2年前,我用Excel作爲XML工作)。我想如果XML是空白的,爲了最小化XML文件的大小,XML不會包含最後兩列。但是我們可以看到它的中間包含空白單元格。 – 2013-02-15 00:28:39

回答

1

您可以使用LinqToExcel來讀取數據,它應該更快,因爲它不必加載整個文件。但是,LinqToExcel使用OLEDB來讀取文件而不是Open XML SDK。

var excel = new ExcelQueryFactory("excelFileName"); 
var firstRow = (from c in excel.Worksheet() 
       select c).First(); 

請參閱documentation for LinqToExcel的其餘部分。

否則,你可以使用LINQ做到這一點:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using NUnit.Framework; 
using System.Xml.Linq; 

namespace UnitTest 
{ 
    [TestFixture] 
    public class TestCode 
    { 
     [Test] 
     public void ReadExcelCellTest() 
     { 
      XDocument document = XDocument.Load(@"C:\TheFile.xml"); 
      XNamespace workbookNameSpace = @"urn:schemas-microsoft-com:office:spreadsheet"; 

      // Get worksheet 
      var query = from w in document.Elements(workbookNameSpace + "Workbook").Elements(workbookNameSpace + "Worksheet") 
         where w.Attribute(workbookNameSpace + "Name").Value.Equals("Settings") 
         select w; 
      List<XElement> foundWoksheets = query.ToList<XElement>(); 
      if (foundWoksheets.Count() <= 0) { throw new ApplicationException("Worksheet Settings could not be found"); } 
      XElement worksheet = query.ToList<XElement>()[0]; 

      // Get the row for "Seat" 
      query = from d in worksheet.Elements(workbookNameSpace + "Table").Elements(workbookNameSpace + "Row").Elements(workbookNameSpace + "Cell").Elements(workbookNameSpace + "Data") 
        where d.Value.Equals("Seat") 
        select d; 
      List<XElement> foundData = query.ToList<XElement>(); 
      if (foundData.Count() <= 0) { throw new ApplicationException("Row 'Seat' could not be found"); } 
      XElement row = query.ToList<XElement>()[0].Parent.Parent; 

      // Get value cell of Etl_SPIImportLocation_ImportPath setting 
      XElement cell = row.Elements().ToList<XElement>()[1]; 

      // Get the value "Leon" 
      string cellValue = cell.Elements(workbookNameSpace + "Data").ToList<XElement>()[0].Value; 

      Console.WriteLine(cellValue); 
     } 
    } 
}