1

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

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

2- 使用 Office 互操作,以及OpenXML Utilities

如果我使用grid.ExportToXls();or grid.ExportToXlsx();,则处理时间比 Office Interop Codes 快(大约 2k 行数据)。但是,这种方法只能用于 1 个网格。所以结果出现在 2 个不同的Excel文件上。因此,我正在使用 Office Interop 在流程完成后合并工作簿。这是发生问题的地方。通过这两种方式,我总是得到System.OutOfMemory异常。(见下面的内存图) 在此处输入图像描述

我被困在这里,因为我知道导出 excel 的方式是抛出System.OutOfMemory异常。您有什么建议,我如何将超过 200k - 300k+ 行的数据导出到Excel?我正在使用.Net Framework 3.5. Visual Studio 2010你可以在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();
            }
        }
4

2 回答 2

2

我会使用 XtraGrid 的内置方法导出到 excel,因为你说它更快。

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

因此,您的问题将不再是 XtraGrid,而只是如何将两个文件合并为一个单独的工作表,已经讨论了很多次,您会在网上找到解决方案,例如:如何将 2 个 Excel 文件合并到一个 excel 文件中分开的床单?

于 2011-10-03T14:42:18.250 回答
1

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

将 printableComponentLink 添加到每个 gridControl,然后创建一个复合链接,您可以将每个 printableComponent 链接添加到该链接。

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

这篇文章引起了我的注意。

于 2012-04-25T16:18:33.087 回答