C# COM Interop: Writing to a Cell in an Excel Sheet - c#

I am using Microsoft.Office.Interop.Excel in a winform where I am reading one excel file, processing the data, and outputting a new excel file. However I am having trouble writing to the cells -- specifically to add column headings. Here's the code:
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Workbook wb = xlApp.Workbooks.Add(XlWBATemplate.xlWBATWorksheet);
Worksheet ws = (Worksheet)wb.Worksheets[1];
for (int i = 0; i < dt.Columns.Count; i++)
{
for (int j = 0; j < dt.Rows.Count; j++)
{
ws.Cells[j + 1, i] = dt.Rows[j][i].ToString();
}
}
ws.Cells[0, 0] = "Ticket Number";
ws.Cells[0, 1] = "Transit";
ws.Cells[0, 2] = "Outage Start Date";
ws.Cells[0, 3] = "Outage End Date";
ws.Cells[0, 4] = "Business Impact";
wb.Worksheets.Add(ws);
where "dt" is my DataTable. The nested for-loop doesn't throw a runtime error but the code following it does. The error just says: COM Exception was unhandled, Exception from HRESULT: 0x800A03EC.
Any advice is appreciated.
Regards.

Cells[] is 1-based, not zero-based.

Related

Application stop when exporting data to excel

I have a code that displays a table from an Access database, on my WinForm I have an option to export the table to excel, once the user click on it takes some time to copy all rows to excel, if the user try to close the excel before all cells get transfer to the sheet the application will stop and throw the error System.Runtime.InteropServices.COMException: 'Exception from HRESULT: 0x800AC472'
Here is the code for the "Export to Excel" button I have in my windows form
private void Export_btn_Click(object sender, EventArgs e)
{
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 = true;
worksheet = workbook.Sheets["Sheet1"];
worksheet = workbook.ActiveSheet;
for (int i = 1; i < fviAoi_tbl.Columns.Count + 1; i++)
{
worksheet.Cells[1, i] = fviAoi_tbl.Columns[i - 1].HeaderText;
}
for (int i = 0; i < fviAoi_tbl.Rows.Count - 1; i++)
{
for (int j = 0; j < fviAoi_tbl.Columns.Count; j++)
{
if (fviAoi_tbl.Rows[i].Cells[j].Value != null)
{
worksheet.Cells[i + 2, j + 1] = fviAoi_tbl.Rows[i].Cells[j].Value.ToString();
}
else
{
worksheet.Cells[i + 2, j + 1] = "";
}
}
}
}
Any ideas why this is happening or how can I make my application to ignore that error and continue running.
Surround the code line that emit the exception with a try... catch...
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/exceptions/
In general, Null is probably not what you think it is.
Null is not 0 nor empty string. Null is lack of data. What is the difference between ("") and (null)
Thus, C# and .NET probably throws an error here:
if (fviAoi_tbl.Rows[i].Cells[j].Value != null) because, it does not understand how can you compare some Excel cell with Null and what should it answer. Change the code to:
if (fviAoi_tbl.Rows[i].Cells[j].Value != "" or something similar.

How to add xml schema/design file to Excel Interop?

I am creating an excel file using a data table in excel interop
Price Profit/Loss%
250.8982989 0.04301071
I have a schema file which has details for design as
1) make all headers bold
2) column definition (weather,string,percentage)
I used this file in fast report export but as such i have to use interop for excel export is there a way i can add that schema file
Excel.Application excelApp = new Excel.Application();
//Create an Excel workbook instance and open it from the predefined location
Excel.Workbook excelWorkBook = excelApp.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
//Add a new worksheet to workbook with the Datatable name
Excel.Worksheet excelWorkSheet = (Excel.Worksheet)excelWorkBook.Sheets.Add();
for (int i = 1; i < table.Columns.Count + 1; i++)
{
excelWorkSheet.Cells[1, i] = table.Columns[i - 1].ColumnName;
}
for (int j = 0; j < table.Rows.Count; j++)
{
for (int k = 0; k < table.Columns.Count; k++)
{
excelWorkSheet.Cells[j + 2, k + 1] = table.Rows[j].ItemArray[k].ToString();
}
}
excelWorkBook.SaveAs(#"D:\sample excel.xls");
excelWorkBook.Close();
excelApp.Quit();
i want to show this value in bold and format as % 0.04301071
make this value Bold and round 250.8982989
This all information will be stored in a schema file i want to load that file
or else i want to load that cell as per the columns datatype in datatable
I have tried :-
clmnrange.NumberFormat = (Object)table.Columns[k - 1].DataType;
but it is raising an exception
Regards
EP
As mentioned in above comment:
The NumberFormat property takes a string that uses Excel's formatting
syntax. For example formatting as a percentage (up to) 8 decimal
places is "0.########%"
Here is an example that someone else provided showing how to implement the type of numberingFormat you are describing:
WorkbookStylesPart sp = workbookPart.AddNewPart<WorkbookStylesPart>();
Create a stylesheet:
sp.Stylesheet = new Stylesheet();
Create a numberingFormat:
sp.Stylesheet.NumberingFormats = new NumberingFormats();
// #.##% is also Excel style index 1
NumberingFormat nf2decimal = new NumberingFormat();
nf2decimal.NumberFormatId = UInt32Value.FromUInt32(3453);
nf2decimal.FormatCode = StringValue.FromString("0.0%");
sp.Stylesheet.NumberingFormat.Append(nf2decimal);

How to hide Excel Columns and Rows using Interop C#

I have made a simple inventory interface that will take data from access and show in datagrid view on my interface and then send the information to Excel via button click. This part works as needed but I would like to remove the unused columns and rows after the information is sent. I am currently using VS 2015. I cant figure out what to add to accomplish this.
//send to excel
private void btnExport_Click(object sender, EventArgs e)
{
ActiveControl = txtSerial;
// creating Excel Application
Microsoft.Office.Interop.Excel._Application app = new Microsoft.Office.Interop.Excel.Application();
// creating new WorkBook within Excel application
Microsoft.Office.Interop.Excel._Workbook workbook = app.Workbooks.Add(Type.Missing);
// creating new Excelsheet in workbook
Microsoft.Office.Interop.Excel._Worksheet worksheet = null;
// see the excel sheet behind the program
app.Visible = true;
// get the reference of first sheet. By default its name is Sheet1.
// store its reference to worksheet
worksheet = workbook.Sheets["Sheet1"];
worksheet = workbook.ActiveSheet;
// changing the name of active sheet
worksheet.Name = "Inventory Search";
// storing header part in Excel
for (int i = 1; i < dataGridFB.Columns.Count + 1; i++)
{
worksheet.Cells[1, i] = dataGridFB.Columns[i - 1].HeaderText;
worksheet.Cells[1, i].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue);
worksheet.Cells[1, i].Font.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black);
worksheet.Cells[1, i].HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
worksheet.Cells[1, i].Font.Size = 14;
}
// storing Each row and column value to excel sheet
for (int i = 0; i < dataGridFB.Rows.Count - 1; i++)
{
for (int j = 0; j < dataGridFB.Columns.Count; j++)
{
worksheet.Cells[i + 2, j + 1] = dataGridFB.Rows[i].Cells[j].Value.ToString();
worksheet.Cells[i + 2, j + 1].HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
worksheet.Cells[i + 2, j + 1].Font.Size = 12;
worksheet.Columns["A:G"].AutoFit();
}
}
}
Your question is a bit too broad, thus the answer is generic: in order to delete entire Worksheet Column you may use VBA statement like: Columns("C").Delete, or Columns(3).EntireColumn.Delete, or Columns("F:K").Delete. Similar syntax may apply to: Rows(3).Delete.
In order to just hide Rows/Columns use the VBA statement like shown below:
Rows("3:10").EntireRow.Hidden = True
Columns("C").Hidden = True
Hope this may help.

