[英]C# OPEN XML: empty cells are getting skipped while getting data from EXCEL to DATATABLE
[英]Preserve empty Excel cells when reading data from clipboard into DataTable
我正在使用以下代碼將Excel數據從剪貼板讀取到C#數據表中。 從此問題的 答案可以發現,代碼相對不變。 然后,我將數據表作為數據源添加到DataGridView控件中進行操作。
但是,在我的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中的范圍,復制到剪貼板
如果前一個單元格丟失(具有空值),則該單元格的xml將具有Index屬性。 您可以更新代碼以檢查列索引是否已更改,然后再將其復制到數據表行中。
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++;
});
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.