您的位置:首页 > 大数据

OpenXml To Excel之写大数据

2013-03-29 11:15 537 查看
之前讲过用OpenXml填充数据,那种方法对于数据量小的场景运行的很好,遇到大数据那种方法填充文档会非常的慢,比如你有50个column,1000行

你会发现前面的方法不能胜任。

网上有牛人提供了用OpenXml写大数据的解决方案,通过这里可以查看原文.附有源码

由于原文中的代码很多,不容易阅读,本人对代码进行了精简,改写成自己喜欢的格式。

实现方式将Excel当做xml来操作,运用linq to xml来进行读写

前面我们说过Excel中的数据存储在sheetData中,而sheetData就是xml文件中的节点,所以我们只要对这个节点进行读写即可。

实现步骤

1.根据sheetName获取指定的sheet,并转化成xml对象

using (SpreadsheetDocument sDoc = SpreadsheetDocument.Open(fileName, true))
{
WorkbookPart workbookPart = sDoc.WorkbookPart;
IEnumerable<DocumentFormat.OpenXml.Spreadsheet.Sheet> sheets = workbookPart.Workbook.Descendants<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Where(s => s.Name == workbook.Worksheets.First().Name);
WorksheetPart worksheetPart = (WorksheetPart)sDoc.WorkbookPart.GetPartById(sheets.First().Id);
XDocument wXDoc = worksheetPart.GetXDocument();
........
}


2.查找sheetData节点

XElement sheetElement = wXDoc.Root.Elements().Where(e => e.Name.LocalName == "sheetData").First();




通过截图我们发现数据的存储规律,sheetData的子节点其实就是row,row包含若干cell element.

知道这个规律我们就可以很方便的去操作它了,只要按照它的格式来构造一个Row,然后把这个Row加入到sheetData中

3.构造Row,并填充数据

private static void SerializeRow(XElement sheetElement, int rowCount, Row row)
{
XNamespace ns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
XElement xR = new XElement(ns + "row",
new XAttribute("r", rowCount),
new XAttribute("spans", "1:" + row.Cells.Count().ToString()));
int cellCount = 0;
foreach (var cell in row.Cells)
{
if (cell != null)
{

XAttribute xa;
switch (cell.CellDataType)
{
case CellDataType.Boolean:
xa = new XAttribute("t", "b");
break;
case CellDataType.Date:
xa = new XAttribute("t", "d");
break;
case CellDataType.Number:
xa = new XAttribute("t", "n");
break;
case CellDataType.String:
xa = new XAttribute("t", "str");
break;
default:
xa = new XAttribute("t", "str");
break;
}
XElement xC;
if (cell.Value != null)
{
XElement xV = new XElement(ns + "v", cell.Value);
xC = new XElement(ns + "c",
new XAttribute("r", SpreadsheetMLUtil.IntToColumnId(cellCount) + rowCount.ToString()),
xa, xV);
}
else
{
XElement xV = new XElement(ns + "v", cell.Value);
xC = new XElement(ns + "c",
new XAttribute("r", SpreadsheetMLUtil.IntToColumnId(cellCount) + rowCount.ToString()),
xa);
}
xR.Add(xC);
}
cellCount++;
}
sheetElement.Add(xR);
}


4.保存sheetElement

worksheetPart.PutXDocument();
workbookPart.Workbook.Save();


通过这种方法,你会发现写数据的效率指数级的上升。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: