OpenXML Sax 方法可将 100K+ 行快速导出到 Excel

2023-12-10

我一直在尝试提高写入 xlsx 的 SAX 方法的性能。我知道 Excel 中的行数限制为 1048576 行。我只达到过这个极限几次。在大多数情况下,我只写出大约 125K 到 250K 行(一个大数据集)。我尝试过的代码似乎没有那么快,因为它会多次写入文件。我希望涉及一些缓存,但现在代码的工作方式似乎仍然有太多的磁盘访问。

下面的代码类似于将模板与 OpenXML 和 SAX 结合使用因为我已经使用 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;
        }

这段代码与我在那里看到的示例非常接近。但问题是它仍然很慢。从单个单元格写入更改为追加到行并写入行似乎将 125K 行的过程改进了 10%。

有没有人找到一种方法来改进作家或设置一种减少写作次数的方法?有没有方法可以加速这个过程?

有没有人尝试过设置某种形式的缓存来提高性能?


一般问题是您不应该将 DOM 和 SAX 方法混合在一起。一旦混合它们,性能就类似于仅使用 DOM。当您全力以赴时,SAX 的性能优势就会显现出来。首先回答您的问题:

有没有人找到一种方法来提高作家或设置一种写作方式 次数少一些?有没有方法可以加速这个过程?

不要将 SAX 编写器与 DOM 操作混合在一起。这意味着您根本不应该对 SDK 类属性或函数进行操作。所以 cell.Append() 已经过时了。 cell.DataType 或 cell.StyleIndex 也是如此。

当你做 SAX 时,你会全力以赴。(这听起来有点挑衅......)例如:

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

其中 oxa 是一个 List,oxw 是 SAX writer 类 OpenXmlWriter。更多详情请看我的文章here.

