Недавно мы столкнулись с этой проблемой при экспорте отчетов в файл Excel с использованием библиотеки Infragistics.
На данный момент наша таблица отчетов содержит более или менее 1,26 миллиона записей.Для этого мы пытаемся создать файл Excel (2007), поэтому примерно это будет 2 рабочих листа, поскольку Excel 2007 поддерживает только около 1 миллиона строк на лист.
У нас нет проблем при создании рабочих таблиц иво время заполнения данных на листе память управляется на этом этапе.
Наша проблема заключается в записи данных Excel в поток (файл, память).Потребление памяти слишком велико, и когда оно достигнет 1,8 ГБ, оно больше не будет продолжаться.
PS Это сводный отчет, клиент хочет получить его в одном файле Excel.
Ваши рекомендации очень ценятся !!!
Ниже приведен код, который я извлек из фактического источника, но я заменил часть поиска данных, и вместо этогоиспользуйте фиктивные данные.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Runtime;
using System.Diagnostics;
using Infragistics.Excel;
namespace ConsoleApplication1
{
class Program
{
static bool tip = true;
static void Main(string[] args)
{
var xls = Workbook.MaxExcelRowCount;
var xlsx =Workbook.MaxExcel2007RowCount;
var wb = new Workbook(WorkbookFormat.Excel2007, WorkbookPaletteMode.StandardPalette);
var ws = wb.Worksheets.Add("Sheet1");
var sheetCtr = 1;
var limit = 1256898;
var rr = 0;
for (var row = 0; row < limit; row++)
{
if (rr >= xlsx - 1)
{
//create new worksheet if row exceeded the limit
ws = wb.Worksheets.Add("Sheet" + sheetCtr.ToString());
rr = 0;
ClearMemory();
}
for (var col = 0; col < 10; col++)
{
ws.Rows[rr].Cells[col].Value = string.Format("data{0}-{1}", row, col);
}
Console.Write("Row=");
Console.Write(row.ToString());
Console.WriteLine();
rr++;
}
Console.Write("Saving worksheet...");
//this part uses too much memory
wb.Save("wb2.xlsx");
Console.WriteLine("Workbook saved.");
Console.WriteLine("Done");
Console.Read();
}
static void ClearMemory()
{
try
{
System.Diagnostics.Process proc = System.Diagnostics.Process.GetCurrentProcess();
if (tip == true)
{
proc.MaxWorkingSet = (IntPtr)((int)proc.MaxWorkingSet - 1);
proc.MinWorkingSet = (IntPtr)((int)proc.MinWorkingSet - 1);
}
else
{
proc.MaxWorkingSet = (IntPtr)((int)proc.MaxWorkingSet + 1);
proc.MinWorkingSet = (IntPtr)((int)proc.MinWorkingSet + 1);
}
tip = !tip;
}
catch (System.Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}