【问题标题】:Reading Excel Spreadsheet with C#, unequal Column/Values使用 C# 读取 Excel 电子表格,不相等的列/值
【发布时间】:2013-02-15 08:48:10
【问题描述】:

我有一个作为 XML 格式的 Excel 电子表格输出,其列定义如下:

   <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);
      }

【问题讨论】:

  • 行中的第五个单元格是空白的,您可以看出它确实有一个结束标记/&gt;
  • 但是最后两列也不见了,systemid和prohibit。它是否只空白显示在中间的标签?我还有其他带有结束标记的工作表,它们最后显示。
  • 已经有一段时间了(大约 2 年前,我使用 Excel 作为 XML)。我认为如果 XML 为空白,则 XML 不会包含最后两列,以最小化 XML 文件的大小。但是我们可以看到它确实在中间包含空白单元格。
  • 这是有道理的,但是同一本 excel 书中的所有其他工作表都有空白标签作为结束元素,如果它们是空的。它们都有匹配的列/行。无论哪种情况,你知道如何使用上面的代码并处理那个空的中间标签吗?

标签: c# xml excel xml-parsing


【解决方案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);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    相关资源
    最近更新 更多