没有真正的方法来缓存 SAX 操作。它们就像一系列 printf 语句。您可以编写一个辅助函数,只在块中执行 WriteStartElement()、WriteElement() 和 WriteEndElement() 函数(例如,编写完整的 Cell 类)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenXML Sax 方法可将 100K+ 行快速导出到 Excel 的相关文章

  • 是否有用于 C 字符串的标准 C++ 迭代器?

    有时我需要使用通用 C 迭代器范围接口将 C 字符串传递给函数 first last 是否有针对这些情况的标准 C 迭代器类 或者无需复制字符串或调用的标准方法strlen 编辑 我知道我可以使用指针作为迭代器 但我必须知道字符串在哪里结束
  • 有没有一种快速的方法将字符绘制到屏幕上?

    我用 Java 开发了一个 Matrix 主题应用程序 并正在尝试移植到 C 然而我发现后者的DrawString当绘制大量单个字符时 该方法的性能要差得多 因此我希望存在以下两种可能性之一 还有一种绘制大量单个字符的替代方法 速度要快得多
  • 如何在 Microsoft 报告中显示字节数组中的图像

    我使用报表文件和 ReportViewer 控件来显示在运行时从对象动态加载数据的报表 我需要显示一个以字节数组形式存储在对象中的图像 PictureBox 的值当前设置为 First Fields ImageData Value dtst
  • 按比例调整图片框的大小以调整表单大小

    我希望每次 用户调整表单的大小 图片框中的图像也使用相同的值 按比例 调整大小 我在互联网上搜索了一些代码并在中找到了这个答案堆栈溢出 https stackoverflow com a 6501997 3264464 https stac
  • 在 C++11 中使用 decltype() 时出错(在 gcc 4.7.0 中创建不透明错误消息)

    使用以下代码 我的原始代码的精简版本 include
  • 如何在 ASP.NET Core Web API 中传递 int 数组

    我有这个 Web API 方法 Route api controller ApiController public class SubjectsController ControllerBase HttpGet children publi
  • 如何解析无效(错误/格式不正确)的 XML?

    目前 我正在开发一项功能 该功能涉及解析从其他产品收到的 XML 我决定针对一些实际的客户数据运行一些测试 看起来其他产品允许用户输入应被视为无效的输入 无论如何 我仍然必须尝试找出解析它的方法 我们正在使用javax xml parser
  • MVC 项目中的 .Rdlc 报告 - 托管调试助手“PInvokeStackImbalance”

    我即将完成并运行我的上一份报告 我在其他报告中没有遇到过这个问题 我正在尝试根据数据库记录创建报告 当我通过 LocalReport 创建报告并为报告创建参数时 收到错误消息 托管调试助手 PInvokeStackImbalance 调用
  • 当字符串的长度大于n时,如何打印字符串的前n个字节?

    所以我有一个具有一定字节数 或长度 的字符串 我说字节是因为字符串末尾没有 NULL 终止符 不过 我知道绳子有多长 通常 众所周知 当您printf s str 它将继续打印每个字节 直到到达 NULL 字符 我知道没有 C 字符串不是
  • asp.net mvc:将 RedirectToAction(string, object) 转换为 RedirectToAction(x => x.Detail(id))

    任何人都知道如何创建一个方法 我将把它放在扩展类中 该方法将仅使用表达式 无魔术字符串 与 mvc 的 RedirectToAction 执行相同的操作 所以不要写这样的东西 RedirectToAction Detail new Rout
  • 使用 ObjPtr(Me) 返回自定义类实例的名称?

    我明白那个ObjPtr http support microsoft com kb 199824将返回内存中对象的地址 并且它指向一个名为 IUNKNOWN 的结构 并且其中编码了某种接口定义以公开对象结构 但我不知道如何确定一个对象的接口
  • 使用 C# 组合两个列表

    在 OCaml 中 有一个函数接受两个相同大小的列表并返回一个元组列表 val combine a list gt b list gt a b list C 中有类似的东西吗 我对输出的类型没有强烈的要求 它可以是元组列表 也可以是字典之类
  • C 十六进制常数类型

    我写了以下c代码 include
  • 直接在c++中访问Android APK资源数据,无需Asset Manager和复制

    我在我的引擎中使用纯 C 在 android 中创建游戏引擎 没有单个 java 文件 基本上 它是一个只能存储在外部存储器中的游戏 当我通过 adb 手动将资产数据移动到外部 SD 卡时 游戏已经运行良好且稳定 adb push Bin
  • Python 和 C#:IronPython 是绝对必要的吗?

    我主要是一名 C 程序员 但剩下的一个项目让我有 2 个选择 调用 python 脚本 保存为 py 文件 并处理返回值 或者 用C 重写整个python脚本 共6个 py文件 当然 如果我可以简单地实现选项 1 选项 2 就是一个主要的时
  • 将 XSL-FO 转换为 HTML

    我有一组用于 PDF 生成的 XSL FO 文档 我还需要将相同的输出数据 PDF 格式 导出为 HTML 文件 此外 我需要 HTML 具有与 PDF 类似的样式 有没有办法使用 C 将 XSL FO 转换为 XHTML NOTE 我知道
  • 在 C++ 中为哈希映射提供复合键

    我有一个数据结构
  • 我可以使用折叠表达式实现 max(A, max(B, max(C, D))) 吗?

    在尝试使用 C 17 折叠表达式时 我尝试实现 maxsizeof其中结果是最大值sizeof的类型 我有一个丑陋的折叠版本 它使用变量和 lambda 但我无法想出一种使用折叠表达式和std max 得到相同的结果 这是我的折叠版本 te
  • 在 OpenGL 中设置 MVP 矩阵

    我正在尝试学习 OpenGL 的基础知识 但我在设置变换矩阵时遇到问题 我制作了模型 视图和投影矩阵 但将它们发送到我的顶点着色器时遇到问题 这是代码 Set up MVP glm mat4 model glm mat4 GLint uni
  • 3D 图形批处理

    很多网站 文章都说 批量 批 批 有人可以解释一下着色器中的 批处理 代表什么吗 即 是否 改变纹理 更改任意着色器变量 意味着某些东西不能 批处理 最简单的总结方法就是尝试尽可能少地调用 API 来绘制您需要绘制的内容 使用顶点数组或 V