How to download Excel object in ASP.Net

Please consider this code:
Microsoft.Office.Interop.Excel.Application objApp;
Microsoft.Office.Interop.Excel._Workbook objBook;
Microsoft.Office.Interop.Excel.Workbooks objBooks;
Microsoft.Office.Interop.Excel.Sheets objSheets;
Microsoft.Office.Interop.Excel._Worksheet objSheet;
Microsoft.Office.Interop.Excel.Range range;
int ColumnsCount = dt.Columns.Count;
int RowsCount = dt.Rows.Count;
objApp = new Microsoft.Office.Interop.Excel.Application();
objBooks = objApp.Workbooks;
objBook = objBooks.Add(System.Reflection.Missing.Value);
objSheets = objBook.Worksheets;
objSheet = (Microsoft.Office.Interop.Excel._Worksheet)objSheets.get_Item(1);
for (int i = 1; i < ColumnsCount + 1; i++)
{
objSheet.Cells[1, i] = dt.Columns[i - 1].ColumnName;
}
range = objSheet.get_Range("A2", System.Reflection.Missing.Value);
range = range.get_Resize(RowsCount, ColumnsCount);
string[,] saRet = new string[RowsCount, ColumnsCount];
for (int iRow = 0; iRow < RowsCount; iRow++)
{
for (int iCol = 0; iCol < ColumnsCount; iCol++)
{
saRet[iRow, iCol] = dt.Rows[iRow][iCol].ToString();
}
}
//Set the range value to the array.
range.set_Value(Missing.Value, saRet);
I want to download Excel object that I created. The problem is Microsoft.Office.Interop.Excel._Workbook is not serializable and until I save it I can't access Excel file. How I can download Excel that created in memory?
thanks
This seems like one of the many problems related to Microsoft KB: Considerations for server-side Automation of Office. Using Excel Interop server-side isn't supported.
I'd recommend you export csv files or look into OpenXML or the easier version ClosedXML to generate xslx files on the server.
See the other methods in this MSDN guide: How To Asp.Net Export Excel
There should be a SaveAs method on your workbook that you can use to save as an xls file.
objBook.SaveAs("my-workbook.xls");

