2017-03-03 3 views
1

Ich habe versucht, XML-Daten in Excel zu importieren, indem ich ein XML-Mapping in OpenXML SDK verwende.XML mit XML-Mapping in OpenXML importieren

Ich habe mehrere Beispiele gefunden, dies mit Excel Interop zu tun, aber nicht mit dem SDK. Als eine Nebenbemerkung habe ich dies für Word-Dateien arbeiten, aber die Prozedur ist in Excel nicht identisch (CustomXmlPart in Word, CustomXmlMappingPart in Excel).

Vielleicht ist es einfach nicht möglich, das SDK direkt zu verwenden. Eine Problemumgehung könnte die Verwendung von benannten Bereichen sein, aber das finde ich weniger praktisch.

Bearbeiten: Das Szenario verwendet eine Excel-Datei mit einem XML-Mapping (erstellt wie beschrieben https://support.office.com/en-us/article/Import-XML-data-6eca3906-d6c9-4f0d-b911-c736da817fa4?ui=en-US&rs=en-US&ad=US) als "Vorlage", um mit Daten zu füllen. Das könnte Kundenname, aktuelles Datum oder ähnliches sein.

Ich habe etwas ähnliches versucht. Im Gegensatz zu Word wird das Mapping in einem CustomXmlMappingsPart angezeigt.

using (var fileStream = File.Open(@"c:\temp\test.xslx", FileMode.Open)) 
{ 
    SpreadsheetDocument excelDoc = SpreadsheetDocument.Open(fileStream, true); 
    // Only one mapping 
    // When doing this for word, there is a document.MainDocumentPart.CustomXmlParts 
    var mapping = excelDoc.WorkbookPart.GetPartsOfType<CustomXmlMappingsPart>().FirstOrDefault(); 
    XNamespace mappingNS = "http://demoimport.org/xmlimport"; 
    var xmlData = new XElement(mappingNS + "ImportRoot", 
           new XElement(mappingNS + "Customer", "Test Customer Name")); 

    XmlReader reader = xmlData.CreateReader(); 
    reader.MoveToContent(); 

    using (MemoryStream ms = new MemoryStream()) 
    { 
     xmlData.Save(ms); 
     ms.Position = 0; 
     // Corrupts the file 
     // Probably due to CustomXmlMappingsPart 
     mapping.FeedData(ms); 
    } 
} 
+1

Bitte können Sie zeigen, was Sie versucht haben und was nicht funktioniert haben und dann eine bestimmte Frage stellen. Es ist sehr schwierig, genau zu verstehen, was Sie erreichen wollen. Vielen Dank. –

+0

Danke, ich habe den Beitrag mit ein bisschen mehr Kontext bearbeitet – Adrian

Antwort

1

Haftungsausschluss - ich habe keine Ahnung, ob der der ist Weg dies zu tun, aber die folgenden Werke für meinen begrenzten Anwendungsfall

Statt direkt mit XML-Mapping-Teilen des Arbeits (CustomXmlMappingsPart), Mithilfe des Open XML Productivity Tools habe ich festgestellt, dass die zugeordneten Zellen XPath für das Mapping in einer Sammlung von SingleCellTablePart enthalten.

Es ist möglich, alle SingleCellTablePart zu durchlaufen, um ein übereinstimmendes Element in der XML-Datei zu finden. Ich fand eine wirklich nützliche Erweiterungen von https://simpleooxml.codeplex.com/, um Daten in das Dokument zu schreiben. Es ist perfekt möglich, nur mit dem OpenXML SDK zu erreichen. Aber ich fand Einstellungszellenwerte mit dem SDK ist nicht so trivial wie man denken würde.

using (var fileStream = File.Open(@"c:\temp\test.xlsx", FileMode.Open)) 
{ 
    /* Simple xml-file, 
    * <General> 
    * <Customer>Demo Customer</Customer> 
    * </General> 
    */ 
    XDocument doc = XDocument.Load(@"c:\temp\demodata.xml"); 

    SpreadsheetDocument excelDoc = SpreadsheetDocument.Open(fileStream, true); 

    foreach (var workSheet in excelDoc.WorkbookPart.WorksheetParts) 
    { 
     // Note, multiple mappings could exist. For simplicity I expect only one 
     var mappings = workSheet.GetPartsOfType<SingleCellTablePart>().FirstOrDefault(); 
     if (mappings == null) 
      continue; 

     foreach (SingleXmlCell cellMapping in mappings.SingleXmlCells) 
     { 
      if (cellMapping.XmlCellProperties != null && 
       cellMapping.XmlCellProperties.XmlProperties != null) 
      { 
       // cellMapping.XmlCellProperties.XmlProperties.XPath = /General/Customer 
       var matchingNode = doc.XPathSelectElement(cellMapping.XmlCellProperties.XmlProperties.XPath); 
       if(matchingNode != null && !string.IsNullOrEmpty(matchingNode.Value)) 
       { 
        // If a maching node exist, set text value from XML-file 
        // SpreadsheetReader and WorksheetWriter from https://simpleooxml.codeplex.com/ 
        string column = SpreadsheetReader.ColumnFromReference(cellMapping.CellReference.Value); 
        uint row = SpreadsheetReader.RowFromReference(cellMapping.CellReference.Value); 
        WorksheetWriter.PasteText(excelDoc, workSheet, column, row, matchingNode.Value); 
       } 
      } 
     } 
     WorksheetWriter.Save(excelDoc, workSheet); 
    } 
}