XtraGrid - 导出到 Excel

发布于 2024-10-18 07:24:17 字数 8462 浏览 3 评论 0原文

我正在使用 Developer Express XtraGrid 组件来显示一些数据。我的 Windows 申请表上有 2 个 XtraGrid。两个网格都有超过 200k+ 行和 8 列数据,并且我有导出到 Excel 按钮。 (据我所知)有两种方法可以将网格数据导出到 Excel。

1- grid.ExportToXls();grid.ExportToXlsx();

2- 使用 Office Interop 和 OpenXML 实用程序

如果我使用 grid.ExportToXls();grid.ExportToXlsx();,处理时间比 Office 互操作代码更快(对于大约 2k 行数据)。但是,此方法只能用于 1 个网格。因此结果出现在 2 个不同的 Excel 文件中。因此,我在流程完成后使用 Office Interop 合并工作簿。这里就出现了问题。通过这两种方式,我总是收到 System.OutOfMemory 异常。 (见下面的内存图) 在此处输入图像描述

我被困在这里,因为我知道导出 excel 的方法会抛出 System.OutOfMemory异常。您有什么建议吗?如何将超过 200k - 300k+ 行的数据导出到 Excel?我在 Visual Studio 2010 上使用 .Net Framework 3.5。 您可以在下面找到我的 Interop 和 Document.Format OpenXML Utility 代码。

try
{
   SaveFileDialog saveDialog = new SaveFileDialog();
   saveDialog.Title = SaveAsTitle;
   saveDialog.Filter = G.Instance.MessageManager.GetResourceMessage("EXCEL_FILES_FILTER");
                saveDialog.ShowDialog();

   if (string.IsNullOrEmpty(saveDialog.FileName))
   {
   // Showing Warning
   return;
   }

   List<GridControl> exportToExcel = new List<GridControl>();
   exportToExcel.Add(dataGrid);
   exportToExcel.Add(summaryGrid);

   ExportXtraGridToExcel2007(saveDialog.FileName, exportToExcel);
}
catch (Exception ex)
{
  // Showing Error
}

这是我的 ExportXtraGridToExcel2007(); 函数代码

public void ExportXtraGridToExcel2007(string path, List<GridControl> grids)
        {
            try
            {
                DisableMdiParent();
                string tmpPath = Path.GetTempPath();
                List<string> exportedFiles = new List<string>();

                for (int i = 0; i < grids.Count; i++)
                {
                    string currentPath = string.Format(@"{0}\document{1}.xlsx", tmpPath, i);
                    GridControl grid = grids[i];
                    grid.MainView.ExportToXlsx(currentPath);
                    exportedFiles.Add(currentPath);
                }

                if (exportedFiles.Count > 0)
                {
                    OpenXmlUtilities.MergeWorkbooks(path, exportedFiles.ToArray());
                    foreach (string excel in exportedFiles)
                    {
                        if (File.Exists(excel))
                        {
                            try
                            {
                                File.Delete(excel);
                            }
                            catch (Exception ex)
                            {
                                EventLog.WriteEntry("Application", ex.Message);
                            }
                        }
                    }

                }                
            }
            catch (Exception ex)
            {
            // showing error
        }
            finally
            {
                EnableMdiParent();
            }
        }

,这是 OpenXML 合并工作簿代码