How can i export the Dates?

Microsoft.Office.Interop.Excel.Application Excel = new Microsoft.Office.Interop.Excel.Application();
Workbook wb = Excel.Workbooks.Add(XlSheetType.xlWorksheet);
Worksheet ws = (Worksheet)Excel.ActiveSheet;
Excel.Visible = true;
ws.Cells[1, 1] = "Tarih";
ws.Cells[1, 2] = "Kasiyer";
ws.Cells[1, 3] = "Ucret";
ws.Cells[1, 4] = "Bilet No";
ws.Cells[1, 5] = "Firma Adı";
for (int j = 2; j < dataGridView1.Rows.Count; j++)
{
for (int i = 2; i <= 5; i++)
{
ws.Cells[j,i]=dataGridView1.Rows[j-2].Cells[i-1].Value;
}
}
Dates are not coming to First Cell in Excel . How can i do that ? please help me ? And also i have got a warning like "HRESULT özel durum döndürdü: 0x800AC472"
You can't probably take date value, it returns null and gives an error. Just for date column, you try to convert.
for (int i = 1; i < dataGridView1.Rows.Count; i++)
{
ws.Cells[i,0] = (Convert.ToDateTime(ws.Cells[i,0]).ToOADate();
}
Additionaly you can try that too.
Microsoft.Office.Interop.Excel.Range range = (Microsoft.Office.Interop.Excel.Range)xlWorkSheet.Cells[1, 1];
range = range.get_Resize(rowCount, columnCount);
range.EntireColumn.NumberFormat = "DD/MM/YYYY";

Categories