2017-07-07 68 views
0

我正在使用以下代碼將Excel數據從剪貼板讀取到C#數據表格中。代碼相對不變,從this answerthis question。然後將數據表作爲數據源添加到DataGridView控件中進行操作。將數據從剪貼板讀入DataTable時保留空的Excel單元格

但是,在我的Excel數據中,我有空白/空單元格,我需要保留,這段代碼沒有做(空白單元格跳過,有效地壓縮每一行,沒有空的空間;缺少空單元格來自Excel XML)。傳輸到數據表時,如何保留空單元格?

方法:

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

擴展方法:

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

人爲的例子來說明:(Excel的2015)在Excel

範圍,複製到剪貼板

Range in Excel, copied to clipboard

的DataGridView在WinForm的,以數據表作爲數據源 Data table in VS

回答

1

細胞的XML將有一個索引屬性,如果前一小區失蹤(有一個空值)。您可以更新您的代碼,以便在將列索引複製到數據表格行之前檢查列索引是否已更改。

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

謝謝,這個伎倆! – natedogg