随机推荐

  • 使用包名称从 google play 获取应用程序的详细信息?

    谁能告诉我如何使用 Android 应用程序的包名称从 google play 获取 Android 应用程序的所有详细信息 包括图标 屏幕截图和描述 如果有任何 api 请告诉我 提前致谢 Google Play 除了记录的意图可用于将
  • 使用 h:commandButton 或等效项传递参数

    我在其他线程上读到这不起作用
  • 如何在没有“while True”循环的情况下绘制这个对数?

    我一直在尝试绘制十二音阶 从最低到最高可听音调 以赫兹为单位 我找到了一种方法来做到这一点 使用始终为真的 while 循环 然后在音高低于或高于人类可听范围时使用 Break 退出循环 我知道这种循环是不好的做法 但是作为一个新手程序员
  • 如何在 Visual Studio Code 中进行标签包装?

    我想将我选择的 HTML 内容包装在 Visual Studio Code 中的标签内 我怎么做 嵌入式Emmet可以做到这一点 选择文本 可选 Open command palette usually Ctrl Shift P Execu
  • 动态属性名称串联

    我正在寻找一种根据另一个变量的值分配给变量的简单方法 device slot2 clipList clipNumber singleClipDetails 我想做的是 用另一个变量替换 2 这样我就可以运行相同的操作 而只需更改 var s
  • C 中允许空宏定义吗?他们的行为如何?

    假设 空 宏定义 define FOO 标准 C 有效吗 如果是这样 那是什么FOO在这个定义之后 它只是一个扩展为空的宏 但是 既然已经定义了宏 您可以检查 if defined or ifdef 是否已定义 define FOO int
  • 自动刷新特定 div 博主 javascript

    我在博客站点上使用 Javascript 小部件 它包含一个带有一些 JavaScript 的 div 这些 JavaScript 从服务器获取一些 非静态 字符串并将其打印在页面上 直到这里一切正常 问题是我想每隔几秒更新一次该 div
  • Python PIL加载抛出AttributeError:'NoneType'对象没有属性'read'

    我已经为这个错误苦苦挣扎了好几天 但进展甚微 基本上 我试图读入图像文件 然后使用 PIL 对其执行特定操作 我的最终目标是执行 PIL 粘贴操作 然而 每当我加载图像 然后调用它的 load 方法 诸如 show paste resize
  • 如何让 Django 在 AWS S3 上将某些文件设为公开,将媒体文件设为私有(无 403 错误)?

    我在用着boto3 and Django 存储在我的 Django 应用程序中提供来自 AWS S3 的文件 我希望我的静态文件是公开的 但其他文件是私有的 我已经有点工作但不完全 我的静态文件就像私有文件一样使用预签名密钥 在我的模板文件
  • 将命名列表传递给 cols_only() [关闭]

    Closed 这个问题需要调试细节 目前不接受答案 当我尝试做这样的事情时 data lt read csv blah csv n max 100 col types cols only list files c Error Some co
  • 为什么这个错误类型“String”不是类型“Map ”的子类型

    已经处于这种情况很长一段时间了 但没有解决该错误 String 不是 Map 类型的子类型 提出了很多相关问题也希望得到帮助 这是我的课程 class Provider Provider required this id required
  • 如何使用脚本生成 INTERVAL 1

    我们正在尝试找到一种语法来从日期函数的第三个参数生成 DAY WEEK MONTH 选项 DECLARE var date option STRING DEFAULT DAY select GENERATE DATE ARRAY 2019
  • 使用 Plupload HTML5 运行时直接上传到 Amazon S3 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我在之前的一篇文章中看到过如何让 Plupload 直接上传到 Amazon S
  • PHPUnit 模拟对象和静态方法

    我正在寻找测试以下静态方法的最佳方法 特别是使用 Doctrine 模型 class Model User extends Doctrine Record public static function create userData new
  • 模态弹出窗口在打开时淡入,在关闭时淡出

    我有一个相当简单的问题 我有删除按钮 可以打开模式弹出窗口以确认或拒绝删除 我希望这些模式弹出窗口在单击时淡入 在取消时淡出 我已经尝试了几种不同的方法 到目前为止还没有运气 我只需要一个简单的解决方案 提前致谢 这是我的代码
  • Google Play 应用签名和即时应用

    相当直接的问题 有人知道 Google Play 应用签名是否支持即时应用吗 我问的原因是 输入应用程序的签名配置 或选择密钥库文件 虽然可以在测试期间使用调试配置或密钥库 但生成的数字资产链接文件将与应用程序的发布版本不兼容 如果您确实上
  • 从 MVC 控制器创建/获取 DefaultHtmlGenerator

    我正在尝试在 MVC6 控制器方法内为 Microsoft AspNet Mvc Rendering DefaultHtmlGenerator 创建 或以某种方式获取它的实例 我想在我的 asp net mvc 控制器中生成用于验证我的模型
  • 生成正则表达式可以在 Python 中匹配的值列表

    我尝试使用正则表达式作为输入 并从那里生成正则表达式匹配的所有可能值 因此 例如 如果正则表达式是 以 a 开头 以 c 结尾的三个字母单词 则代码将生成一个包含值 aac abc acc adc a1c 的列表 是否有捷径可寻 我正在使用
  • 在Google云机器学习上部署Retrained inception模型

    我设法使用通用初始模型重新训练我的特定分类模型tutorial 我现在想将其部署在谷歌云机器学习上steps 我已经设法将其导出为 MetaGraph 但我无法获得正确的输入和输出 在本地使用它 我的图表入口点是DecodeJpeg con
  • OpenXML Sax 方法可将 100K+ 行快速导出到 Excel

    我一直在尝试提高写入 xlsx 的 SAX 方法的性能 我知道 Excel 中的行数限制为 1048576 行 我只达到过这个极限几次 在大多数情况下 我只写出大约 125K 到 250K 行 一个大数据集 我尝试过的代码似乎没有那么快 因