Экспорт в Excel

Приветствую!

Экспортирую данные из DataGridView в Excel. И столкнулся со следующими проблемами:

  1. Если Excel не активирован, то иногда при попытке запуска возникает исключение с кодом 0x800AC472
    “Исключение из HRESULT: 0x800AC472”.

Нашел решение, заключающееся в циклических попытках запуска, пока не запустится нормально. Но очень похоже на костыль. Может кто-нибудь знает, как по-человечески сделать?

bool completed = false;

do
{
	Microsoft.Office.Interop.Excel.Application xlApp = null;
	Microsoft.Office.Interop.Excel.Workbook xlWorkBook = null;
	Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet = null;

	try
	{
		this.ArtDBView.SelectAll();

		DataObject dataObj = this.ArtDBView.GetClipboardContent();

		if (dataObj != null)
		{
			Clipboard.SetDataObject(dataObj);
		}

		xlApp = new Microsoft.Office.Interop.Excel.Application();
		xlApp.Visible = false;
		xlApp.Interactive = false;

		Object misValue = System.Reflection.Missing.Value;
		xlWorkBook = xlApp.Workbooks.Add(misValue);
		xlWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

		xlWorkSheet.EnableSelection = Microsoft.Office.Interop.Excel.XlEnableSelection.xlNoSelection;

		Microsoft.Office.Interop.Excel.Range cells = (Microsoft.Office.Interop.Excel.Range)xlWorkSheet.Cells[1, 1];

		cells.Select();
		xlWorkSheet.PasteSpecial(cells, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, true);

		//Autofit all columns
		xlWorkSheet.Cells.EntireColumn.AutoFit();

		xlApp.Visible = true;
		xlApp.Interactive = true;

		completed = true;
	}

	catch (Exception exp)
	{
		completed = false;
	}

	finally
	{
		if (xlWorkSheet != null)
		{
			this.ReleaseObject(xlWorkSheet);
		}

		if (xlWorkBook != null)
		{
			this.ReleaseObject(xlWorkBook);
		}

		if (xlApp != null)
		{
			this.ReleaseObject(xlApp);
		}
	}
} while (completed != true);
  1. После закрытия окна с Excel остается непонятный зомби-процесс Excel в процессах.
    В коде, отвечающем за открытие Excel в блоке finally есть освобождение ресурсов. Но не помогает. Код метода освобождения ресурсов.
private void ReleaseObject(Object Obj)
{
	try
	{
		System.Runtime.InteropServices.Marshal.ReleaseComObject(Obj);
	}

	finally
	{
		Obj = null;
		GC.Collect();
	}
}
1 лайк

Если Эксель 2007+, то обычно в 100500 раз проще и лучше не трогать само приложение Экселя, а взять библиотеку типа этой:

1 лайк

Спасибо, посмотрю

За это вообще не партесь. Это нормальный штатный глюк Microsoft. Маркетинговый ход, не завершать своевременно процессы, чем и подводим юзера покупать ноуты с большим объемом ОЗУ.

Совет Alex P. по использованию библиотеки вместо дергать приложение поддерживаю.

Вообще его все-таки можно как-то закрыть если делать всё правильно, но да, там какая-то сложная процедура закрытия/освобождения памяти. Close + Quit + ReleaseComObject + null :kolobokcrossing:

И еще там вроде можно случайно создать объект не получив ссылку на него (обращения через “две точки” типа excel.Workbooks.Open), и его тогда не получится освободить: https://stackoverflow.com/a/17367570/964478
Хотя GC вроде все-таки может справиться с этим если не убивать программу отдадчиком и т.п. https://stackoverflow.com/a/25135685/964478

Так то-то и оно. Что приходится следить за конструкторами и их деструкторами.
Это как с OpenCV - не следишь за конструкторами получишь переполнение ОЗУ. И самое интересное что винда после закрытия приложения, по умолчанию, не все процессы приложеня прекращает.

боже, привет, спасибо, я целый день сидел над данной проблемой. Даже турецкий добрый человек не помогу решить мне данную проблему. я кстати сижу и делаю диплом)))