I'm getting an error when I'm exporting Excel to C#, I can't find where my code is wrong and the solution for my problem
Error :
An unhandled exception of type
'System.Runtime.InteropServices.COMException' occurred in GestãoSI.exe
Additional information: Índice inválido. (Excepção de HRESULT:
0x8002000B (DISP_E_BADINDEX))
The error appear when the code is running
// Add a workbook.
oBook = oExcel_12.Workbooks.Add(oMissing);
// Get worksheets collection
oSheetsColl = oExcel_12.Worksheets;
// Get Worksheet "Sheet1"
oSheet = (Excel_12.Worksheet)oSheetsColl.get_Item("Sheet1");
Here is all my code
public static void ExportDataGridViewTo_Excel12(DataGridView itemDataGridView)
{
Excel_12.Application oExcel_12 = null; //Excel_12 Application
Excel_12.Workbook oBook = null; // Excel_12 Workbook
Excel_12.Sheets oSheetsColl = null; // Excel_12 Worksheets collection
Excel_12.Worksheet oSheet = null; // Excel_12 Worksheet
Excel_12.Range oRange = null; // Cell or Range in worksheet
Object oMissing = System.Reflection.Missing.Value;
// Create an instance of Excel_12.
oExcel_12 = new Excel_12.Application();
// Make Excel_12 visible to the user.
oExcel_12.Visible = true;
// Set the UserControl property so Excel_12 won't shut down.
oExcel_12.UserControl = true;
// System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("en-US");
// Add a workbook.
oBook = oExcel_12.Workbooks.Add(oMissing);
// Get worksheets collection
oSheetsColl = oExcel_12.Worksheets;
// Get Worksheet "Sheet1"
oSheet = (Excel_12.Worksheet)oSheetsColl.get_Item("Sheet1");
// Export titles
for (int j = 0; j < itemDataGridView.Columns.Count; j++)
{
oRange = (Excel_12.Range)oSheet.Cells[1, j + 1];
oRange.Value2 = itemDataGridView.Columns[j].HeaderText;
}
// Export data
for (int i = 0; i < itemDataGridView.Rows.Count - 1; i++)
{
for (int j = 0; j < itemDataGridView.Columns.Count; j++)
{
oRange = (Excel_12.Range)oSheet.Cells[i + 2, j + 1];
oRange.Value2 = itemDataGridView[j, i].Value;
}
}
// Release the variables.
//oBook.Close(false, oMissing, oMissing);
oBook = null;
//oExcel_12.Quit();
oExcel_12 = null;
// Collect garbage.
GC.Collect();
}
this work for me..
oSheet = oBook.Worksheets.get_Item(index);
Since you got a non-english exception text from Excel I assume there is no sheet that is named "Sheet1", instead it has the localized name. You have to either use the loclized name or, which would be way better, just use the sheet index (should start with 1) instead of the sheet name.
Related
The template I am attempting to recreate is this: Template
I have started the process of attempting to recreate the template, but I am mainly having issues with cell structure and inserting data into the cells. So I am not sure if I am wasting my time trying to do something that might not be possible.
private void excelcreator()
{
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
app.Visible = true;
app.Interactive = false;
Microsoft.Office.Interop.Excel.Workbook wb = app.Workbooks.Add(1);
Microsoft.Office.Interop.Excel.Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets[1];
ws.Range["B7"].EntireRow.Font.Size = 14;
Range line = (Range)ws.Rows[1];
line.Insert();
ws.Range[ws.Cells[7, 2], ws.Cells[7, 4]].Merge();
app.Cells[7, 2] = "Date";
app.Interactive = true;
// AutoSet Cell Widths to Content Size
ws.Cells.Select();
ws.Cells.EntireColumn.AutoFit();
ws.PageSetup.TopMargin = 0;
ws.PageSetup.BottomMargin = 0;
ws.PageSetup.LeftMargin = 0;
ws.PageSetup.RightMargin = 0;
ws.Range[7, 2].EntireRow.Font.Bold = true;
ws.PageSetup.Orientation = XlPageOrientation.xlLandscape;
}
I am also getting an error on the line ws.Range[7, 2].EntireRow.Font.Bold = true; that says: System.Runtime.InteropServices.COMException: 'Exception from HRESULT: 0x800A03EC'"
I want to export all my DataGridViews in one Excell document.
For every DataGridView there shoud be a own sheet in the Excell File.
But with my code i only recive the Error: System.Runtime.InteropServices.COMException: HRESULT: 0x800A03EC"
I think there is something wrong with my parameters.
private void exportToExcellButton_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileD = new SaveFileDialog();
string fileName = truckListBox.SelectedItem.ToString() + "__" + DateTime.Now.ToShortDateString();
saveFileD.InitialDirectory = #"C:/TML/";
saveFileD.FileName = fileName;
if (!Directory.Exists(#"C:/TML/"))
Directory.CreateDirectory(#"C:/TML/");
List<DataGridView> dataGridViews = getAllDataGridViews();
Microsoft.Office.Interop.Excel.Application app;
Microsoft.Office.Interop.Excel.Workbook book;
Microsoft.Office.Interop.Excel.Worksheet sheet;
app = new Excel.Application();
app.Visible = true;
book = app.Workbooks.Add(System.Reflection.Missing.Value);
foreach (var grid in dataGridViews)
{
int count = book.Worksheets.Count;
sheet = (Worksheet)book.Sheets.Add(Type.Missing, book.Worksheets[count], Type.Missing, Type.Missing);
sheet.Name = grid.Name.ToString().Remove(0, 13);
int cMin = 0, rMin = 0;
int c = cMin, r = rMin;
// Set Headers
foreach (DataGridViewColumn column in grid.Columns)
{
//Here appears the Error: System.Runtime.InteropServices.COMException: HRESULT: 0x800A03EC"
sheet.Cells[r, c] = column.HeaderText;
c++;
}
sheet.Range[sheet.Cells[r, cMin], sheet.Cells[r, c]].Font.Bold = true;
sheet.Range[sheet.Cells[r, cMin], sheet.Cells[r, c]].VerticalAlignment = Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;
// Set Rows
foreach (DataGridViewRow row in grid.Rows)
{
r++;
c = cMin;
// Set Cells
foreach (DataGridViewCell item in row.Cells)
{
sheet.Cells[r, c++] = item.Value;
}
}
}
book.Save();
book.Close();
app.Quit();
}
Spended allready days into it and cant get it work.
Thx for your Help!
EDIT: Fixed one error to get to the new one.
There are a few problems you may have with the posted code. Therefore, I will break them down.
For starters, it appears you are using a SaveFileDialog however I do not see where it is being used. The code sets the InitalDirectory and FileName, but it is never used. This is not that important as a dialog is not really needed, however the way the code is getting the file name is going to have some problems. The line of code…
string fileName = truckListBox.SelectedItem.ToString() + "__" + DateTime.Now.ToShortDateString();
is going to have problems if you try to save the file name because the string returned from DateTime.Now.ToShortDateString() is going to be in a format like “2019\11\26”… Obviously the “\” characters are going to be interpreted as a path (folder) and will most likely fail when the code tries to save the file. Creating a method that returns a string that uses some other character should be easy to fix this.
Next is the fact that Excel files are NOT zero based on their rows and columns. Therefore, setting the initial Excel row column variables (int c = 0, r = 0;) will fail on the first try. These values should be one (1).
Another problem is on the line…
book.Save();
Is most likely going to save the file to the users “Documents” folder using the file name of “Book1.xlsx.” When saving the file you need to supply the complete path and file name which as stated earlier does not appear to be used.
Lastly, anytime you use “COM” objects such as Excel apps, workbooks and worksheets, it is very important for the code to “RELEASE” the com objects your code creates before you exit the program. In the current posted code, it is highly likely that there are lingering “Excel” resources still running. Therefore, to avoid leaking resources, it is important for your code to release the com objects it creates.
In my example below the code to release the resources is in the finally clause of the try/catch/finally statement.
private void button1_Click(object sender, EventArgs e) {
//SaveFileDialog saveFileD = new SaveFileDialog();
//string fileName = truckListBox.SelectedItem.ToString() + "__" + DateTime.Now.ToShortDateString();
string fileName = #"C:\Users\John\Desktop\Grr\TestExcelFile" + "__" + DateTime.Now.Year + "_" + DateTime.Now.Month;
//saveFileD.InitialDirectory = #"C:\Users\John\Desktop\Grr\";
//saveFileD.FileName = fileName;
//if (!Directory.Exists(#"C:/TML/"))
// Directory.CreateDirectory(#"C:/TML/");
//List<DataGridView> dataGridViews = getAllDataGridViews();
List<DataGridView> dataGridViews = getGrids();
Microsoft.Office.Interop.Excel.Application app = null;
Microsoft.Office.Interop.Excel.Workbook book = null;
Microsoft.Office.Interop.Excel.Worksheet sheet = null;
app = new Microsoft.Office.Interop.Excel.Application();
app.Visible = true;
book = app.Workbooks.Add(System.Reflection.Missing.Value);
try {
foreach (var grid in dataGridViews) {
int count = book.Worksheets.Count;
//sheet = (Microsoft.Office.Interop.Excel.Worksheet)book.Sheets.Add(Type.Missing, book.Worksheets[count], Type.Missing, Type.Missing);
sheet = (Microsoft.Office.Interop.Excel.Worksheet)book.Worksheets.Add();
//sheet.Name = grid.Name.ToString().Remove(0, 13);
sheet.Name = grid.Name.ToString();
int cMin = 1, rMin = 1;
int c = cMin, r = rMin;
// Set Headers
foreach (DataGridViewColumn column in grid.Columns) {
//Here appears the Error: System.Runtime.InteropServices.COMException: HRESULT: 0x800A03EC"
sheet.Cells[r, c] = column.HeaderText;
c++;
}
sheet.Range[sheet.Cells[r, cMin], sheet.Cells[r, c]].Font.Bold = true;
sheet.Range[sheet.Cells[r, cMin], sheet.Cells[r, c]].VerticalAlignment = Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;
// Set Rows
foreach (DataGridViewRow row in grid.Rows) {
r++;
c = cMin;
// Set Cells
foreach (DataGridViewCell item in row.Cells) {
sheet.Cells[r, c++] = item.Value;
}
}
}
book.SaveAs(fileName, Type.Missing, Type.Missing, Type.Missing);
book.Close();
app.Quit();
}
catch (Exception ex) {
MessageBox.Show("Error writing to excel: " + ex.Message);
}
finally {
if (sheet != null)
Marshal.ReleaseComObject(sheet);
if (book != null)
Marshal.ReleaseComObject(book);
if (app != null)
Marshal.ReleaseComObject(app);
}
}
Hope this helps.
Simply Make a method and pass DataGridView
using Excel = Microsoft.Office.Interop.Excel;
public void ete(DataGridView dgv)//ExportToExcel
{
// Creating a Excel object.
Excel._Application excel = new Excel.Application();
Excel._Workbook workbook = excel.Workbooks.Add(Type.Missing);
Excel._Worksheet worksheet = null;
excel.Columns.ColumnWidth = 20;
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 = -1; i < dgv.Rows.Count; i++)
{
for (int j = 0; j < dgv.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] = dgv.Columns[j].HeaderText;
}
else
{
worksheet.Cells[cellRowIndex, cellColumnIndex] = dgv.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() == DialogResult.OK)
{
workbook.SaveAs(saveDialog.FileName.ToString());
MessageBox.Show("Export Successful");
}
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
excel.Quit();
workbook = null;
excel = null;
}
}
Now Call Method
ete(datagridview1);
What is the reason I am getting the error like in datagridview below?
System.InvalidCastException: The COM object of type '' Microsoft.Office.Interop.Excel.ApplicationClass' could not be assigned to interface type 'Microsoft.Office.Interop.Excel._Application'. This operation failed because the QueryInterface call in the COM component for the interface with the IID '{000208D5-0000-0000-C000-000000000046}' failed with the following error: Error loading type library / DLL. (HRESULT exception returned: 0x80029C4A (TYPE_E_CANTLOADLIBRARY)). '
The code I wrote is:
saveFileDialog.InitialDirectory = "C:";
saveFileDialog.Title = "Save as Excel File";
saveFileDialog.FileName = "Data";
saveFileDialog.Filter = "Excel Files(2003)|*.xls|Excel Files(2007)|*.xlsx";
if (saveFileDialog.ShowDialog() != DialogResult.Cancel)
{
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
excelApp.Application.Workbooks.Add(Type.Missing);
excelApp.Columns.ColumnWidth = 20;
for (int i = 1; i < dgwReport.Columns.Count + 1; i++)
{
excelApp.Cells[1, i] = dgwReport.Columns[i - 1].HeaderText;
}
for (int i = 0; i < dgwReport.Rows.Count; i++)
{
for (int j = 0; j < dgwReport.Columns.Count; j++)
{
excelApp.Cells[i + 2, j + 1] = dgwReport.Rows[i].Cells[j].Value;
}
}
excelApp.ActiveWorkbook.SaveCopyAs(saveFileDialog.FileName.ToString());
excelApp.ActiveWorkbook.Saved = true;
excelApp.Quit();
}
Using the posted code, I did not get the error you describe…
excelApp.Application.Workbooks.Add(Type.Missing);
This appears correct in creating a new Workbook. However, when it comes to writing the data to the workbook it appears to have a problem. The problem is that the code is writing the data to the excelApp and this is incorrect. The excelApp could have numerous workbooks open and each workbook could have numerous “worksheets.” You need to specify “where” (which worksheet in which workbook) you want to write to.
Since you are creating a new workbook, you need to “add” a new worksheet and write to that worksheet instead of the excelApp.
I tested the code below and it writes the data properly to a new worksheet in a new workbook.
saveFileDialog.InitialDirectory = "C:";
saveFileDialog.Title = "Save as Excel File";
saveFileDialog.FileName = "Data";
saveFileDialog.Filter = "Excel Files(2003)|*.xls|Excel Files(2007)|*.xlsx";
Microsoft.Office.Interop.Excel.Application excelApp = null;
Microsoft.Office.Interop.Excel.Workbook workbook = null;
Microsoft.Office.Interop.Excel.Worksheet worksheet = null;
try {
if (saveFileDialog.ShowDialog() != DialogResult.Cancel) {
excelApp = new Microsoft.Office.Interop.Excel.Application();
workbook = excelApp.Application.Workbooks.Add(Type.Missing);
worksheet = workbook.ActiveSheet;
excelApp.Columns.ColumnWidth = 20;
for (int i = 1; i < dgwReport.Columns.Count + 1; i++) {
worksheet.Cells[1, i] = dgwReport.Columns[i - 1].HeaderText;
}
for (int i = 0; i < dgwReport.Rows.Count; i++) {
for (int j = 0; j < dgwReport.Columns.Count; j++) {
worksheet.Cells[i + 2, j + 1] = dgwReport.Rows[i].Cells[j].Value;
}
}
excelApp.ActiveWorkbook.SaveCopyAs(saveFileDialog.FileName.ToString());
excelApp.ActiveWorkbook.Saved = true;
workbook.Close();
excelApp.Quit();
}
}
catch (Exception ex) {
MessageBox.Show("Excel write error: " + ex.Message);
}
finally {
// release the excel objects to prevent leaking the unused resource
if (worksheet != null)
Marshal.ReleaseComObject(worksheet);
if (workbook != null)
Marshal.ReleaseComObject(workbook);
if (excelApp != null)
Marshal.ReleaseComObject(excelApp);
}
I am trying to set an Excel sheet specific cells starting at column A and second Excel sheet row. I wrote the following code:
if (!File.Exists(AppConfiguration.FilePath))
{
throw new FileNotFoundException("File Not Found. The requested template.xlsx was not found on the server");
}
Microsoft.Office.Interop.Excel.Application xlsx = new Microsoft.Office.Interop.Excel.Application();
Workbook workbook = null;
try
{
workbook = xlsx.Workbooks.Open(AppConfiguration.FilePath, ReadOnly: false, Editable: true);
Worksheet worksheet = workbook.Worksheets[1];
Microsoft.Office.Interop.Excel.Range cells = worksheet.Cells["$A"];
List<Analytics> list = (List<Analytics>)data;
for (int i = 0; i < list.Count; i++)
{
((Microsoft.Office.Interop.Excel.Range)cells[i + 1, 0]).Value = list[i].ProductShare;
((Microsoft.Office.Interop.Excel.Range)cells[i + 1, 1]).Value = list[i].MarketPotential;
}
workbook.Save();
}
catch(Exception e)
{
throw new Exception("Error while processing file");
}
finally
{
workbook.Close(SaveChanges: true);
xlsx.Quit();
Marshal.ReleaseComObject(workbook);
}
However, I always get an Exception at
(Microsoft.Office.Interop.Excel.Range)cells[i + 1, 0]).Value = list[i].ProductShar
In Excel, indexes begin with 1, therefore cells[i + 1, 0]is invalid, use cells[i + 2, 1] instead.
for(int i = 0; i< list.Count; i++)
{
worksheet.Range[string.Format("A{0}", i + 2].Value = list[i].val;
}
Starting at A2 I begin to write the values within my list which is what I was seeking for! Thanks for all of you for your times and considerations!
Microsoft.Office.Interop.Excel._Application app = new Microsoft.Office.Interop.Excel.Application();
object misValue = System.Reflection.Missing.Value;
// creating new WorkBook within Excel application
Microsoft.Office.Interop.Excel._Workbook workbook = app.Workbooks.Open(System.IO.Directory.GetCurrentDirectory() + #"\Report.xlsx");
// Get current worksheet and clear it
Microsoft.Office.Interop.Excel._Worksheet worksheet1 = workbook.Worksheets[1];
Microsoft.Office.Interop.Excel._Worksheet worksheet2 = workbook.Worksheets[2];
app.DisplayAlerts = false;
worksheet1.Delete();
worksheet2.Delete();
app.DisplayAlerts = true;
//app.Worksheets[1].Delete();
//app.Worksheets[2].Delete();
workbook.Save();
Microsoft.Office.Interop.Excel._Worksheet worksheet = (Excel.Worksheet)app.Worksheets.Add(); ;
// storing header part in Excel
for (int i = 1; i < mydatatable.Columns.Count + 1; i++)
{
worksheet.Cells[1, i] = mydatatable.Columns[i - 1].ColumnName.ToString();
}
// storing Each row and column value to excel sheet
for (int i = 0; i < mydatatable.Rows.Count; i++)
{
for (int j = 0; j < mydatatable.Columns.Count; j++)
{
worksheet.Cells[i + 2, j + 1] = mydatatable.Rows[i][j].ToString();
}
worksheet.Columns.AutoFit();
}
Excel.Range chartRange;
Excel.ChartObjects xlCharts = (Excel.ChartObjects)worksheet.ChartObjects(Type.Missing);
Excel.ChartObject myChart = (Excel.ChartObject)xlCharts.Add(10, 80, 300, 250);
Excel.Chart chartPage = myChart.Chart;
chartRange = worksheet.get_Range("C1", "E20");
chartPage.SetSourceData(chartRange);
chartPage.ChartType = Excel.XlChartType.xlColumnClustered;
chartPage.Location(Excel.XlChartLocation.xlLocationAsNewSheet,"Chart");
workbook.Save();
workbook.Close(misValue);
Marshal.ReleaseComObject(worksheet);
app.Quit();
It creates the new worksheet perfectly, but doesn't delete the old one first. I even have two codes to delete it and it doesn't. I have more than one sheet in the app.
EDIT: I just noticed that the first time I run the code it deletes the given sheets, but if I run it a second time (etc) it won't delete them anymore and gives me error, because aparently EXCEL proccess is still open in the background for some reason, altough I use "app.Quit()". Please help!
One of the problems could be that you have one worksheet when you're trying to delete it. Make sure that you're not deleting last worksheet or it won't work. So, create new one, then delete old one; not the other way around.
EDIT:
Try this code:
app.DisplayAlerts = false;
worksheetdel.Delete();
app.DisplayAlerts = true;
Source: https://stackoverflow.com/a/678795/2006048