【问题标题】:OpenXML get sheet name from WorksheetOpenXML 从 Worksheet 获取工作表名称
【发布时间】:2014-10-31 06:09:51
【问题描述】:

我正在像这样迭代我的工作表

WorkbookPart wbPart = doc.WorkbookPart;
SharedStringTablePart sstPart = wbPart.GetPartsOfType<SharedStringTablePart>().First();
SharedStringTable sst = sstPart.SharedStringTable;

foreach (var wsp in wbPart.WorksheetParts)
{
    Worksheet ws = wsp.Worksheet;

    // i want to do something like this
    if (ws.Name == "People_Sheet")
    {

    }
}

我需要知道我正在处理哪张工作表,以便以不同的方式处理它。如何获取工作表的名称(当我从这里在 excel 中打开它时显示)?

如果我得到一个工作表列表,我可以通过属性找到它

doc.WorkbookPart.Workbook.Sheets.ToList().ForEach(x => Console.WriteLine(x.GetAttribute("name", "").Value));

但是工作表和工作表之间的关系是什么?如何从工作表中获取相应的工作表或工作表名称?

更新:

所以我确实找到并尝试了这个How to retrieve Tab names from excel sheet using OpenXML

但是 sheetName 与工作表不匹配。

 foreach (var wsp in wbPart.WorksheetParts)
 {
      Worksheet worksheet = wsp.Worksheet;
      var sheetName = wbPart.Workbook.Descendants<Sheet>().ElementAt(sheetIndex).Name;
      var rows = worksheet.Descendants<Row>();
      ...
 }

从工作表返回的行与 sheetName 指示的工作表中的行不对应。让我再解释一下

我的 Excel 文档中有三个工作表 - 人员、企业、产品(按此顺序)

在该循环的第一次迭代中 - 我从工作表行获得的数据是指产品表数据,但 sheetName 显示“人员”

【问题讨论】:

  • 我将更新我的原始答案以回复该评论。
  • 我强烈建议不要使用 Open XML。它很慢而且 api 很糟糕。看看 EPPplus 项目,我发现它更适合处理 Excel。 epplus.codeplex.com
  • @Steve - 这是 2022 年。您关于开放 XML 糟糕的评论仍然有效。如果您尝试将此 api 用于一个一次性的 excel 项目,那么您将疯狂地试图跟踪什么是什么。他们可能出于某种原因过度设计了这个 api。我只是希望有人能提供一个抽象所有细节的包装器。不幸的是,EPPlus 不再是一个开源项目。您必须获得许可才能用于商业用途。

标签: c# openxml openxml-sdk


【解决方案1】:

该帖子错误地假设WorkbookPart.WorksheetPartsWorkbook.Sheets 集合中的索引是一致的。应该寻找的匹配是关系 id,因为这是包部分通信的范例。

代替:

var workbook = doc.WorkbookPart.Workbook;
workbook.Sheets.ToList().ForEach(x => Console.WriteLine(x.GetAttribute("name", "").Value));

可以将OpenXmlCompositeElement 转换为它的集合组件类型:

var sheets = workbook.Sheets.Cast<Sheet>().ToList();
sheets.ForEach(x => Console.WriteLine(
      String.Format("RelationshipId:{0}\n SheetName:{1}\n SheetId:{2}"
      , x.Id.Value, x.Name.Value, x.SheetId.Value)));

然后在遍历parts时,找到当前part的relationship id,并匹配Sheet.Id(作为OpenXmlLeafElement):

foreach (var w in doc.WorkbookPart.WorksheetParts)
{
    string partRelationshipId = doc.WorkbookPart.GetIdOfPart(w);
    var correspondingSheet = sheets.FirstOrDefault(
        s => s.Id.HasValue && s.Id.Value == partRelationshipId);
    Debug.Assert(correspondingSheet != null); 
}

也可以反向连接,从id中获取对象:

public OpenXmlPart OpenXmlContainer.GetPartById (string id);  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多