如何使用OpenXML从Excel表格中检索选项卡名称

我有一个电子表格文件,其中有182列。 我需要将电子表格数据放入一个数据表中,但是我需要从每个选项卡添加数据,选项卡名称是什么,并将选项卡名称添加到数据表中的列。

这是我如何设置数据表。

然后,我在工作簿中循环,深入到sheetData对象,遍历每一行和每列,获取单元格数据。

 DataTable dt = new DataTable(); for (int i = 0; i <= col.GetUpperBound(0); i++) { try { dt.Columns.Add(new DataColumn(col[i].ToString(), typeof(string))); } catch (Exception e) { MessageBox.Show("Uploader Error" + e.ToString()); return null; } } dt.Columns.Add(new DataColumn("SheetName", typeof(string))); 

然而,在我用于数据表的string数组的末尾,我需要添加标签名称。 如何在Open XML表单中循环查找标签名称?

这是我的代码到目前为止:

 using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(Destination, false)) { WorkbookPart workbookPart = spreadSheetDocument.WorkbookPart; Workbook workbook = spreadSheetDocument.WorkbookPart.Workbook; Sheets sheets = spreadSheetDocument .WorkbookPart .Workbook .GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>(); OpenXmlElementList list = sheets.ChildElements; foreach (WorksheetPart worksheetpart in workbook.WorkbookPart.WorksheetParts) { Worksheet worksheet = worksheetpart.Worksheet; foreach (SheetData sheetData in worksheet.Elements<SheetData>()) { foreach (Row row in sheetData.Elements()) { string[] thisarr = new string[183]; int index = 0; foreach (Cell cell in row.Elements()) { thisarr[(index)] = GetCellValue(spreadSheetDocument, cell); index++; } thisarr[182] = ""; //need to add tabname here if (thisarr[0].ToString() != "") { dt.Rows.Add(thisarr); } } } } } return dt; 

只需要注意一点:我之前从“list”的InnerXML属性中获取了选项卡名称

 OpenXmlElementList list = sheets.ChildElements; 

但我注意到,因为我循环在电子表格中没有得到正确的顺序标签名称。

工作表名称存储在WorkbookPart中的Sheets元素中,该元素具有与Excel文件中的每个工作表相对应的元素Sheet子元素。 你所要做的就是从Sheets元素中获取正确的索引,这就是你循环中的工作表。 我在下面加了一段代码来做你想做的事情。

 int sheetIndex = 0; foreach (WorksheetPart worksheetpart in workbook.WorkbookPart.WorksheetParts) { Worksheet worksheet = worksheetpart.Worksheet; // Grab the sheet name each time through your loop string sheetName = workbookPart.Workbook.Descendants<Sheet>().ElementAt(sheetIndex).Name; foreach (SheetData sheetData in worksheet.Elements<SheetData>()) { ... } sheetIndex++; } 

下面是一个方便的帮助器方法来获取对应于WorksheetPart的工作表:

 public static Sheet GetSheetFromWorkSheet (WorkbookPart workbookPart, WorksheetPart worksheetPart) { string relationshipId = workbookPart.GetIdOfPart(worksheetPart); IEnumerable<Sheet> sheets = workbookPart.Workbook.Sheets.Elements<Sheet>(); return sheets.FirstOrDefault(s => s.Id.HasValue && s.Id.Value == relationshipId); } 

那么你可以从床单上得到名字Name-property:

 Sheet sheet = GetSheetFromWorkSheet(myWorkbookPart, myWorksheetPart); string sheetName = sheet.Name; 

…这将是OP提到的“标签名称”。


为了logging,相反的方法将如下所示:

 public static Worksheet GetWorkSheetFromSheet(WorkbookPart workbookPart, Sheet sheet) { var worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id); return worksheetPart.Worksheet; } 

…和我们也可以添加以下方法:

 public static IEnumerable<KeyValuePair<string, Worksheet>> GetNamedWorksheets (WorkbookPart workbookPart) { return workbookPart.Workbook.Sheets.Elements<Sheet>() .Select(sheet => new KeyValuePair<string, Worksheet> (sheet.Name, GetWorkSheetFromSheet(workbookPart, sheet))); } 

现在,您可以轻松地枚举所有工作表,包括他们的名字。

把它全部放到一个字典中,以便进行基于名称的查找,如果你喜欢:

 IDictionary<string, WorkSheet> wsDict = GetNamedWorksheets(myWorkbookPart) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); 

…或者如果你只想要一个具体的名单:

 public static Sheet GetSheetFromName(WorkbookPart workbookPart, string sheetName) { return workbookPart.Workbook.Sheets.Elements<Sheet>() .FirstOrDefault(s => s.Name.HasValue && s.Name.Value == sheetName); } 

(然后调用GetWorkSheetFromSheet获取相应的工作表。)

  Using spreadsheetDocument As SpreadsheetDocument = spreadsheetDocument.Open("D:\Libro1.xlsx", True) Dim workbookPart As WorkbookPart = spreadsheetDocument.WorkbookPart workbookPart.Workbook.Descendants(Of Sheet)() Dim worksheetPart As WorksheetPart = workbookPart.WorksheetParts.Last Dim text As String For Each Sheet As Sheet In spreadsheetDocument.WorkbookPart.Workbook.Sheets Dim sName As String = Sheet.Name Dim sID As String = Sheet.Id Dim part As WorksheetPart = workbookPart.GetPartById(sID) Dim actualSheet As Worksheet = part.Worksheet Dim sheetData As SheetData = part.Worksheet.Elements(Of SheetData)().First For Each r As Row In sheetData.Elements(Of Row)() For Each c As Cell In r.Elements(Of Cell)() text = c.CellValue.Text Console.Write(text & " ") Next Next Next End Using Console.Read() 
 worksheet.GetAttribute("name","").Value