2017-07-07 5 views
0

Ich verwende den folgenden Code, um Excel-Daten aus der Zwischenablage in eine C# -Datentabelle zu lesen. Der Code ist relativ unverändert wie er von this answer bis this question gefunden wurde. Ich füge dann die Datentabelle als Datenquelle zu einem DataGridView-Steuerelement für die Bearbeitung hinzu. In meinen Excel-Daten habe ich leere/leere Zellen, die ich beibehalten muss, was dieser Code nicht tut (leere Zellen werden übersprungen, jede Zeile wird effektiv komprimiert, es bleibt kein leerer Platz übrig; die leeren Zellen fehlen.) aus dem Excel-XML). Wie kann ich leere Zellen bei der Übertragung in die Datentabelle erhalten?Leere Excel-Zellen beibehalten beim Lesen von Daten aus der Zwischenablage in DataTable

Methode:

private DataTable ParseClipboardData(bool blnFirstRowHasHeader) 
    { 
     var clipboard = Clipboard.GetDataObject(); 
     if (!clipboard.GetDataPresent("XML Spreadsheet")) return null; 
     StreamReader streamReader = new StreamReader((MemoryStream)clipboard.GetData("XML Spreadsheet")); 
     streamReader.BaseStream.SetLength(streamReader.BaseStream.Length - 1); 

     XmlDocument xmlDocument = new XmlDocument(); 
     xmlDocument.LoadXml(streamReader.ReadToEnd()); 
     XNamespace ssNs = "urn:schemas-microsoft-com:office:spreadsheet"; 
     DataTable dt = new DataTable(); 

     var linqRows = xmlDocument.fwToXDocument().Descendants(ssNs + "Row").ToList<XElement>(); 
     for (int x = 0; x < linqRows.Max(a => a.Descendants(ssNs + "Cell").Count()); x++) 
      dt.Columns.Add("Column " + x.ToString()); 

     int intCol = 0; 
     DataRow currentRow; 

     linqRows.ForEach(rowElement => 
     { 
      intCol = 0; 
      currentRow = dt.Rows.Add(); 
      rowElement.Descendants(ssNs + "Cell") 
       .ToList<XElement>() 
       .ForEach(cell => currentRow[intCol++] = cell.Value); 
     }); 

     if (blnFirstRowHasHeader) 
     { 
      int x = 0; 
      foreach (DataColumn dcCurrent in dt.Columns) 
       dcCurrent.ColumnName = dt.Rows[0][x++].ToString(); 

      dt.Rows.RemoveAt(0); 
     } 

     return dt; 
    } 

Erweiterungsmethode:

public static XDocument fwToXDocument(this XmlDocument xmlDocument) 
{ 
    using (XmlNodeReader xmlNodeReader = new XmlNodeReader(xmlDocument)) 
    { 
     xmlNodeReader.MoveToContent(); 
     var doc = XDocument.Load(xmlNodeReader); 
     return doc; 
    } 
} 

konstruiertes Beispiel zu veranschaulichen: (Excel 2015)

Bereich in Excel, die Zwischenablage kopiert

Range in Excel, copied to clipboard

Datagridview auf Winform, mit Datentabelle als Datenquelle Data table in VS

Antwort

1

die XML-Zelle wird ein Index-Attribut, wenn die vorherige Zelle fehlt (hatte einen leeren Wert). Sie können Ihren Code aktualisieren, um zu prüfen, ob der Spaltenindex geändert wurde, bevor Sie ihn in Ihre Datentabellenzeile kopieren.

linqRows.ForEach(rowElement => 
{ 
    intCol = 0; 
    currentRow = dt.Rows.Add(); 
    rowElement.Descendants(ssNs + "Cell") 
     .ToList<XElement>()      
     .ForEach(cell => 
     { 
      int cellIndex = 0; 
      XAttribute indexAttribute = cell.Attribute(ssNs + "Index"); 

      if (indexAttribute != null) 
      { 
       Int32.TryParse(indexAttribute.Value, out cellIndex); 
       intCol = cellIndex - 1; 
      } 

      currentRow[intCol] = cell.Value; 
      intCol++; 
     }); 
}); 
+0

Danke, das hat den Trick! – natedogg

Verwandte Themen