public static void MergeWorkbooks(string path, string[] sourceWorkbookNames)
        {
            WorkbookPart mergedWorkbookPart = null;

            WorksheetPart mergedWorksheetPart = null;
            WorksheetPart childWorksheetPart = null;

            Sheets mergedWorkbookSheets = null;
            Sheets childWorkbookSheets = null;

            Sheet newMergedSheet = null;
            SheetData mergedSheetData = null;

            SharedStringTablePart mergedSharedStringTablePart = null;
            SharedStringTablePart childSharedStringTablePart = null;

            // Create the merged workbook package.
            using (SpreadsheetDocument mergedWorkbook =
                SpreadsheetDocument.Create(path,
                SpreadsheetDocumentType.Workbook))
            {
                // Add the merged workbook part to the new package.
                mergedWorkbookPart = mergedWorkbook.AddWorkbookPart();
                GenerateMergedWorkbook().Save(mergedWorkbookPart);

                // Get the Sheets element in the merged workbook for use later. 
                mergedWorkbookSheets = mergedWorkbookPart.Workbook.GetFirstChild<Sheets>();

                // Create the Shared String Table part in the merged workbook.
                mergedSharedStringTablePart = mergedWorkbookPart.AddNewPart<SharedStringTablePart>();
                GenerateSharedStringTablePart().Save(mergedSharedStringTablePart);

                // For each source workbook to merge...
                foreach (string workbookName in sourceWorkbookNames)
                {
                    // Open the source workbook. The following will throw an exception if
                    // the source workbook does not exist.
                    using (SpreadsheetDocument childWorkbook =
                        SpreadsheetDocument.Open(workbookName, false))
                    {
                        // Get the Sheets element in the source workbook.
                        childWorkbookSheets = childWorkbook.WorkbookPart.Workbook.GetFirstChild<Sheets>();

                        // Get the Shared String Table part of the source workbook.
                        childSharedStringTablePart = childWorkbook.WorkbookPart.SharedStringTablePart;

                        // For each worksheet in the source workbook...
                        foreach (Sheet childSheet in childWorkbookSheets)
                        {
                            // Get a worksheet part for the source worksheet using it's relationship Id. 
                            childWorksheetPart = (WorksheetPart)childWorkbook.WorkbookPart.GetPartById(childSheet.Id);

                            // Add a worksheet part to the merged workbook based on the source worksheet.
                            mergedWorksheetPart = mergedWorkbookPart.AddPart<WorksheetPart>(childWorksheetPart);

                            // There should be only one worksheet that is set as the main view.
                            CleanView(mergedWorksheetPart);

                            // Create a Sheet element for the new sheet in the merged workbook.
                            newMergedSheet = new Sheet();

                            // Set the Name, Id, and SheetId attributes of the new Sheet element.
                            newMergedSheet.Name = GenerateWorksheetName(mergedWorkbookSheets, childSheet.Name.Value);
                            newMergedSheet.Id = mergedWorkbookPart.GetIdOfPart(mergedWorksheetPart);
                            newMergedSheet.SheetId = (uint)mergedWorkbookSheets.ChildElements.Count + 1;

                            // Add the new Sheet element to the Sheets element in the merged workbook.
                            mergedWorkbookSheets.Append(newMergedSheet);

                            // Get the SheetData element of the new worksheet part in the merged workbook.
                            mergedSheetData = mergedWorksheetPart.Worksheet.GetFirstChild<SheetData>();

                            // For each row of data...
                            foreach (Row row in mergedSheetData.Elements<Row>())
                            {
                                // For each cell in the row...
                                foreach (Cell cell in row.Elements<Cell>())
                                {
                                    // If the cell is using a shared string then merge the string
                                    // from the source workbook into the merged workbook. 
                                    if (cell.DataType != null &&
                                        cell.DataType.Value == CellValues.SharedString)
                                    {
                                        ProcessCellSharedString(mergedWorksheetPart, cell,
                                            mergedSharedStringTablePart, childSharedStringTablePart);
                                    }
                                }
                            }
                        }
                    }
                }

                //Save the changes to the merged workbook.
                mergedWorkbookPart.Workbook.Save();
            }
        }

I'am using Developer Express XtraGrid Component to show some data. I have 2 XtraGrid on my Windows Application Form. Both grids have more than 200k+ lines, and 8 columns of data, and I have export to excel button. There are two ways (as I know) for exporting grid data to excel.

1- grid.ExportToXls(); or grid.ExportToXlsx();

2- Using Office Interop, and OpenXML Utilities

If I use grid.ExportToXls(); or grid.ExportToXlsx();, the process time is faster than Office Interop Codes (for arround 2k lines of data). But, this method can be used for just 1 grid. So result appears on 2 different Excel files. So, I'am using Office Interop to merge workbooks after process completed. Here is the problem occurs. With both these ways, I am always getting System.OutOfMemory Exception. (See the memory graph below)
enter image description here

I'am stuck here, because the ways I know to export excel are throwing System.OutOfMemory Exception. Do you have any suggestion, how can I export more than 200k - 300k+ lines of data to Excel? I'am using .Net Framework 3.5 on Visual Studio 2010.
And you can find my Interop, and Document.Format OpenXML Utility codes below.

