Error in saving/opening file after deploying .net C# MVC application - c#

In my MVC application I am exporting data to excel using Microsoft.Office.Interop.Excel .
I have also enabled ASP.NET Impersonation and gave the authentication details. It writes data to excel but it doesn't save or opens the excel file. It throws a exception Exception from HRESULT: 0x800A03EC. I will be so glad if anyone could help. thanks in advance.
My code for Export is:
public static void ExportExcel(this DataTable Tbl, string ExcelFilePath = null)
{
ExcelFilePath = "ExportTable.xls";
try
{
if (Tbl == null || Tbl.Columns.Count == 0)
//throw new Exception("ExportToExcel: Null or empty input table!\n");
Console.WriteLine("ExportToExcel: Null or empty input table!\n");
// load excel, and create a new workbook
Excel.Application excelApp = new Excel.Application();
excelApp.Workbooks.Add();
// single worksheet
Excel._Worksheet workSheet = excelApp.ActiveSheet;
// column headings
for (int i = 0; i < Tbl.Columns.Count; i++)
{
workSheet.Cells[1, (i + 1)] = Tbl.Columns[i].ColumnName;
workSheet.Cells[1, (i + 1)].Font.Bold = true;
workSheet.Cells[1, (i + 1)].Font.Size = 12;
}
// rows
for (int i = 0; i < Tbl.Rows.Count; i++)
{
// to do: format datetime values before printing
for (int j = 0; j < Tbl.Columns.Count; j++)
{
workSheet.Cells[(i + 2), (j + 1)] = Tbl.Rows[i][j];
}
}
// works fine till here
// check fielpath
if (ExcelFilePath != null && ExcelFilePath != "")
{
try
{
workSheet.SaveAs(ExcelFilePath);
excelApp.Quit();
}
catch (Exception ex)
{
Console.WriteLine("ExportToExcel: Excel file could not be saved! Check filepath.\n"+ ex.Message);
}
}
else // no filepath is given
{
excelApp.Visible = true;
}
}
catch (Exception ex)
{
Console.WriteLine("ExportToExcel: \n" + ex.Message);
}
}

The IIS user account has to have permissions to write the file.
Search for 0x800A03EC in the following article, How to Create Excel file in ASP.NET C#

HRESULT: 0x800A03EC is an unknown (to VB.Net) COM error. This usually happens when Excel throws some error because your input or parameters were wrong. If you try your code in Excel VBA it is often easier to figure out the problem.

Related

C#, Winforms automation app throwing 0x800AC472 error when saving excel file

