阅读Excel电子表格使用C#,不等列/值

问题描述:

我有一个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

您可以使用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); 
     } 
    } 
}