vsto excel 工作簿项目:如何快速地将巨大的数据表写入 Excel 工作表

发布于 2024-12-23 00:50:29 字数 1419 浏览 0 评论 0原文

我有一个复杂的对象(树结构),我将其展平到数据表中以将其显示在 Excel 工作表上。数据表很大,大约有 20000 行和 10000 列。

将数据一次写入 Excel 单元格需要很长时间。因此,我将复杂对象转换为数据表,然后使用下面的代码将其写入 Excel 工作表。

是否可以在一分钟之内相当快地将 20K 行 x 10K 列数据写入 Excel 工作表或 << 5分钟?快速完成这项任务的最佳技术是什么?

环境:Visual studio 2010、VSTO excel 工作簿项目、.net Framework 4.0、excel 2010/2007

编辑:

原始数据源是 json 格式的休息服务响应。然后,我将 json 响应反序列化为 C# 对象,最后将其展平为数据表。

使用此代码将数据表写入 Excel 工作表:

Excel.Range oRange;
                var oSheet = Globals.Sheet3;
                int rowCount = 1;
                foreach (DataRow dr in resultsDataTable.Rows)
                {
                    rowCount += 1;
                    for (int i = 1; i < resultsDataTable.Columns.Count + 1; i++)
                    {
                        // Add the header the first time through 
                        if (rowCount == 2)
                        {
                            oSheet.Cells[1, i] = resultsDataTable.Columns[i - 1].ColumnName;
                        }
                        oSheet.Cells[rowCount, i] = dr[i - 1].ToString();
                    }
                }

                // Resize the columns 
                oRange = oSheet.get_Range(oSheet.Cells[1, 1],
                                oSheet.Cells[rowCount, resultsDataTable.Columns.Count]);
                oRange.EntireColumn.AutoFit();

最终解决方案: 使用 2D 对象数组而不是数据表并将其写入范围。

I have a complex object(tree structure) which I am flattening it out into a datatable to display it on an excel sheet. Datatable is huge and has around 20000 rows and 10000 columns.

Writing the data onto an excel cell one at a time took forever. So, I am converting the complex object into a datatable and then writing it to the excel sheet using the code below.

Is it possible to write 20K rows x 10K columns data to an excel sheet fairly quickly in less than a minute or < 5 minutes? What is the best technique to complete this task fast.

Environment: Visual studio 2010, VSTO excel workbook project, .net framework 4.0, excel 2010/2007

EDIT:

Original source of data is a rest service response in json format. I am then deserializing json response into c# objects and finally flattening it into a datatable.

Using this Code to write datatable to an excel sheet:

Excel.Range oRange;
                var oSheet = Globals.Sheet3;
                int rowCount = 1;
                foreach (DataRow dr in resultsDataTable.Rows)
                {
                    rowCount += 1;
                    for (int i = 1; i < resultsDataTable.Columns.Count + 1; i++)
                    {
                        // Add the header the first time through 
                        if (rowCount == 2)
                        {
                            oSheet.Cells[1, i] = resultsDataTable.Columns[i - 1].ColumnName;
                        }
                        oSheet.Cells[rowCount, i] = dr[i - 1].ToString();
                    }
                }

                // Resize the columns 
                oRange = oSheet.get_Range(oSheet.Cells[1, 1],
                                oSheet.Cells[rowCount, resultsDataTable.Columns.Count]);
                oRange.EntireColumn.AutoFit();

Final Solution:
Used a 2D Object array instead of datatable and wrote it to the range.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

謸气贵蔟 2024-12-30 00:50:29

除了冻结 Excel 的动画之外,在给定数据源的情况下,您还可以通过 Excel.Range 对象(这必然会成为瓶颈)进行循环,而不是写入Datatable,写入string[,],Excel 可使用该字符串立即写入Range。循环遍历 string[,] 比循环遍历 Excel 单元格要快得多。

string[,] importString = new string[yourJsonSource.Rows.Count, yourJsonSource.Columns.Count];
//populate the string[,] however you can
for (int r = 0; r < yourJsonSource.Rows.Count; r++)
{
    for (int c = 0; c < yourJsonSource.Columns.Count; c++)
    {
        importString[r, c] = yourJsonSource[r][c].ToString();
    }
}

var oSheet = Globals.Sheet3;
Excel.Range oRange = oSheet.get_Range(oSheet.Cells[1, 1],
            oSheet.Cells[yourJsonSource.Rows.Count, yourJsonSource.Columns.Count]);
oRange.Value = importString;

In addition to freezing Excel's animation, you can, given the data source this is coming from, save yourself the looping through the Excel.Range object, which is bound to be a bottleneck, by instead of writing to a Datatable, write to a string[,], which Excel can use to write to a Range at once. Looping through a string[,] is much faster than looping through Excel cells.

string[,] importString = new string[yourJsonSource.Rows.Count, yourJsonSource.Columns.Count];
//populate the string[,] however you can
for (int r = 0; r < yourJsonSource.Rows.Count; r++)
{
    for (int c = 0; c < yourJsonSource.Columns.Count; c++)
    {
        importString[r, c] = yourJsonSource[r][c].ToString();
    }
}

var oSheet = Globals.Sheet3;
Excel.Range oRange = oSheet.get_Range(oSheet.Cells[1, 1],
            oSheet.Cells[yourJsonSource.Rows.Count, yourJsonSource.Columns.Count]);
oRange.Value = importString;
凯凯我们等你回来 2024-12-30 00:50:29

我不能谈论使用数据表来完成这项工作,但如果您想使用 Interop,您肯定希望避免逐个单元地编写。相反,创建一个二维数组,并立即将其写入一个范围,这会给你带来非常显着的性能提升。

您应该考虑的另一个选择是完全避免互操作,并使用 OpenXML 。如果您使用的是 Excel 2007 或更高版本,这通常是处理文件的更好方法。

I can't speak about using a datatable for the job, but if you want to use Interop, you definitely want to avoid writing cell by cell. Instead, create a 2-d array, and write it at once to a range, which will give you a very significant performance improvement.

Another option you should consider is avoiding interop altogether, and using OpenXML. If you are working with Excel 2007 or above, this is typically a better approach to manipulate files.

打小就很酷 2024-12-30 00:50:29

VSTO 总是需要时间,我可以与您分享的最佳技巧是在填充数据时禁用工作表刷新,一种方法是弹出一个“模态”进度对话框并在后台刷新工作表,这将给出您的性能提高 50-70%。您可以做的另一件事是将 VS 更新到 sp1,这会有所帮助。

VSTO is always gonna take its time, the best tip I can share with you is disable sheet refresh when you populate data, one way to do this is pop up a "Modal" progress dialog box and refresh your sheet in background, this will give you 50-70% better performance. Another thing you can do is update VS to sp1, it helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文