try
{
   SaveFileDialog saveDialog = new SaveFileDialog();
   saveDialog.Title = SaveAsTitle;
   saveDialog.Filter = G.Instance.MessageManager.GetResourceMessage("EXCEL_FILES_FILTER");
                saveDialog.ShowDialog();

   if (string.IsNullOrEmpty(saveDialog.FileName))
   {
   // Showing Warning
   return;
   }

   List<GridControl> exportToExcel = new List<GridControl>();
   exportToExcel.Add(dataGrid);
   exportToExcel.Add(summaryGrid);

   ExportXtraGridToExcel2007(saveDialog.FileName, exportToExcel);
}
catch (Exception ex)
{
  // Showing Error
}

And this is my ExportXtraGridToExcel2007(); function codes

public void ExportXtraGridToExcel2007(string path, List<GridControl> grids)
        {
            try
            {
                DisableMdiParent();
                string tmpPath = Path.GetTempPath();
                List<string> exportedFiles = new List<string>();

                for (int i = 0; i < grids.Count; i++)
                {
                    string currentPath = string.Format(@"{0}\document{1}.xlsx", tmpPath, i);
                    GridControl grid = grids[i];
                    grid.MainView.ExportToXlsx(currentPath);
                    exportedFiles.Add(currentPath);
                }

                if (exportedFiles.Count > 0)
                {
                    OpenXmlUtilities.MergeWorkbooks(path, exportedFiles.ToArray());
                    foreach (string excel in exportedFiles)
                    {
                        if (File.Exists(excel))
                        {
                            try
                            {
                                File.Delete(excel);
                            }
                            catch (Exception ex)
                            {
                                EventLog.WriteEntry("Application", ex.Message);
                            }
                        }
                    }

                }                
            }
            catch (Exception ex)
            {
            // showing error
        }
            finally
            {
                EnableMdiParent();
            }
        }

and this is the OpenXML Merge Work Books Codes

public static void MergeWorkbooks(string path, string[] sourceWorkbookNames)
        {
            WorkbookPart mergedWorkbookPart = null;

            WorksheetPart mergedWorksheetPart = null;
            WorksheetPart childWorksheetPart = null;

            Sheets mergedWorkbookSheets = null;
            Sheets childWorkbookSheets = null;

            Sheet newMergedSheet = null;
            SheetData mergedSheetData = null;

            SharedStringTablePart mergedSharedStringTablePart = null;
            SharedStringTablePart childSharedStringTablePart = null;

            // Create the merged workbook package.
            using (SpreadsheetDocument mergedWorkbook =
                SpreadsheetDocument.Create(path,
                SpreadsheetDocumentType.Workbook))
            {
                // Add the merged workbook part to the new package.
                mergedWorkbookPart = mergedWorkbook.AddWorkbookPart();
                GenerateMergedWorkbook().Save(mergedWorkbookPart);

                // Get the Sheets element in the merged workbook for use later. 
                mergedWorkbookSheets = mergedWorkbookPart.Workbook.GetFirstChild<Sheets>();

                // Create the Shared String Table part in the merged workbook.
                mergedSharedStringTablePart = mergedWorkbookPart.AddNewPart<SharedStringTablePart>();
                GenerateSharedStringTablePart().Save(mergedSharedStringTablePart);

                // For each source workbook to merge...
                foreach (string workbookName in sourceWorkbookNames)
                {
                    // Open the source workbook. The following will throw an exception if
                    // the source workbook does not exist.
                    using (SpreadsheetDocument childWorkbook =
                        SpreadsheetDocument.Open(workbookName, false))
                    {
                        // Get the Sheets element in the source workbook.
                        childWorkbookSheets = childWorkbook.WorkbookPart.Workbook.GetFirstChild<Sheets>();

                        // Get the Shared String Table part of the source workbook.
                        childSharedStringTablePart = childWorkbook.WorkbookPart.SharedStringTablePart;

                        // For each worksheet in the source workbook...
                        foreach (Sheet childSheet in childWorkbookSheets)
                        {
                            // Get a worksheet part for the source worksheet using it's relationship Id. 
                            childWorksheetPart = (WorksheetPart)childWorkbook.WorkbookPart.GetPartById(childSheet.Id);

                            // Add a worksheet part to the merged workbook based on the source worksheet.
                            mergedWorksheetPart = mergedWorkbookPart.AddPart<WorksheetPart>(childWorksheetPart);

                            // There should be only one worksheet that is set as the main view.
                            CleanView(mergedWorksheetPart);

                            // Create a Sheet element for the new sheet in the merged workbook.
                            newMergedSheet = new Sheet();

                            // Set the Name, Id, and SheetId attributes of the new Sheet element.
                            newMergedSheet.Name = GenerateWorksheetName(mergedWorkbookSheets, childSheet.Name.Value);
                            newMergedSheet.Id = mergedWorkbookPart.GetIdOfPart(mergedWorksheetPart);
                            newMergedSheet.SheetId = (uint)mergedWorkbookSheets.ChildElements.Count + 1;

                            // Add the new Sheet element to the Sheets element in the merged workbook.
                            mergedWorkbookSheets.Append(newMergedSheet);

                            // Get the SheetData element of the new worksheet part in the merged workbook.
                            mergedSheetData = mergedWorksheetPart.Worksheet.GetFirstChild<SheetData>();

                            // For each row of data...
                            foreach (Row row in mergedSheetData.Elements<Row>())
                            {
                                // For each cell in the row...
                                foreach (Cell cell in row.Elements<Cell>())
                                {
                                    // If the cell is using a shared string then merge the string
                                    // from the source workbook into the merged workbook. 
                                    if (cell.DataType != null &&
                                        cell.DataType.Value == CellValues.SharedString)
                                    {
                                        ProcessCellSharedString(mergedWorksheetPart, cell,
                                            mergedSharedStringTablePart, childSharedStringTablePart);
                                    }
                                }
                            }
                        }
                    }
                }

                //Save the changes to the merged workbook.
                mergedWorkbookPart.Workbook.Save();
            }
        }

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

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

