Memory issues with excel interops , memory out exception - c#

I have a code that converts bunch of csv files into excel and then highlights some rows.When I feed multiple files it throws memory out of exception . I believe there are memory leaks in code pertaining to com objects.Also, I am not sure how to correctly place garbage collectors.
Below is my do work method of background worker . It works fine if I put single file but for multiple file is throws exception. I just need help in assesing if i am correctly releasing memory ,or my logic is inefficient, or really i am using extra memory [I dont believe this might be case]
Giving below my code for expert analysis
try
{
Microsoft.Office.Interop.Excel.Application oXL;
Microsoft.Office.Interop.Excel.Workbook oWB;
Microsoft.Office.Interop.Excel.Worksheet oSheet;
Microsoft.Office.Interop.Excel.Range oRng;
oXL = new Microsoft.Office.Interop.Excel.Application();
oXL.Visible = false;
oWB = (Microsoft.Office.Interop.Excel.Workbook)(oXL.Workbooks.Add(""));
oSheet = (Microsoft.Office.Interop.Excel.Worksheet)oWB.ActiveSheet;
oSheet.Name = "Summary Report";
object misvalue = System.Reflection.Missing.Value;
int file_progress_Delta = 72 / lstFileName.Count();
int droppedCount = 0;
int acceptedCount = 0;
int invalidMACCount = 0;
int ARCRepeatedCount = 0;
int tMAC1matchedCount = 0;
int tMACmatchedCount = 0;
int tMAC2matchedCount = 0;
int tMAC3matchedCount = 0;
int syncFrameARCUpdatedCount = 0;
int resyncFrameARCUpdatedCount = 0;
int syncFrameARCNotUpdatedCount = 0;
int resyncFrameARCNotUpdatedCount = 0;
int securedinvalidframeCount = 0;
int ARClessthanwindowCount = 0;
int tMACNotMatchedSyncFrame = 0;
int tMACNotMatchedReSyncFrame = 0;
int tMACMatched = 0;
int IPDUDLCZeroCount = 0;
int IPDUDLCEightCount = 0;
int invalidpaddingCount = 0;
int invalidContainerFrame = 0;
oSheet.Cells[2, 3] = "Log Analysis Report";
oSheet.Cells[4, 4] = "Category";
oSheet.Cells[4, 5] = "Count";
oSheet.Cells[6, 4] = "Result";
oSheet.Cells[7, 4] = "Accepted";
oSheet.Cells[8, 4] = "Dropped";
oSheet.Cells[10, 4] = "Remarks";
oSheet.Cells[11, 4] = "Invalid MAC";
oSheet.Cells[12, 4] = "ARC Repeated";
oSheet.Cells[13, 4] = "tMAC1 matched";
oSheet.Cells[14, 4] = "tMAC2 matched";
oSheet.Cells[15, 4] = "tMAC3 matched";
oSheet.Cells[16, 4] = "Sync Frame ARC Updated";
oSheet.Cells[17, 4] = "Resync Frame ARC Updated";
oSheet.Cells[18, 4] = "MAC matched. Sync frame ARC not updated";
oSheet.Cells[19, 4] = "MAC matched. Resync frame ARC not updated";
oSheet.Cells[20, 4] = "Secured invalid frame";
oSheet.Cells[21, 4] = "ARC less than window";
oSheet.Cells[22, 4] = "tMAC Not Matched Sync Frame";
oSheet.Cells[23, 4] = "tMAC Not Matched ReSync Frame";
oSheet.Cells[24, 4] = "tMAC Matched";
oSheet.Cells[25, 4] = "Secure container frame check";
oSheet.Cells[26, 4] = "IPDU DLC =0";
oSheet.Cells[27, 4] = "IPDU DLC >8";
oSheet.Cells[28, 4] = "Invalid padding";
oSheet.Cells[29, 4] = "Invalid Container Frame";
oSheet.Cells[30, 4] = "Sync ARC jumps greater than 1 million";
oSheet.get_Range("E7", "E30").HorizontalAlignment =
Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
oSheet.get_Range("C2", "F2").HorizontalAlignment =
Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
oSheet.get_Range("C2", "F2").Font.Bold = true;
oSheet.get_Range("C2", "F2").Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue);
oSheet.get_Range("D4", "E4").Font.Bold = true;
oSheet.get_Range("D4", "E4").Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue);
oSheet.get_Range("D4", "E4").VerticalAlignment =
Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;
oSheet.get_Range("D6", "E6").Font.Bold = true;
oSheet.get_Range("D6", "E6").Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue);
oSheet.get_Range("D6", "E6").VerticalAlignment =
Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;
oSheet.get_Range("D10", "E10").Font.Bold = true;
oSheet.get_Range("D10", "E10").Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue);
oSheet.get_Range("D10", "E10").VerticalAlignment =
Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;
oSheet.get_Range("D25", "E25").Font.Bold = true;
oSheet.get_Range("D25", "E25").Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue);
oSheet.get_Range("D25", "E25").VerticalAlignment =
Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;
oSheet.get_Range("D30", "E30").Font.Bold = true;
oSheet.get_Range("D30", "E30").Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue);
oSheet.get_Range("D30", "E30").VerticalAlignment =
Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;
oRng = oSheet.get_Range("C2", "F2");
oRng.Borders.Color = System.Drawing.Color.Black.ToArgb();
oRng = oSheet.get_Range("D4", "D30");
oRng.Borders.Color = System.Drawing.Color.Black.ToArgb();
oRng = oSheet.get_Range("E4", "E30");
oRng.Borders.Color = System.Drawing.Color.Black.ToArgb();
oSheet.Range[oSheet.Cells[2, 3], oSheet.Cells[2, 6]].Merge();
oRng = oSheet.get_Range("D4", "E4");
oRng.EntireColumn.AutoFit();
//backgroundWorker1.ReportProgress(3,0);
backgroundWorker1.ReportProgress(5);
percentageCounter = 5;
fileCount = 0;
foreach (String file in lstFileName)
{
//GC.Collect();
//GC.WaitForPendingFinalizers();
Thread.Sleep(1000);
Microsoft.Office.Interop.Excel.Application appCSVToExcel;
Excel.Application appHighlight;
string name = file.Split('.')[0].ToString().Split('\\').Last();
//Converting each file from .csv to excel
appCSVToExcel = new Microsoft.Office.Interop.Excel.Application();
appCSVToExcel.DisplayAlerts = false;
Microsoft.Office.Interop.Excel.Workbook wbCSVToExcel = appCSVToExcel.Workbooks.Open(file, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
wbCSVToExcel.SaveAs(outputFolderPath + "\\" + name + ".xlsx", Excel.XlFileFormat.xlOpenXMLWorkbook, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
wbCSVToExcel.Close();
appCSVToExcel.Quit();
//int generation_3 = System.GC.GetGeneration(appCSVToExcel);
//System.GC.Collect(generation_3);
Marshal.ReleaseComObject(wbCSVToExcel);
Marshal.ReleaseComObject(appCSVToExcel);
//appCSVToExcel =null;
//wbCSVToExcel = null;
//GC.Collect();
//GC.WaitForPendingFinalizers();
//Thread.Sleep(2);
//backgroundWorker1.ReportProgress(10);
//Highlighting the excel files
//Application.DoEvents();
//GC.Collect();
appHighlight = new Excel.Application();
var wbHighlight = appHighlight.Workbooks;
var workbook = wbHighlight.Open(outputFolderPath + "\\" + name + ".xlsx", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Microsoft.Office.Interop.Excel.Worksheet worksheet = workbook.ActiveSheet;
Microsoft.Office.Interop.Excel.Range usedRange = worksheet.UsedRange;
Microsoft.Office.Interop.Excel.Range rows = usedRange.Rows;
Microsoft.Office.Interop.Excel.Range columns = usedRange.Columns;
appHighlight.DisplayAlerts = false;
r = rows.Count;
c = columns.Count;
var startCell = (Microsoft.Office.Interop.Excel.Range)worksheet.Cells[1, 1];
var endCell = (Microsoft.Office.Interop.Excel.Range)worksheet.Cells[r, 12];
object[,] RangeValues = worksheet.get_Range(startCell, endCell).Value2;
ArrayList higlight = new ArrayList();
for (int i = 1; i <= r; i++)
{
if (RangeValues[i, 8] != null)
{
//if (RangeValues[i, 9].ToString() == "Invalid MAC"
//|| RangeValues[i, 9].ToString() == "ARC Repeated"
//|| RangeValues[i, 9].ToString() == "Secured invalid frame"
//|| RangeValues[i, 9].ToString() == "ARC less than window")
if (RangeValues[i, 8].ToString() == "Dropped")
{
higlight.Add(i);
}
}
//Thread.Sleep(2);
//backgroundWorker1.ReportProgress(20);
string firstCellValue1 = "";
if (RangeValues[i, 8] != null)
{
firstCellValue1 = RangeValues[i, 8].ToString();
}
if (firstCellValue1 == "Accepted")
{
acceptedCount++;
}
if (firstCellValue1 == "Dropped")
{
droppedCount++;
}
string cell = "";
if (RangeValues[i, 9] != null)
{
cell = RangeValues[i, 9].ToString();
}
switch (cell)
{
case "Invalid MAC":
invalidMACCount++;
break;
case "ARC Repeated":
ARCRepeatedCount++;
break;
case "tMAC1 matched":
tMAC1matchedCount++;
break;
case "tMAC2 matched":
tMAC2matchedCount++;
break;
case "tMAC3 matched":
tMAC3matchedCount++;
break;
case "Sync Frame ARC Updated":
syncFrameARCUpdatedCount++;
break;
case "Resync Frame ARC Updated":
resyncFrameARCUpdatedCount++;
break;
case "MAC matched. Sync frame ARC not updated":
syncFrameARCNotUpdatedCount++;
break;
case "MAC matched. Resync frame ARC not updated":
resyncFrameARCNotUpdatedCount++;
break;
case "ARC less than window":
ARClessthanwindowCount++;
break;
case "tMAC Matched":
tMACmatchedCount++;
break;
case "tMAC Not Matched Sync Frame":
tMACNotMatchedSyncFrame++;
break;
case "tMAC Not Matched ReSync Frame":
tMACNotMatchedReSyncFrame++;
break;
default:
break;
}
string cellReceptionRemarks = "";
if (RangeValues[i, 12] != null)
{
cellReceptionRemarks = RangeValues[i, 12].ToString();
}
switch (cellReceptionRemarks)
{
case "Zero DLC of 'contained I-PDU' has been detected.":
IPDUDLCZeroCount++;
break;
case "DLC greater than 8 in 'contained I-PDU' has been detected.":
IPDUDLCEightCount++;
break;
case "Padding other than 0x00 or 0xFF is observed in frame":
invalidpaddingCount++;
break;
case "Invalid container frame structure.":
invalidContainerFrame++;
break;
}
//backgroundWorker1.ReportProgress(25,0);
//percentageCounterFile++;
//int countProcessFile = r;
//percentFile = 100 - (((countProcessFile - percentageCounterFile) * 100) / countProcessFile);
//backgroundWorker1.ReportProgress(percentFile);
}
for (int k = 0; k < higlight.Count; k++)
{
string exclcmnS1 = "A" + higlight[k];
string exclcmnL1 = "L" + higlight[k];
Excel.Range _range1;
_range1 = worksheet.get_Range(exclcmnS1, exclcmnL1);
_range1.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Pink);
_range1.Font.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red);
}
workbook.SaveAs(outputFolderPath + "\\" + name + ".xlsx", Excel.XlFileFormat.xlOpenXMLWorkbook, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
// GC.Collect();
//GC.WaitForPendingFinalizers();
//GC.Collect();
//GC.WaitForPendingFinalizers();
int generation = System.GC.GetGeneration(appHighlight);
System.GC.Collect(generation);
//int generation_4 = System.GC.GetGeneration(wbHighlight);
//System.GC.Collect(generation_4);
//int generation_5 = System.GC.GetGeneration(workbook);
//System.GC.Collect(generation_4);
//int generation_6 = System.GC.GetGeneration(worksheet);
//System.GC.Collect(generation_4);
//int generation_7 = System.GC.GetGeneration(usedRange);
//System.GC.Collect(generation_4);
//int generation_8 = System.GC.GetGeneration(rows);
//System.GC.Collect(generation_4);
//int generation_9 = System.GC.GetGeneration(columns);
//System.GC.Collect(generation_4);
wbHighlight.Close();
//workbook.Close(0);
appHighlight.Quit();
//usedRange.Clear();
//rows.Clear();
//columns.Clear();
while (Marshal.ReleaseComObject(appHighlight) != 0) { }
while (Marshal.ReleaseComObject(wbHighlight) != 0) { }
while (Marshal.ReleaseComObject(workbook) != 0) { }
while (Marshal.ReleaseComObject(worksheet) != 0) { }
while (Marshal.ReleaseComObject(usedRange) != 0) { }
while (Marshal.ReleaseComObject(rows) != 0) { }
while (Marshal.ReleaseComObject(columns) != 0) { }
//while (Marshal.ReleaseComObject(worksheet.get_Range(startCell, endCell)) != 0) { }
//while (Marshal.ReleaseComObject(RangeValues) != 0) { }
//while (Marshal.ReleaseComObject(_range1) != 0) { }
appHighlight = null;
wbHighlight = null;
workbook = null;
worksheet = null;
usedRange = null;
rows = null;
columns = null;
RangeValues = null;
//_range1 = null;
//startCell = null;
//endCell = null;
//higlight = null;
//KillSpecificExcelFileProcess(name + ".xlsx");
//Thread.Sleep(2);
//backgroundWorker1.ReportProgress(60,0);
//GC.Collect();
//GC.WaitForPendingFinalizers();
//var processes = from p in Process.GetProcessesByName("EXCEL") select p;
//foreach (var process in processes)
//{
// process.Kill();
//}
//For Abnormal ARC
//rch_updates.AppendText(DateTime.Now.ToString("t") + " " + "Analyzing file : "+file +" for Abnormal ARC Increments.\n");
// Application.DoEvents();
var excel_Report = new excel.Application();
var excelWB = excel_Report.Workbooks.Add();
var workSheet = excelWB.ActiveSheet;
dict_ADAS = new Dictionary<Int64, Int64>();
dict_BCM = new Dictionary<Int64, Int64>();
dict_CDM = new Dictionary<Int64, Int64>();
dict_AVM = new Dictionary<Int64, Int64>();
dict_SONAR = new Dictionary<Int64, Int64>();
dict_PWT = new Dictionary<Int64, Int64>();
dict_ATCU = new Dictionary<Int64, Int64>();
// List of class Logdata
data = new List<LogData>();
dict_LogData = new Dictionary<Int64, LogData>();
List<string> lines = new List<string>();
workSheet.Name = "Abnormal ARC Observations";
excel_Report.Visible = false;
workSheet.Cells[1, "A"] = "Time Stamp";
workSheet.Cells[1, "B"] = "CAN ID";
workSheet.Cells[1, "C"] = "DLC";
workSheet.Cells[1, "D"] = "CAN PAYLOAD";
workSheet.Cells[1, "E"] = "RESULT";
workSheet.Cells[1, "F"] = "REMARK";
workSheet.Cells[1, "G"] = "ARC Difference";
//Thread.Sleep(2);
//backgroundWorker1.ReportProgress(65,0);
readCSV(file, lines);
//backgroundWorker1.ReportProgress(70,0);
categorizeSyncFrames();
//backgroundWorker1.ReportProgress(75,0);
identifyAbnormalIndices();
//backgroundWorker1.ReportProgress(80);
writeToReport(workSheet);
//Thread.Sleep(2);
//backgroundWorker1.ReportProgress(85);
dict_LogData.Clear();
dict_ATCU.Clear();
dict_ADAS.Clear();
dict_AVM.Clear();
dict_CDM.Clear();
dict_PWT.Clear();
dict_SONAR.Clear();
dict_BCM.Clear();
ADAS_Indices_List.Clear();
BCM_Indices_List.Clear();
CDM_Indices_List.Clear();
AVM_Indices_List.Clear();
SONAR_Indices_List.Clear();
PWT_Indices_List.Clear();
ATCU_Indices_List.Clear();
data.Clear();
dict_LogData.Clear();
excel_Report.DisplayAlerts = false;
excelWB.SaveAs(outputFolderPath + "\\" + "Abnormal_ARC_Increment" + DateTime.Now.ToLongDateString() + ".xlsx", excel.XlFileFormat.xlOpenXMLWorkbook, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
//GC.Collect();
//GC.WaitForPendingFinalizers();
int generation_2 = System.GC.GetGeneration(excel_Report);
System.GC.Collect(generation_2);
excelWB.Close(0);
excel_Report.Quit();
//rch_updates.AppendText(DateTime.Now.ToString("t") + " " + "File Analysis complete for : " + file + " for Abnormal ARC Increments.\n");
while (Marshal.ReleaseComObject(excel_Report) != 0) { }
while (Marshal.ReleaseComObject(excelWB) != 0) { }
while (Marshal.ReleaseComObject(workSheet) != 0) { }
excel_Report = null;
excelWB = null;
workSheet = null;
fileCount++;
percentageCounter += file_progress_Delta;
backgroundWorker1.ReportProgress(percentageCounter);
}
oSheet.Cells[7, 5] = acceptedCount;
oSheet.Cells[8, 5] = droppedCount;
oSheet.Cells[11, 5] = invalidMACCount;
oSheet.Cells[12, 5] = ARCRepeatedCount;
oSheet.Cells[13, 5] = tMAC1matchedCount;
oSheet.Cells[14, 5] = tMAC2matchedCount;
oSheet.Cells[15, 5] = tMAC3matchedCount;
oSheet.Cells[16, 5] = syncFrameARCUpdatedCount;
oSheet.Cells[17, 5] = resyncFrameARCUpdatedCount;
oSheet.Cells[18, 5] = syncFrameARCNotUpdatedCount;
oSheet.Cells[19, 5] = resyncFrameARCNotUpdatedCount;
oSheet.Cells[20, 5] = securedinvalidframeCount;
oSheet.Cells[21, 5] = ARClessthanwindowCount;
oSheet.Cells[22, 5] = tMACNotMatchedSyncFrame;
oSheet.Cells[23, 5] = tMACNotMatchedReSyncFrame;
oSheet.Cells[24, 5] = tMACMatched;
oSheet.Cells[26, 5] = IPDUDLCZeroCount;
oSheet.Cells[27, 5] = IPDUDLCEightCount;
oSheet.Cells[28, 5] = invalidpaddingCount;
oSheet.Cells[29, 5] = invalidContainerFrame;
//Abnromal ARC observations count
oSheet.Cells[30, 5] = (i - 1) / 2;
backgroundWorker1.ReportProgress(85);
oXL.Visible = false;
oXL.UserControl = false;
oXL.ActiveWindow.DisplayGridlines = false;
oXL.DisplayAlerts = false;
oWB.SaveAs(outputFolderPath + "\\" + DateTime.Now.ToLongDateString() + "Report.xlsx", Excel.XlFileFormat.xlOpenXMLWorkbook, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
oWB.Close(0);
oXL.Quit();
backgroundWorker1.ReportProgress(90);
//Marshal.FinalReleaseComObject(oSheet);
//Marshal.FinalReleaseComObject(oWB);
//Marshal.FinalReleaseComObject(oXL);
//Marshal.FinalReleaseComObject(oRng);
while (Marshal.ReleaseComObject(oXL) != 0) { }
while (Marshal.ReleaseComObject(oWB) != 0) { }
while (Marshal.ReleaseComObject(oSheet) != 0) { }
while (Marshal.ReleaseComObject(oRng) != 0) { }
oXL = null;
oWB = null;
oSheet = null;
oRng = null;
//KillSpecificExcelFileProcess(DateTime.Now.ToLongDateString() + "Report.xlsx");
//Thread.Sleep(2);
backgroundWorker1.ReportProgress(100);
//progressBar3.Value = 100;
e.Result = true;
}
catch (Exception ex)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
MessageBox.Show(ex.ToString());
//wbHighlight.Close();
//appHighlight.Quit();
//int generation = System.GC.GetGeneration(appHighlight);
//System.GC.Collect(generation);
var processes = from p in Process.GetProcessesByName("EXCEL") select p;
foreach (var process in processes)
{
process.Kill();
}
}
finally
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
//wbHighlight.Close();
//appHighlight.Quit();
//int generation = System.GC.GetGeneration(appHighlight);
//System.GC.Collect(generation);
var processes = from p in Process.GetProcessesByName("EXCEL") select p;
foreach (var process in processes)
{
process.Kill();
}
}

Why do you create new Excel instance for each file ? Try to create one excel instance and just close the workbook and open a new one for each file.
It is bad practice to call GC.Collect manually (GC is quite smart to collect object instances if there is no alive dependencies).
You do not have to copy the same code from finally to catch - finally is executed always.
Why do you think that Excel causes out of memory? What about identifyAbnormalIndices, writeToReport, writeToReport methods? Seems that there are a lot of global variables, like dictionaries you are creating.
Are you using using when working with file/stream in the readCSV method?
Is there really need to store int64 in the Dictionary btw? Can you use int32 ?
Try to use VS memory dumps and check what kind of objects are being kept in the memory. Just run the program under debug and take memory dump after one file was processed. Then you can compare the dumps, check the diff and you will get some imagine what objects are not collected by the GC.
UPD link provided by #bradbury9 should be taken into account as well.

Related

C# Datatable linq condiction check

I have created the function shown below. Everything is working fine, the challenge now, is that I have some scenarios where it would be ideal to have the constructor 'RadGridView grid' as a Datatable. I'm looking for a constructor that can take the input type of 'RadGridView' or type of 'Datatable' - a kind of "universal" constructor, if that is possiple?
public static void Export(RadGridView grid, string sheetName)
{
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "Excel file |*.xlsx";
saveFileDialog1.Title = "Save";
saveFileDialog1.ShowDialog();
if (saveFileDialog1.FileName != "")
{
Microsoft.Office.Interop.Excel._Application app = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel._Workbook workbook = app.Workbooks.Add(Type.Missing);
Microsoft.Office.Interop.Excel._Worksheet worksheet = null;
app.Visible = false;
worksheet = workbook.Sheets["Sheet1"];
worksheet = workbook.ActiveSheet;
worksheet.Name = sheetName;
Microsoft.Office.Interop.Excel.Range aRange = worksheet.UsedRange;
workbook.Worksheets[1].Cells.NumberFormat = "#";
for (int i = 1; i < grid.Columns.Count + 1; i++)
{
worksheet.Cells[1, i] = grid.Columns[i - 1].HeaderText;
}
for (int i = 0; i < grid.Rows.Count; i++)
{
for (int j = 0; j < grid.Columns.Count; j++)
{
worksheet.Cells[i + 2, j + 1] = grid.Rows[i].Cells[j].Value.ToString();
}
}
aRange.Value = aRange.Value;
aRange.Cells.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignLeft;
worksheet.Columns.AutoFit();
workbook.SaveAs(saveFileDialog1.FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
app.Quit();
}
}
Thanks in advance!
I solved this by using the 'dynamic' keyword.

C# Appending list to excel file

so currently my code below generates a string and adds it to a list for each image file in a directory, then after its does adding to the list, it opens an excel file, appends the list, and formats it. Currently my problem is that my excel line is selecting the entireColumn and pasting the list, how can I get it to recognize how many strings are in the list and only append that many to the excel sheet.
//Fill A2:B6 with an array of values .
oRng = oSheet.get_Range("C2");
oRng.EntireColumn.Value2 = checkInformation.ToArray();
Here is my whole project
class Program
{
[STAThread]
static void Main(string[] args)
{
Microsoft.Office.Interop.Excel.Application oXL;
Microsoft.Office.Interop.Excel._Workbook oWB;
Microsoft.Office.Interop.Excel._Worksheet oSheet;
Microsoft.Office.Interop.Excel.Range oRng;
object misvalue = System.Reflection.Missing.Value;
Console.WriteLine("Initializing Check Parser Menu.....");
string dataPath = #"C:\Users\User\Desktop\Tesseract\Tesseract\tessdata";
string[] filePaths = Directory.GetFiles(#"C:\Users\User\Desktop\Tesseract\Tesseract\Check_Images", "*.png");
string checkData = "";
int checkCounter = 0;
List<string> checkInformation = new List<string>();
foreach (string filePath in filePaths)
{
checkCounter++;
Console.WriteLine("Initializing Check Parser... on Check: " + checkCounter);
using (TesseractEngine ocr = new TesseractEngine(dataPath, "eng", EngineMode.TesseractOnly))
{
using (Pix p = Pix.LoadFromFile(filePath))
{
using (Pix img = p.Scale(2, 3))
{
using (var page = ocr.Process(img))
{
string text = page.GetText();
if (text.Contains("Claim ID"))
{
int indexOfNone = text.IndexOf("NONE");
int indexOfClaimId = text.IndexOf("Claim ID");
int difference = indexOfClaimId - indexOfNone;
var dollarData = text.Substring(indexOfNone, difference);
int startingPoint = indexOfNone + (dollarData.Length - 6);
var dollarAmount = text.Substring(startingPoint, 6);
var claimIdData = text.Substring(indexOfClaimId, 14);
var claimInfoOutput = claimIdData + " Check Amount: " + dollarAmount;
Console.WriteLine(claimInfoOutput);
checkInformation.Add(claimInfoOutput);
}
else
{
Console.WriteLine("You will need to locate this check, there was an issue parsing " + "\n" + filePath);
Console.WriteLine("Press any Key to continue");
Console.ReadKey();
}
}
}
}
}
}
Console.WriteLine("Writing Data to Excel File... DONT TaCH");
try
{
//Start Excel and get Application object.
oXL = new Microsoft.Office.Interop.Excel.Application();
oXL.Visible = true;
//Get a new workbook.
oWB = (Microsoft.Office.Interop.Excel._Workbook)(oXL.Workbooks.Add(""));
oSheet = (Microsoft.Office.Interop.Excel._Worksheet)oWB.ActiveSheet;
//Add table headers going cell by cell. //Format A1:B1 as bold, vertical alignment = center.
oSheet.Cells[1, 1] = "Claim ID";
oSheet.Cells[1, 2] = "Check Amount";
oSheet.get_Range("A1", "B1").Font.Bold = true;
oSheet.get_Range("A1", "B1").VerticalAlignment = Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;
// Create an array to multiple values at once.
//Fill A2:B6 with an array of values .
oRng = oSheet.get_Range("C2");
oRng.Value2 = checkInformation.ToArray();
//oSheet.get_Range("A2", "B6").Value2 = checkInformation.ToArray();
//Fill A2 with a formula(=MID(C2,9,5)
oRng = oSheet.get_Range("A2", "A50");
oRng.Formula = "=MID(C2,9,5)";
//Fill B2 with a =RIGHT(C2,6)
oRng = oSheet.get_Range("B2", "B50");
oRng.Formula = "=RIGHT(C2,6)";
//AutoFit columns A:C.
oRng = oSheet.get_Range("A1", "C1");
oRng.EntireColumn.AutoFit();
oXL.Visible = false;
oXL.UserControl = false;
oWB.SaveAs("C:\\Users\\User\\Desktop\\Tesseract\\Tesseract\\excel\\checkdata.xlsx", Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookDefault,
Type.Missing, Type.Missing,
false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
oWB.Close();
;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
Okay I solved it guys sorry to bug you but heres what I did.
//Fill A2:B6 with an array of values .
string cellName;
int counter = 2;
foreach (var check in checkInformation)
{
cellName = "C" + counter.ToString();
oRng = oSheet.get_Range(cellName, cellName);
oRng.Value2 = check.ToString();
++counter;
}
and basically i just need to say for each item in my list this is the first cell name append the value.tostring

C# Excel Write to multiple cells

Hi i try to get better with the c# excel stuff. Right now i try to select some values from an existing excelsheet. For Example: From B4 to C16. So i can replace the values with something else but i dont get it to work.
This is my little method:
public void writeExcelFile()
{
string path = #"C:\Users\AAN\Documents\Visual Studio 2015\Projects\WorkWithExcel\WorkWithExcel\bin\Debug\PROJEKTSTATUS_GESAMT_neues_Layout.xlsm";
oXL = new Excel.Application();
oXL.Visible = true;
oXL.DisplayAlerts = false;
mWorkBook = oXL.Workbooks.Open(path, 0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false);
//Get all the sheets in the workbook
mWorkSheets = mWorkBook.Worksheets;
//Get the allready exists sheet
mWSheet1 = (Excel.Worksheet)mWorkSheets.get_Item(1);
//Excel.Range range = mWSheet1.UsedRange;
//int colCount = range.Columns.Count;
//int rowCount = range.Rows.Count;
int countRows = mWSheet1.UsedRange.Rows.Count;
int countColumns = mWSheet1.UsedRange.Columns.Count;
object[,] data = mWSheet1.Range[mWSheet1.Cells[1, 1], mWSheet1.Cells[countRows, countColumns]].Cells.Value2;
for (int index = 1; index < 15; index++)
{
mWSheet1.Cells[countRows + index, 1] = countRows + index;
mWSheet1.Cells[countRows + index, 2] = "test" + index;
}
//Excel.Worksheet sheet = workbook.ActiveSheet;
//Excel.Range rng = (Excel.Range)sheet.get_Range(sheet.Cells[1, 1], sheet.Cells[3, 3]);
mWorkBook.SaveAs(path, Excel.XlFileFormat.xlOpenXMLWorkbookMacroEnabled,Missing.Value, Missing.Value, Missing.Value, Missing.Value, Excel.XlSaveAsAccessMode.xlExclusive,Missing.Value, Missing.Value, Missing.Value,Missing.Value, Missing.Value);
mWorkBook.Close(Missing.Value, Missing.Value, Missing.Value);
mWSheet1 = null;
mWorkBook = null;
oXL.Quit();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
I tried it with get_range but i get an exception that this is not aviable.
It has something to do with the Microsoft.Office.Interop libary 14. Then i tried it with object[,] but the only thing i got to work is that after all used cells to insert test but not to select anything. So any help would be great.
Thanks for your Time and sorry for my english.
EDIT: At least the read process works now and i loop trough a selected range.
Here is the working code:
public void writeExcelFile()
{
String inputFile = #"C:\Users\AAN\Documents\Visual Studio 2015\Projects\WorkWithExcel\WorkWithExcel\bin\Debug\PROJEKTSTATUS_GESAMT_neues_Layout.xlsm";
Excel.Application oXL = new Excel.Application();
#if DEBUG
oXL.Visible = true;
oXL.DisplayAlerts = true;
#else
oXL.Visible = false;
oXL.DisplayAlerts = false;
#endif
//Open the Excel File
Excel.Workbook oWB = oXL.Workbooks.Open(inputFile);
String SheetName = "Gesamt";
Excel._Worksheet oSheet = oWB.Sheets[SheetName];
String start_range = "B4";
String end_range = "R81";
Object[,] values = oSheet.get_Range(start_range, end_range).Value2;
int t = values.GetLength(0);
for (int i = 1; i <= values.GetLength(0); i++)
{
String val = values[i, 1].ToString();
}
oXL.Quit();
}
After many tries i finnaly got a working solution where i can select any cells i want. Maby there are better ways but for me it works as expected.
the code:
public void writeExcelFile()
{
try
{
String inputFile = #"C:\Users\AAN\Documents\Visual Studio 2015\Projects\WorkWithExcel\WorkWithExcel\bin\Debug\PROJEKTSTATUS_GESAMT_neues_Layout.xlsm";
Excel.Application oXL = new Excel.Application();
#if DEBUG
oXL.Visible = true;
oXL.DisplayAlerts = true;
#else
oXL.Visible = false;
oXL.DisplayAlerts = false;
#endif
//Open a Excel File
Excel.Workbook oWB = oXL.Workbooks.Add(inputFile);
Excel._Worksheet oSheet = oWB.ActiveSheet;
List<String> Name = new List<String>();
List<Double> Percentage = new List<Double>();
Name.Add("Anil");
Name.Add("Vikas");
Name.Add("Ashwini");
Name.Add("Tobias");
Name.Add("Stuti");
Name.Add("Raghavendra");
Name.Add("Chithra");
Name.Add("Glen");
Name.Add("Darren");
Name.Add("Michael");
Percentage.Add(78.5);
Percentage.Add(65.3);
Percentage.Add(56);
Percentage.Add(56);
Percentage.Add(97);
Percentage.Add(89);
Percentage.Add(85);
Percentage.Add(76);
Percentage.Add(78);
Percentage.Add(89);
oSheet.Cells[1, 1] = "Name";
oSheet.Cells[1, 2] = "Percentage(%)"; // Here 1 is the rowIndex and 2 is the columnIndex.
//Enter the Header data in Column A
int i = 0;
for (i = 0; i < Name.Count; i++)
{
oSheet.Cells[i + 2, 1] = Name[i];
}
//Enter the Percentage data in Column B
for (i = 0; i < Percentage.Count; i++)
{
oSheet.Cells[i + 2, 2] = Percentage[i];
}
oSheet.Cells[Name.Count + 3, 1] = "AVERAGE";
//Obtain the Average of the Percentage Data
string currentFormula = "=AVERAGE(B2:" + "B" + Convert.ToString(Percentage.Count + 1) + ")";
oSheet.Cells[Percentage.Count + 3, 2].Formula = currentFormula;
//Format the Header row to make it Bold and blue
oSheet.get_Range("A1", "B1").Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.AliceBlue);
oSheet.get_Range("A1", "B1").Font.Bold = true;
//Set the column widthe of Column A and Column B to 20
oSheet.get_Range("A1", "B12").ColumnWidth = 20;
//String ReportFile = #"D:\Excel\Output.xls";
oWB.SaveAs(inputFile, Excel.XlFileFormat.xlOpenXMLWorkbookMacroEnabled,
Type.Missing, Type.Missing,
false,
false,
Excel.XlSaveAsAccessMode.xlNoChange,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing);
oXL.Quit();
Marshal.ReleaseComObject(oSheet);
Marshal.ReleaseComObject(oWB);
Marshal.ReleaseComObject(oXL);
oSheet = null;
oWB = null;
oXL = null;
GC.GetTotalMemory(false);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.GetTotalMemory(true);
}
catch (Exception ex)
{
String errorMessage = "Error reading the Excel file : " + ex.Message;
MessageBox.Show(errorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
This is not my own code its from a blog: the blog where i got it just edited so it works for me.

Modify Interop Excel for Opening Existing File

I'm using Excel Interop for C# to export a datagridview to Excel and print it. I'm using this code:
try
{
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
excel.Application.Workbooks.Add(true);
int ColumnIndex = 0;
int rowIndex = -1;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
rowIndex++;
ColumnIndex = 0;
foreach (DataGridViewColumn col in dataGridView1.Columns)
{
ColumnIndex++;
excel.Cells[rowIndex + 1, ColumnIndex] = row.Cells[col.Name].Value;
}
}
excel.Visible = true;
excel.DisplayAlerts = false;
Worksheet worksheet = (Worksheet)excel.ActiveSheet;
worksheet.Activate();
worksheet.Cells.Style.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
worksheet.Range[worksheet.Cells[1, 1], worksheet.Cells[1, 7]].Merge();
worksheet.Range[worksheet.Cells[2, 1], worksheet.Cells[2, 7]].Merge();
worksheet.Range[worksheet.Cells[3, 1], worksheet.Cells[3, 7]].Merge();
worksheet.Range[worksheet.Cells[4, 1], worksheet.Cells[4, 4]].Merge();
worksheet.Cells[1, 1].Font.Bold = true;
worksheet.Range["A1"].Cells.Font.Size = 15;
worksheet.Range["A4"].Cells.Font.Size = 15;
worksheet.Range["B7"].Cells.Font.Size = 15;
worksheet.Range["B8"].Cells.Font.Size = 15;
worksheet.Range["B9"].Cells.Font.Size = 15;
worksheet.Range["A11"].Cells.Font.Size = 15;
worksheet.Range["B13"].Cells.Font.Size = 15;
worksheet.PrintOut(Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
GC.Collect();
GC.WaitForPendingFinalizers();
excel.Quit();
}
catch (Exception ex)
{
MessageBox.Show("Error de exportación.");
}
It works fine, but I need to open an existing file to do this same thing to avoid reconfiguration of the printing margins. I checked other similar questions and tried to apply the "workBook = oXL.Workbooks.Open("path", ...);" but it can make it work. Any thoughts?
To open a file use the open method.
Microsoft.Office.Interop.Excel.Workbooks wkbks = null;
Microsoft.Office.Interop.Excel.Workbook wkbk = null;
wkbks = excel.Workbooks;
wkbk = wkbks.Open(xlsFileName);
At the end of your method you should do a cleanup on all your interop variables:
if (wkbk != null)
{
try
{
wkbk.Close(false);
}
catch
{
}
Marshal.FinalReleaseComObject(wkbk);
wkbk = null;
}

written code for Autofit in c# for Excel sheet. Everything is perfect. but the Excel.exe is still running even after clearing com componets

This is my code. I am trying to export gridview to excel with some of the cells with color and autofit. The problem here is everything is working fine except the EXCEL.EXE running in the background. But If i exclude code for Autofit and coloring cells, then the Excel Task is terminated.
Below is my code
protected void xlsWorkBook()
{
try
{
Excel.Application oXL;
Excel.Workbook oWB;
Excel.Workbooks oWBs;
Excel.Worksheet oSheet;
Excel.Range oRange;
// Start Excel and get Application object.
oXL = new Excel.Application();
// Set some properties
oXL.Visible = false;
oXL.DisplayAlerts = false;
// Get a new workbook.
oWBs = oXL.Workbooks;
oWB = oWBs.Add(1);
oSheet = oWB.ActiveSheet;
DataGridView dataGridExport = new DataGridView();
dataGridExport.DataSource = GetData();
bool isColorCells = false;
oRange = oSheet.Cells;
for (int k = 1; k <= dataGridExport.Columns.Count; k++)
{
//oRange.set_Item(1, k, dataGridExport.Columns[k - 1].Name);
oSheet.Cells[1, k] = dataGridExport.Columns[k - 1].Name;
((dynamic)oSheet.Cells[1, k]).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.SteelBlue);
}
for (int i = 1; i <= dataGridExport.Rows.Count; i++)
{
for (int k = 1; k <= dataGridExport.Rows[i - 1].Cells.Count; k++)
{
if (Convert.ToString(dataGridExport.Rows[i - 1].Cells[k - 1].Value) != string.Empty)
{
//oRange.set_Item(i + 1, k, dataGridExport.Rows[i - 1].Cells[k - 1].Value);
oSheet.Cells[i + 1, k] = dataGridExport.Rows[i - 1].Cells[k - 1].Value;
}
if ((isColorCells) && (dataGridExport.Rows[i - 1].Cells[k - 1].Style.BackColor.ToArgb() != 0))
{
//oRange.Interior.Color = Color.Red;
((dynamic)oSheet.Cells[i + 1, k]).Interior.Color = ColorTranslator.ToOle(Color.FromArgb(dataGridExport.Rows[i - 1].Cells[k - 1].Style.BackColor.ToArgb()));
}
}
}
dataGridExport = null;
oSheet.Columns.AutoFit();
//oRange.EntireColumn.AutoFit();
// Save the sheet and close
//oSheet = null;
//oRange = null;
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "Excel File|*.xlsx";
saveFileDialog1.Title = "Save an Excel File";
saveFileDialog1.ShowDialog();
if (saveFileDialog1.FileName != "")
{
oWB.SaveAs(saveFileDialog1.FileName, Excel.XlFileFormat.xlOpenXMLWorkbook, Missing.Value, Missing.Value, false, false, Excel.XlSaveAsAccessMode.xlNoChange,
Excel.XlSaveConflictResolution.xlUserResolution, true, Missing.Value, Missing.Value, Missing.Value);
}
GC.Collect();
GC.WaitForPendingFinalizers();
oWB.Close();
oXL.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(oRange);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oSheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWB);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWBs);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oXL);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}
catch (Exception ex)
{
lblError.Text = ex.Message;
}
this.Cursor = Cursors.Default;
}
Moving Range to different function solved my problem. The Excel.exe is not running at the background anymore. But i am not sure why. Somebody can give explanation for this?
protected void xlsWorkBook()
{
Excel.Application oXL;
Excel.Workbook oWB;
Excel.Worksheet oSheet;
// Start Excel and get Application object.
oXL = new Excel.Application();
// Set some properties
//oXL.Visible = false;
oXL.DisplayAlerts = false;
// Get a new workbook.
oWB = oXL.Workbooks.Add(Missing.Value);
oSheet = (Excel.Worksheet)oWB.ActiveSheet;
UpdataDataToExcelSheets(oSheet,"sheet name",dataGrid1,true);
// Save the sheet and close
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "Excel File|*.xlsx";
saveFileDialog1.Title = "Save an Excel File";
saveFileDialog1.ShowDialog();
if (saveFileDialog1.FileName != "")
{
oWB.SaveAs(saveFileDialog1.FileName, Excel.XlFileFormat.xlOpenXMLWorkbook, Missing.Value, Missing.Value, false, false, Excel.XlSaveAsAccessMode.xlNoChange,
Excel.XlSaveConflictResolution.xlUserResolution, true, Missing.Value, Missing.Value, Missing.Value);
}
oWB.Close();
oXL.Quit();
//// Clean up
if (oSheet != null)
{
Marshal.FinalReleaseComObject(oSheet);
oSheet = null;
}
if (oWB != null)
{
Marshal.FinalReleaseComObject(oWB);
oWB = null;
}
if (oXL.Workbooks != null)
{
Marshal.FinalReleaseComObject(oXL.Workbooks);
}
if (oXL != null)
{
Marshal.FinalReleaseComObject(oXL);
oXL = null;
}
//// NOTE: When in release mode, this does the trick
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}
private void UpdataDataToExcelSheets(Excel.Worksheet oSheet,string sheetName, DataGridView dataGridExport,bool isColorCells)
{
Excel.Range oRange;
oSheet.Name = sheetName;
for (int k = 1; k <= dataGridExport.Columns.Count; k++)
{
oSheet.Cells[1, k] = dataGridExport.Columns[k - 1].Name;
((dynamic)oSheet.Cells[1, k]).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.SteelBlue);
}
for (int i = 1; i <= dataGridExport.Rows.Count; i++)
{
for (int k = 1; k <= dataGridExport.Rows[i - 1].Cells.Count; k++)
{
if (Convert.ToString(dataGridExport.Rows[i - 1].Cells[k - 1].Value) != string.Empty)
{
oSheet.Cells[i + 1, k] = dataGridExport.Rows[i - 1].Cells[k - 1].Value;
}
if ((isColorCells)&&(dataGridExport.Rows[i - 1].Cells[k - 1].Style.BackColor.ToArgb() != 0))
{
((dynamic)oSheet.Cells[i + 1, k]).Interior.Color = ColorTranslator.ToOle(Color.FromArgb(dataGridExport.Rows[i - 1].Cells[k - 1].Style.BackColor.ToArgb()));
}
}
}
oRange = oSheet.Range[oSheet.Cells[1, 1],
oSheet.Cells[dataGridExport.Rows.Count - 1, dataGridExport.Columns.Count + 1]];
oRange.EntireColumn.AutoFit();
if (oRange != null)
{
Marshal.FinalReleaseComObject(oRange);
oRange = null;
}
}

Categories

Resources