I am writing a winform app that reads data from an sql database, paste it into excel and then saves the file in a given location.
My current issue is i'm encountering system error : 0x800AC472 when saving down the excel file.
So far I have tried adding
GC.Collect();
GC.WaitForPendingFinalizers();
to the on click method, after calling the excel save function.
From my googling it seems as though it may be due to the COM object not being removed after usage? these GC methods were meant to clear this, but it doesn't seem to be working properly. The reason I think it's not working properly is that there is still a microsoftoffice.exe process running in task manager after executing the code and receiving the error.
Something else worthy of mention is that if i wrap the code in a try-catch, the error is pasted to the console and the excel file is saved without issue, the only issue being that the process is still running in the task manager.
Is anyone here able to help me isolate the issue in my code causing this error? Thank you.
Here is the code that is called upon button press;
else if (((DataGridView)sender).Columns[e.ColumnIndex].DataPropertyName == "Run")
{
// return SQL into datatable
var returnedDT = SQLAcess.SQLtoDataTable(dataGridView1[0, e.RowIndex].Value.ToString()!);
//find item to open
string loadstring = DataGridClass.CellColumn(dataGridView1, "Load_Location", e.RowIndex);
//finds workbook to paste into.
var SettingsDataset = XMLData.ReturnXMLDataset(2);
var workbookstring = XMLData.returnXMLcellwithcolumnname(SettingsDataset, "Data_Dump_Worksheet_name", e.RowIndex);
//find location to save it
string savestring = DataGridClass.CellColumn(dataGridView1, "Save_location", e.RowIndex);
//execute export to excel, with the locations saved from above.
GXOMIClassLibrary.My_DataTable_Extensions.ExportToExcelDetailed(returnedDT, loadstring, workbookstring, savestring);
GC.Collect();
GC.WaitForPendingFinalizers();
}
The
GXOMIClassLibrary.My_DataTable_Extensions.ExportToExcelDetailed(returnedDT, loadstring, workbookstring, savestring);
method refers to a class library I have created with this method below;
public static void ExportToExcelDetailed(this System.Data.DataTable DataTable, string ExcelLoadPath, string WorksheetName, string ExcelSavePath)
{
try
{
int ColumnsCount;
//if datatable is empty throw an exception.
if (DataTable == null || (ColumnsCount = DataTable.Columns.Count) == 0)
throw new Exception("ExportToExcel: Null or empty input table!\n");
// load excel, and create a new workbook
//Microsoft.Office.Interop.Excel.Application Excel = new Microsoft.Office.Interop.Excel.Application();
//Excel.Workbooks.Add();
var excelApp = new Excel.Application();
Excel.Workbook excelWorkbook = excelApp.Workbooks.Open(ExcelLoadPath);
//TELL THE PROGRAM WHAT WORKBOOK TO OPEN
// select the right worksheet.
var Worksheet = excelWorkbook.Sheets[WorksheetName];
// DataCells
int RowsCount = DataTable.Rows.Count;
object[,] Cells = new object[RowsCount, ColumnsCount];
for (int j = 0; j < RowsCount; j++)
for (int i = 0; i < ColumnsCount; i++)
Cells[j, i] = DataTable.Rows[j][i];
//find last row
var xlRange = (Excel.Range)Worksheet.Cells[Worksheet.Rows.Count, 1];
long lastRow = (long)xlRange.get_End(Excel.XlDirection.xlUp).Row;
long newRow = lastRow + 1;
///cells[2,1] needs to become cell below last paste
Worksheet.Range((Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[newRow, 1]), (Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[newRow + RowsCount -1, ColumnsCount])).Value = Cells;
// check fielpath
if (ExcelSavePath != null && ExcelSavePath != "")
{
try
{
Worksheet.SaveAs(ExcelSavePath);
excelApp.Quit();
// Worksheet.Close(0);
//richTextBox1("Excel file saved!");
}
catch (Exception ex)
{
throw new Exception("ExportToExcel: Excel file could not be saved! Check filepath.\n"
+ ex.Message);
excelApp.Quit();
}
}
else // no filepath is given
{
excelApp.Visible = true;
}
excelApp.Quit();
}
catch (Exception ex)
{
throw new Exception("ExportToExcel: \n" + ex.Message);
}
}
changing this part of the ExportToExcelDetailed seems to have corrected the issue;
if (ExcelSavePath != null && ExcelSavePath != "")
{
try
{
Worksheet.SaveAs(ExcelSavePath);
excelApp.Quit();
Marshal.ReleaseComObject(Worksheet);
GC.Collect();
GC.WaitForPendingFinalizers();
}
catch (Exception ex)
{
throw new Exception("ExportToExcel: Excel file could not be saved! Check filepath.\n"
+ ex.Message);
excelApp.Quit();
}
}
else // no filepath is given
{
excelApp.Visible = true;
}

excel download methods are not getting called .net core c#

