C# 用于导出100K+;要快速超越的行
我一直在努力提高SAX方法写入xlsx的性能。我知道Excel中有1048576行的限制。我只有几次达到这个极限。但在大多数情况下,我只写出大约125K到250K行(一个大数据集)。我尝试过的代码似乎没有它可能的那么快,因为它会写入文件很多次。我希望有一些缓存参与,但它仍然似乎有太多的磁盘访问方式的代码现在工作 下面的代码与类似,因为我已经使用ClosedXML写入了一个文件,然后切换到SAX来处理大型内容。当尝试对这么多行使用ClosedXML时,内存会出现问题。这就是我使用SAX的原因C# 用于导出100K+;要快速超越的行,c#,xml,excel,openxml,sax,C#,Xml,Excel,Openxml,Sax,我一直在努力提高SAX方法写入xlsx的性能。我知道Excel中有1048576行的限制。我只有几次达到这个极限。但在大多数情况下,我只写出大约125K到250K行(一个大数据集)。我尝试过的代码似乎没有它可能的那么快,因为它会写入文件很多次。我希望有一些缓存参与,但它仍然似乎有太多的磁盘访问方式的代码现在工作 下面的代码与类似,因为我已经使用ClosedXML写入了一个文件,然后切换到SAX来处理大型内容。当尝试对这么多行使用ClosedXML时,内存会出现问题。这就是我使用SAX的原因
int numCols = dt.Columns.Count;
int rowCnt = 0;
//for (curRec = 0; curRec < totalRecs; curRec++)
foreach (DataRow row in dt.Rows)
{
Row xlr = new Row();
//starting of new row.
//writer.WriteStartElement(xlr);
for (int col = 0; col < numCols; ++col)
{
Cell cell = new Cell();
CellValue v = new CellValue(row[col].ToString());
{
string objDataType = row[col].GetType().ToString();
if (objDataType.Contains(TypeCode.Int32.ToString()) || objDataType.Contains(TypeCode.Int64.ToString()))
{
cell.DataType = new EnumValue<CellValues>(CellValues.Number);
//cell.CellValue = new CellValue(row[col].ToString());
cell.Append(v);
}
else if (objDataType.Contains(TypeCode.Decimal.ToString()) || objDataType.Contains("Single"))
{
cell.DataType = new EnumValue<CellValues>(CellValues.Number);
cell.Append(v);
//TODO: set the decimal qualifier - May be fixed elsewhere
cell.StyleIndex = 2;
}
else
{
//Add text to text cell
cell.DataType = new EnumValue<CellValues>(CellValues.String);
cell.Append(v);
}
}
if (colStyles != null && col < colStyles.Count)
{
cell.StyleIndex = (UInt32Value)colStyles[col];
}
//writer.WriteElement(cell);
xlr.Append(cell);
}
writer.WriteElement(xlr);
//end row element
//writer.WriteEndElement();
++rowCnt;
}
int numCols=dt.Columns.Count;
int rowCnt=0;
//对于(curRec=0;curRec
这段代码与我在那里看到的示例非常接近。但问题是它仍然相当缓慢。从单个单元格写入更改为追加到行并写入行似乎可以在125K行上将该过程改进10%
有没有人找到一种方法来改进编写器或设置一种方法来减少编写次数?有没有方法可以加快这个过程
有人尝试过设置某种形式的缓存来提高性能吗?一般的问题是不应该将DOM和SAX方法混合在一起。一旦混合使用它们,性能就类似于只使用DOM。当您全力以赴时,SAX的性能优势就会显现出来。首先回答您的问题: 是否有人找到了改进编写器或设置编写方法的方法 更少的次数?有没有方法可以加快这个过程 不要将SAX编写器与DOM操作混用。这意味着您根本不应该操纵SDK类属性或函数。因此,cell.Append()已退出。cell.DataType或cell.StyleIndex也是如此 当你吹萨克斯时,你全力以赴。(听起来有点挑逗…)例如:
for (int i = 1; i <= 50000; ++i)
{
oxa = new List<OpenXmlAttribute>();
// this is the row index
oxa.Add(new OpenXmlAttribute("r", null, i.ToString()));
oxw.WriteStartElement(new Row(), oxa);
for (int j = 1; j <= 100; ++j)
{
oxa = new List<OpenXmlAttribute>();
// this is the data type ("t"), with CellValues.String ("str")
oxa.Add(new OpenXmlAttribute("t", null, "str"));
// it's suggested you also have the cell reference, but
// you'll have to calculate the correct cell reference yourself.
// Here's an example:
//oxa.Add(new OpenXmlAttribute("r", null, "A1"));
oxw.WriteStartElement(new Cell(), oxa);
oxw.WriteElement(new CellValue(string.Format("R{0}C{1}", i, j)));
// this is for Cell
oxw.WriteEndElement();
}
// this is for Row
oxw.WriteEndElement();
}
for(int i=1;i
尝试以下操作,这将帮助您使用EPPlus dll在几秒钟内生成超过1000K行。我刚刚在谷歌搜索中找到了许多SAX示例。出于某种原因,它们混合了SAX和DOM。我将很快尝试您的解决方案。这是一个良好的开端。改进约为20%。我在1250上运行了测试00行44列。它仍然需要100秒才能完成。过去它只需要125秒多一点。所以我找到了对DOM的另一个引用,并在我的特定代码中发现了一些其他算法改进(一个if语句并对其进行了优先级排序).现在,我在47.3秒内拥有了125K行,而不是100或125秒。当每毫秒迭代那么多次时,这是非常重要的。混合使用sax和dom的原因在于内存优化。您可以对一行使用dom操作,然后使用sax方法写入行。这样,就不会使用内存,因为dom元素用于特定的rows是垃圾收集的。这对我来说太棒了。使用这种方法,我几乎可以在9-10秒内写出350K+行。我们还可以冻结第一行(标题)并应用一些格式吗?什么是EPPlus dll?itemToExport包含哪些内容?下面的链接是您正在寻找的很好的解释
using (var stream = new MemoryStream())
{
// ok, we can run the real code of the sample now
using (var xlPackage = new ExcelPackage(stream))
{
// get handles to the worksheets
var worksheet = xlPackage.Workbook.Worksheets.Add("SheetName");
worksheet.Cells["A1"].LoadFromCollection(itemsToExport, true, TableStyles.Medium15);
xlPackage.Save();
}