发布评论

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

评论(2

感情旳空白 2024-10-25 07:24:17

我会使用 XtraGrid 的内置方法导出到 Excel,正如您所说,它甚至更快。

生成两个 Excel 文件后,我将仅使用 Excel Interop 程序集将两个结果文件合并到同一工作簿中两个单独的 Excel 工作表上的同一文件中。

因此您的问题不再是 XtraGrid,而是简单地涉及如何将两个文件合并为一个单独的工作表中的一个,已经讨论过很多次,您可以在网上找到解决方案,例如在这里: 如何将 2 个 Excel 文件合并为一个具有分隔工作表的 Excel 文件?< /a>

I would use the built-in method from XtraGrid to export to excel as you say it's even faster.

After having generated the two excel files I would use Excel Interop assemblies only to merge the two resulting files in the same file on two separated Excel Sheets in same workbook.

so your problem would not be with XtraGrid anymore but simply with how to merge two files into one in separated worksheets, discussed many times already and you will find solutions online, for example here: How do I merge 2 Excel files into one excel file with separated sheets?

×眷恋的温暖 2024-10-25 07:24:17

我知道这是一个迟到的答案,但是,您可以使用 devExpress 方法和组件将多个网格导出到同一个 Excel 文件。 (也许旧版本中不是这种情况,我不确定它什么时候可用)

向每个 gridControl 添加一个 printableComponentLink ,然后创建一个您可以添加每个 printableComponent 链接的合成链接。

然后您将使用compositeLink.ExportToXlsx 方法。如果您使用等于 SingleFilePageByPage 的 XlsxExportOptions.ExportMode 属性创建 XlsxExportOptions 并将其传递给 CompositeLink.ExportToXlsx 方法,则每个页面都将导出到单独的工作表。

这篇帖子引起了我的注意。

I know this is a late answer but, you can use devExpress methods and components to export multiple grids to the same excel file. (Perhaps this was not the case in older versions, I am not sure when it became available)

Add a printableComponentLink to each gridControl, and then Create a compositeLink that you can add each of the printableComponent links to.

Then you will use the compositeLink.ExportToXlsx method. If you create XlsxExportOptions with the XlsxExportOptions.ExportMode property equal to SingleFilePageByPage and pass it to the CompositeLink.ExportToXlsx method, every page will be exported to a separate sheet.

This post brought this question to my attention.

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