GetHistoricalData(), GetAnalyticsDetail(), GetInfraAnalyticsDetail() methods are getting executed and returning the datatables dt1, dt2, dt3 but the exceldownload methods are not hitting, logs are also captured until the 'Excel Extract method call started' but the other logs are not getting logged. Any issue with the code which is written ? Find the code snippet below.
public void GetDataForExcel()
{
try {
SharedLibrary.LogManager.Logger.LogMessages("Repository - ", "Excel Extract method call started");
string folderPath = _configuration["AnalyticsData:DirectoryPath"];
if (!Directory.Exists(folderPath))
{
//If Directory (Folder) does not exists. Create it.
Directory.CreateDirectory(folderPath);
}
GetHistoricalData();
GetAnalyticsDetail();
GetInfraAnalyticsDetail();
SharedLibrary.LogManager.Logger.LogMessages("Repository - ", "Starting the save function");
excelDownload(dt1, "DummySheet1", null, null);
excelDownload(dt2, "DummySheet2", "DummySheet3", dt3);
}
catch(Exception ex)
{
SharedLibrary.LogManager.Logger.Log("Repository - ", "Excel Extract method call exception", ex);
throw (ex);
}
}
public void excelDownload(DataTable dt, String sheetName, string? sheetName1, DataTable? dTable)
{
SharedLibrary.LogManager.Logger.LogMessages("Repository - ", "Excel Download method call outside try");
try
{
SharedLibrary.LogManager.Logger.LogMessages("Repository - " , "Excel Download method call started");
Microsoft.Office.Interop.Excel.Application excel;
Microsoft.Office.Interop.Excel.Workbook excelworkBook;
Microsoft.Office.Interop.Excel.Worksheet excelSheet;
Microsoft.Office.Interop.Excel.Range excelCellrange;
// get Application object.
excel = new Microsoft.Office.Interop.Excel.Application();
excel.Visible = false;
excel.DisplayAlerts = false;
// Creation a new Workbook
excelworkBook = excel.Workbooks.Add(Type.Missing);
// Workk sheet
excelSheet = (Microsoft.Office.Interop.Excel.Worksheet)excelworkBook.ActiveSheet;
excelSheet.Name = sheetName;
// loop through each row and add values to our sheet
var rowcount = 1;
foreach (DataRow datarow in dt.Rows)
{
rowcount += 1;
for (int i = 1; i <= dt.Columns.Count; i++)
{
// on the first iteration we add the column headers
if (rowcount == 3)
{
excelSheet.Cells[1, i] = dt.Columns[i - 1].ColumnName;
}
// Filling the excel file
excelSheet.Cells[rowcount, i] = datarow[i - 1].ToString();
}
}
if (sheetName1 != null)
{
excelworkBook.Sheets.Add();
excelSheet = (Microsoft.Office.Interop.Excel.Worksheet)excelworkBook.ActiveSheet;
excelSheet.Name = sheetName1;
rowcount = 1;
foreach (DataRow datarow in dTable.Rows)
{
rowcount += 1;
for (int i = 1; i <= dTable.Columns.Count; i++)
{
// on the first iteration we add the column headers
if (rowcount == 3)
{
excelSheet.Cells[1, i] = dTable.Columns[i - 1].ColumnName;
}
// Filling the excel file
excelSheet.Cells[rowcount, i] = datarow[i - 1].ToString();
}
}
}
string folderPath = _configuration["AnalyticsData:DirectoryPath"];
string savePath = folderPath.Replace("/", "\\");
excelworkBook.SaveAs(#savePath + sheetName + ".xlsx");
SharedLibrary.LogManager.Logger.LogMessages("Repository - ", sheetName + " Saved");
excelworkBook.Close();
excel.Quit();
}
catch (Exception ex)
{
SharedLibrary.LogManager.Logger.Log("Repository - Excel Save", "Error", ex);
throw ex;
}
}

Export DataGridView to Excel (Microsoft.Office.Interop.Excel)

I'm trying to export datagridview content to Excel but I encountered the following problem.
The code that I used is below (taken from code.msdn.microsoft.com)
private void ExportToExcel()
{
// Creating a Excel object.
Microsoft.Office.Interop.Excel._Application excel = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel._Workbook workbook = excel.Workbooks.Add(Type.Missing);
Microsoft.Office.Interop.Excel._Worksheet worksheet = null;
try
{
worksheet = workbook.ActiveSheet;
worksheet.Name = "ExportedFromDatGrid";
int cellRowIndex = 1;
int cellColumnIndex = 1;
//Loop through each row and read value from each column.
for (int i = 0; i < DataGridView1.Rows.Count - 1; i++)
{
for (int j = 0; j < DataGridView1.Columns.Count; j++)
{
// Excel index starts from 1,1. As first Row would have the Column headers, adding a condition check.
if (cellRowIndex == 1)
{
worksheet.Cells[cellRowIndex, cellColumnIndex] = DataGridView1.Columns[j].HeaderText;
}
else
{
worksheet.Cells[cellRowIndex, cellColumnIndex] = DataGridView1.Rows[i].Cells[j].Value.ToString();
}
cellColumnIndex++;
}
cellColumnIndex = 1;
cellRowIndex++;
}
//Getting the location and file name of the excel to save from user.
SaveFileDialog saveDialog = new SaveFileDialog();
saveDialog.Filter = "Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*";
saveDialog.FilterIndex = 2;
if (saveDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
workbook.SaveAs(saveDialog.FileName);
MessageBox.Show("Export Successful");
}
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
excel.Quit();
workbook = null;
excel = null;
}
}
Previously, I added the reference Microsoft.Office.Interop.Excel to my project from Reference manager / COM section (Microsoft Excel 16.0 Object library). Despite that I received the next error messages:
-> The type name _Application does not exist in the type 'Office.Interop.Excel'
-> The type name _Workbook does not exist in the type 'Office.Interop.Excel'
-> The type name _Worksheet does not exist in the type 'Office.Interop.Excel'
How can I solve this?
Many thanks!

Save datatable to large excel file having rows 100k in c#

I working with windows application and processing large excel file. I need to save 100k rows from datatable to excel file.
Currently my create excel function only support 65,500 rows only?
But I need to save excel file more than that. Is it possible?
If yes then, Kindly give the source?
Here is my code
public static void ExportDataSetToExcel(DataTable dt, int index, string strFilePathName)
{
Console.WriteLine("Creating Output Excel file");
string fileFomat = getExcelFileName(index) + (DateTime.Now.ToString("yyyyMMddTHHmmss"));
Microsoft.Office.Interop.Excel.Application objXL = null;
Microsoft.Office.Interop.Excel.Workbook objWB = null;
try
{
objXL = new Microsoft.Office.Interop.Excel.Application();
objWB = objXL.Workbooks.Add(1);
int sheetcount = 1;
Microsoft.Office.Interop.Excel.Worksheet objSHT = (Microsoft.Office.Interop.Excel.Worksheet)objWB.Sheets.Add();
Microsoft.Office.Interop.Excel.Range cells = objSHT.Cells;
cells.NumberFormat = "#";
//formatRange = objSHT.get_Range("b1",Type.Missing);
//formatRange.EntireRow.Font.Bold = true;
objSHT.Name = "RunOrderSheet";
for (int j = 0; j < dt.Rows.Count; j++)
{
for (int i = 0; i < dt.Columns.Count; i++)
{
//Condition to put column names in 1st row
//Excel work book indexes start from 1,1 and not 0,0
if (j == 0)
{
objSHT.Cells[1, i + 1] = dt.Columns[i].ColumnName.ToString();
}
//Writing down data
objSHT.Cells[j + 2, i + 1] = dt.Rows[j][i].ToString();
}
}
sheetcount++;
objWB.Saved = true;
objWB.SaveCopyAs(strFilePathName.Trim() + fileFomat.Trim() + ".xlsx");
objWB.Close();
objXL.Quit();
Console.WriteLine("Process done");
}
catch (Exception ex)
{
objWB.Saved = true;
objWB.Close();
objXL.Quit();
log.Error(ex.Message);
}
}
Excel and the COM interface with C# absolutely will support more than 65k lines. Just to prove that it's possible, run the following code:
public static void ExportDataSetToExcel()
{
Excel.Application objXL = null;
Excel.Workbook objWB = null;
objXL = new Microsoft.Office.Interop.Excel.Application();
objXL.Visible = true;
objWB = objXL.Workbooks.Add(1);
Excel.Worksheet objSHT = objWB.Sheets.Add();
for (int row = 1; row < 100000; row++)
{
objSHT.Cells[row, 1].Value2 = row;
}
objWB.SaveAs("c:\test\test.xlsx", Excel.XlFileFormat.xlOpenXMLWorkbook);
objWB.Close();
objXL.Quit();
}
Which leads me to several possibilities as to what your issue might be, in order of my suspicions (first being what I think is the most likely):
Since you have a try/catch block that is very nicely trapping errors and making sure that anything that happens within your loop while still saving the file, something is tripping the proverbial circuit breaker. While I don't see any glaring errors, it could be anything. Put a breakpoint within the catch block and see what ex contains. Also, make note of the specific record that is causing the error so you can step through just that one record and see where it occurs.
I noticed you are using SaveCopyAs rather than SaveAs. SaveCopyAs automatically saves in the exact same format as the original. I would think your Excel comes up with the default xlsx, but I certainly can't guarantee that. Using SaveAs with the explicit file format will guarantee it is saved in a format that supports more than 65k lines:
.
objWB.SaveAs("c:\test\test.xlsx", Excel.XlFileFormat.xlOpenXMLWorkbook);
Without knowing how large your datatable is, it might simply be a memory issue also that's tripping the try/catch.

C# export datatable to excel spreadsheet *object reference not set to an instance of an object

Hey folks I am trying to export a datatable to an excel spreadsheet (excel 15.0 library, excel 2013, VS 2013), and I am running into an issue. Right now I'm not worried so much about getting column headers and all that I'd just be happy with getting the data into the spreadsheet, my code is below and when I run it I keep getting
Object reference not set to an instance of an object
on the
workSheet.Cells[(i+2),(j+1)]
line of code.
public static void exportReport(System.Data.DataTable Results)
{
try
{
string excelFilePath = #"C:\exceltest\exceltestsheet.xlsx";
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel._Worksheet workSheet = excelApp.ActiveSheet;
if (Results == null || Results.Columns.Count == 0)
{
throw new Exception("null or empty table");
}
for (int i = 0; i < Results.Rows.Count; i++)
{
for (int j = 0; j < Results.Columns.Count; j++)
{
workSheet.Cells[(i + 2), (j + 1)] = Results.Rows[i][j];
}
}
if (excelFilePath != null && excelFilePath != "")
{
workSheet.SaveAs(excelFilePath);
excelApp.Quit();
Console.WriteLine("Excel File Saved!");
}
}
catch(Exception ex)
{
}
}
I believe you have to create a new workbook before accessing the active sheet. Try:
excelApp.Workbooks.Add();
BEFORE accessing the active worksheet.

Categories