2011-09-21 30 views
9

kullanarak excel sayfasından Sekme adları nasıl alınır. Elektronik tablo verilerini bir veri tablosuna, sekmeye göre yerleştirmem gerekiyor, ancak her sekmeden veri eklediğimi, sekme adının ne olduğunu ve sekme adını veri tablosundaki bir sütuna eklediğimi bulmam gerekiyor . İçinde 182 sütun vardır bir tablo belge var openxml

Bu

ben veri tablosunu kurmak nasıl.

Sonra çalışma kitabındaki döngü ve sheetData nesneye detaya ve hücre verilerini alma, her satır ve sütunun içinden yürümek.

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

Ancak veriler Tablo için kullanılacak dize dizinin sonunda, ben sekme adı eklemem gerekiyor. Açık XML'de sayfada döngü yaptığım gibi sekme adını nasıl bulabilirim?

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; 

Sadece bir not: Burada

benim şimdiye kadar kodudur daha önce ancak ben gibi fark

OpenXmlElementList list = sheets.ChildElements; 

yılında "liste" nin InnerXml özelliğinden sekme isimleri aldın E-tablodaki döngü, sekme adlarını doğru sırada almaz.

+0

http://msdn.microsoft.com/en-us/library/bb507946. aspx –

+0

sadece ben sekme isimleri dışarı çekmek istiyorum eğer gayet iyi çalışıyor .. Inner/dış xml ayrıştırma yapabilirsiniz .. ama ben kendi For döngüsü içinde yapmak istiyorum .. Ben Sheet erişmekte sorun yaşıyorum SheetData seviyesinde iken .. – Kwalke001

+0

Adını almak için "çalışma sayfası" nesnesinde çalışamazsınız? Bu sayfadaki son kod örneği, bir sayfanın özniteliklerine rağmen nasıl döngü yapılacağını gösterir: muhtemelen sayfa adı bu özelliklerden biridir (kendimi hiç deneyimim yoktur). –

cevap

15

sac isimleri Excel dosyasındaki her çalışma sayfasına gelen öğe Sheet çocukları olan bir Sheets elemanda WorkbookPart saklanır. Tek yapmanız gereken, Sheets öğesinden doğru dizini yakalamanızdır ve bu, döngünüzde olduğunuz Sheet olacaktır. İstediğinizi yapmak için aşağıdan bir kod snippet'i ekledim.

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

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

Sonra yaprak İsim-mülk adını alabilirsiniz: Burada

+0

mükemmel bir çözümdü. Teşekkür ederim amurra! – Kwalke001

+3

Deneyimlerimden, kod snippet'inizi kullanarak, sheetName sayfa isimlerini doğru sırada (dosyada oldukları gibi) okur, ancak sheetData, Excel dosyasında olduğu gibi aynı sırada okunmaz. Sonuç olarak, kod tüm sayfalar için karışık adlarla sonuçlanır. – Skull

+2

Sorun, e-tablo adları ve bazı rasgele sırada depolanan elektronik tablo içeriğine başvuruları olan "excel_file.xlsx \ xl \ _rels \ workbook.xml.rels" dosyasından geliyor. Bunları manuel olarak 1'den N'ye (Id = "rId1", Id = "rId2", ..., Id = "rIdN") yeniden düzenlerseniz, e-tablo adları dosyayı okuduktan sonra içeriğiyle hizalar. Kodda bu sorunu nasıl ele alacağımı bilmiyorum. – Skull

0
worksheet.GetAttribute("name","").Value 
4
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() 
bir WorksheetPart tekabül Sheet almak için kullanışlı bir yardımcı yöntemdir

... bu, atıfta bulunulan "sekme adı" olacaktır.


Kayıt için karşıt yöntem gibi görünecektir:

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

... ve bununla biz de aşağıdaki yöntemi ekleyebilirsiniz:

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

Şimdi kolaylıkla numaralandırabilmesidir adlarını da içeren tüm çalışma sayfalarında.

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

...: isme dayalı arama için bir sözlüğüne

Atma hepsini İstersenizyoksa sadece ismen belirli bir levha istiyorsanız:

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

(Sonra gelen çalışma sayfası almak için GetWorkSheetFromSheet arayın.)

+2

Yöntemin kodun yanı sıra neden işlediğine dair bir tartışma ekleyebilirseniz harika olur. – ASGM

+0

Bu şekilde, adla sayfa aradıkça, bu sayfanın kimliğini aldığınızda ve sonra da adı temel alan çalışma sayfası aldığınızda (linq kullanarak, döngülemeniz gerekmediği anlamına gelir) . Yanıt olarak işaretlenen yanıt, istediğiniz şeyi bulana kadar döngü gerektiren bir dizin kullanır. – wavydavy

21

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++; 
} 
+2

Bu doğru çözüm olmalı. –

+0

Parlak .. Teşekkürler! – Jason