XtraGrid - экспорт в Excel
Я использую Developer Express XtraGrid
Компонент, чтобы показать некоторые данные. у меня есть 2 XtraGrid
в моей заявке на участие в Windows. Обе сетки имеют более 200 тыс. Строк и 8 столбцов данных, и у меня есть кнопка экспорта в Excel. Есть два способа (насколько я знаю) для экспорта данных сетки в Excel.
1- grid.ExportToXls();
или же grid.ExportToXlsx();
2- Использование Office Interop, и OpenXML Utilities
Если я использую grid.ExportToXls();
или же grid.ExportToXlsx();
время обработки быстрее, чем коды взаимодействия Office (около 2 тыс. строк данных). Но этот метод может быть использован только для 1 сетки. Так что результат появляется на 2 разных Excel
файлы. Итак, я использую Office Interop для объединения рабочих книг после завершения процесса. Вот проблема возникает. С обоими этими способами я всегда получаю System.OutOfMemory
Исключение. (См. График памяти ниже)
Я застрял здесь, потому что пути, которые я знаю, чтобы экспортировать Excel, бросают System.OutOfMemory
Исключение. Есть ли у вас какие-либо предложения, как я могу экспортировать более 200 000 - 300 000 строк данных в Excel
? Я использую .Net Framework 3.5
на Visual Studio 2010
, И вы можете найти мой 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 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();
}
}
2 ответа
Я бы использовал встроенный метод из XtraGrid для экспорта, чтобы преуспеть, как вы говорите, это еще быстрее.
После создания двух файлов Excel я бы использовал сборки Excel Interop только для объединения двух полученных файлов в один файл на двух отдельных листах Excel в одной книге.
так что ваша проблема больше не будет с XtraGrid, а просто с тем, как объединить два файла в один в отдельных листах, уже обсуждалось много раз, и вы найдете решения в Интернете, например, здесь: Как объединить 2 файла Excel в один файл Excel с отдельные листы?
Я знаю, что это поздний ответ, но вы можете использовать методы и компоненты devExpress для экспорта нескольких сеток в один файл Excel. (Возможно, это было не так в старых версиях, я не уверен, когда это стало доступно)
Добавьте printableComponentLink к каждому gridControl, а затем создайте CompositLink, к которому вы можете добавить каждую из ссылок printableComponent.
Затем вы будете использовать метод CompositeLink.ExportToXlsx. Если вы создадите XlsxExportOptions со свойством XlsxExportOptions.ExportMode, равным SingleFilePageByPage, и передадите его методу CompositeLink.ExportToXlsx, каждая страница будет экспортирована на отдельный лист.
Этот пост принес этот вопрос моему вниманию.