Excel activity is viewable - c#

I'm using the following code to generate an Excel file using Microsoft.Interop.Excel. The problem is that I can actually see the workbook generation, when the code is executed, an excel document is open on the screen and the doc starts filling out with data. Can this be done somehow in the background?
Thanks
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
xlApp.Visible = false;
if (xlApp == null)
{
MessageBox.Show("EXCEL could not be started. Check that your office installation and project references are correct.");
return false;
}
xlApp.Visible = true;
Workbook wb = xlApp.Workbooks.Add(XlWBATemplate.xlWBATWorksheet);
try
{
if (details != false)
{
//Workbook wb = xlApp.Workbooks.Add(XlWBATemplate.xlWBATWorksheet);
wb.Worksheets.Add();
Worksheet detailsWs = (Worksheet)wb.Worksheets[2];
for (int i = 0; i < dt.Columns.Count; i++)
{
detailsWs.Cells[1, i + 1] = dt.Columns[i].Caption;
}
}
Worksheet ws = (Worksheet)wb.Worksheets[1];
if (ws == null)
{
MessageBox.Show("Worksheet could not be created. Check that your office installation and project references are correct.");
}
for (int i = 0; i < dt.Columns.Count; i++)
{
ws.Cells[1, i + 1] = dt.Columns[i].Caption;
}
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int j = 0; j < dt.Columns.Count; j++)
{
ws.Cells[i + 2, j + 1] = dt.Rows[i].ItemArray[j];
}
worker.ReportProgress((i * 100) / dt.Rows.Count);
}
wb.SaveAs(filename, XlFileFormat.xlWorkbookNormal, Type.Missing, Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlShared, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
wb.Close(true, filename);
return true;
}
catch (Exception ex)
{
throw ex;
}
finally
{
// Cleanup
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
if (wb != null)
{
wb.Close(Type.Missing, Type.Missing, Type.Missing);
Marshal.FinalReleaseComObject(wb);
}
if (xlApp != null)
{
xlApp.Quit();
Marshal.FinalReleaseComObject(xlApp);
}
}

Your code reads:
xlApp.Visible = false;
if (xlApp == null)
{
MessageBox.Show("EXCEL could not be started. Check that your office installation and project references are correct.");
return false;
}
then you write:
xlApp.Visible = true;
Leave this out. It will stay not visible.

Related

Is it possible to import data from Excel through memory?

Say a new Excel file is opened and data is entered into it. Could an external C# application hook onto the Excel process and get the data from it? Also, the Excel file is never saved into a file.
Would this be difficult to do and also could you point me in the right direction on how to achieve this.
Just add this code in the code behind of a windows form application that has a button named "button1" added on it. This sample code will iterate through cells of the Excel file and display the content of each cell in a Message Box. Of course a project reference to "Microsoft.Office.Interop.Excel" is required.
And don't forget to actually create the excel file, in this example I used this path "C:\ExcelData\DataToImp.xlsx".
using Excel = Microsoft.Office.Interop.Excel;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Range range;
string str;
int rCnt = 0;
int cCnt = 0;
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Open("C:\\ExcelData\\DataToImp.xlsx", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
range = xlWorkSheet.UsedRange;
for (int rowIndex = 1; rowIndex <= range.Rows.Count; rowIndex++)
{
for (int columnIndex = 1; columnIndex <= range.Columns.Count; columnIndex++)
{
Excel.Range rangeTest = range.Cells[rowIndex, columnIndex] as Excel.Range;
if (rangeTest.MergeCells)// && rangeTest.Value2 == null)
{
//continue;
int columns = rangeTest.Columns.Count;
columnIndex += columns;
}
MessageBox.Show("m " + (string)rangeTest.Value2);
}
}
xlWorkBook.Close(true, null, null);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Unable to release the Object " + ex.ToString());
}
finally
{
GC.Collect();
}
}

xml load after exporting excel file failed

I have a c# application with the following features:
read a password from a config file.
export an Excel file.
when I read the password at fist: it's ok. but once I export the Excel file, I can't no more read the password from config file. the following instruction fail.
xmlDoc.Load("Cfg.xml");
this issue appear only on Windows XP. on windows 7 it's ok.
the code for reading password from config file:
private void OK_Click(object sender, EventArgs e)
{
try
{
// Check password
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("Cfg.xml");
XmlNode node = xmlDoc.SelectSingleNode("Config/ManagerPW");
if (node != null)
{
string MangerPW = node.Attributes[0].Value;
PCCrypto PWCrypto = new PCCrypto();
if (PWCrypto.verifyMd5(this.Password.Text, MangerPW) == true)
{
isCorrectPassWord = true;
this.Dispose();
}
else
{
MessageBox.Show("Incorrect Password!", "PW Authentication", MessageBoxButtons.OK,
MessageBoxIcon.Error);
this.Password.Text = "";
}
}
else
{
MessageBox.Show("You tried to perform an unauthorized operation!", "PW Authentication", MessageBoxButtons.OK,
MessageBoxIcon.Error);
this.Password.Text = "";
}
}
catch
{
MessageBox.Show("Error in loading configuration file", "Configuration Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
this.Dispose();
}
}
the code of exporting Excel file
public bool exportToExcel(string path)
{
bool bRet = true;
int columnsNum = resultList.Columns.Count - 1;
int rowsNum = resultList.Items.Count;
object[,] array = new object[rowsNum + 1, columnsNum];
//Change Current System Time to US
System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
Excel.Application xlApp = new Excel.ApplicationClass();
Excel.Workbooks xlWorkBooks = xlApp.Workbooks;
Excel.Workbook xlWorkBook = xlWorkBooks.Add(Type.Missing);
Excel.Sheets xlWorkSheets = xlWorkBook.Sheets;
Excel.Worksheet xlWorkSheet = (Excel.Worksheet)xlWorkSheets[1];
//disable alerts
xlApp.DisplayAlerts = false;
//Add Header to array
for (int i = 0; i < columnsNum; i++)
{
array[0, i] = resultList.Columns[i + 1].Text;
}
//Add Listview data to array
for (int r = 0; r < rowsNum; r++)
{
for (int c = 0; c < columnsNum; c++)
{
this.Invoke(new MethodInvoker(delegate
{
array[r + 1, c] = resultList.Items[r].SubItems[c+1].Text;
}));
}
}
//Save array data into excel
Excel.Range c1 = (Excel.Range)xlWorkSheet.Cells[1, 1];
Excel.Range c2 = (Excel.Range)xlWorkSheet.Cells[rowsNum + 1, columnsNum];
Excel.Range xlRange = xlWorkSheet.get_Range(c1, c2);
xlRange.Borders.LineStyle = Excel.XlLineStyle.xlContinuous;
xlRange.EntireColumn.NumberFormat = "#";
xlRange.Value2 = array;
xlRange.EntireColumn.AutoFit();
//Add Header color
xlWorkSheet.get_Range("A1", "I1").Interior.Color = ColorTranslator.ToOle(Color.Aquamarine);
//Save Excel file
try
{
xlWorkBook.SaveAs(#path, Excel.XlFileFormat.xlWorkbookNormal, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
xlWorkBook.Close(true, Type.Missing, Type.Missing);
}
catch
{
bRet = false;
}
xlWorkBooks.Close();
xlApp.Application.Quit();
xlApp.Quit();
releaseObject(c1);
releaseObject(c2);
releaseObject(xlRange);
releaseObject(xlWorkSheet);
releaseObject(xlWorkSheets);
releaseObject(xlWorkBook);
releaseObject(xlWorkBooks);
releaseObject(xlApp);
return bRet;
}
Try specifying the full path in
xmlDoc.Load("Cfg.xml");
e.g.
xmlDoc.Load(#"C:\myfolder\Cfg.xml");
The current folder is being changed when you export the excel.

Writing to the activecell in excel

I have the following code which write a value to the activecell in the excel. It works fine 50% of the time but not the last 50% it does not.
Why??
void ValueToExcel(string value)
{
Excel.Application oXL=null;
Excel.Workbook oWB=null;
Excel.Worksheet oSheet=null;
Excel.Range rng =null;
try
{
oXL = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
oXL.Visible = true;
oWB = (Excel.Workbook)oXL.ActiveWorkbook;
oSheet = oWB.ActiveSheet;
rng = oSheet.Application.ActiveCell;
rng.Value = value;
rng.Application.ActiveCell.Offset[1, 0].Select();
}
catch (Exception EX)
{
MessageBox.Show(EX.Message);
}
}
I tried to change the code but it still not works. It seems that the value is written to some other Excel application.
void ValueToExcel(string value)
{
//Gets Excel and gets Activeworkbook and worksheet
Excel.Application oXL=null;
Excel.Workbook oWB=null;
Excel.Worksheet oSheet=null;
Excel.Range rng =null;
try
{
while (oXL==null)
oXL = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
oXL.Visible = true;
while (oWB == null)
oWB = (Excel.Workbook)oXL.ActiveWorkbook;
while (oSheet == null)
oSheet = oWB.ActiveSheet;
while (rng == null)
rng = oSheet.Application.ActiveCell;
while(rng.Value=="")
rng.Value = value;
MessageBox.Show(value);
Console.Beep();
rng.Application.ActiveCell.Offset[1, 0].Select();
}
catch (Exception EX)
{
MessageBox.Show(EX.Message);
}
}
somebody have some help?

Unable to export multiple pages of gridview data to excel

I have an issue exporting all my data to an excel file. I've only managed to export the data from the first page of the gridview. May I know the right way to export data including those in other pages? Thanks a bunch.
protected void bn_export_Click(object sender, EventArgs e)
{
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition","attachment;filename=GridViewExport.xls");
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/vnd.ms-excel";
StringWriter sw = new StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(sw);
gv_getGameDetails.AllowPaging = false;
//Change the Header Row back to white color
gv_getGameDetails.HeaderRow.Style.Add("background-color", "#FFFFFF");
gv_getGameDetails.HeaderRow.Cells[0].Style.Add("background-color", " #262626");
gv_getGameDetails.HeaderRow.Cells[1].Style.Add("background-color", " #262626");
gv_getGameDetails.HeaderRow.Cells[2].Style.Add("background-color", " #262626");
gv_getGameDetails.HeaderRow.Cells[3].Style.Add("background-color", " #262626");
this.RemoveControls(gv_getGameDetails);
gv_getGameDetails.RenderControl(hw);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
This may help. It reiterates all columns and rows and export to Excel sheet.You need to add Microsoft.Office.Interop.Excel
private void button2_Click(object sender, EventArgs e)
{
// 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
try
{
//Fixed:(Microsoft.Office.Interop.Excel.Worksheet)
worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Sheets["Sheet1"];
worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.ActiveSheet;
// changing the name of active sheet
worksheet.Name = "YourChosenSheetName";
// storing header part in Excel
for (int i = 1; i < dataGridView1.Columns.Count + 1; i++)
{
worksheet.Cells[1, i] = dataGridView1.Columns[i - 1].HeaderText;
}
// storing Each row and column value to excel sheet
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
{
for (int j = 0; j < dataGridView1.Columns.Count; j++)
{
worksheet.Cells[i + 2, j + 1] = dataGridView1.Rows[i].Cells[j].Value.ToString();
}
}
// save the application
string fileName = String.Empty;
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "Excel files |*.xls|All files (*.*)|*.*";
saveFileDialog1.FilterIndex = 2;
saveFileDialog1.RestoreDirectory = true;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
fileName = saveFileDialog1.FileName;
//Fixed-old code :11 para->add 1:Type.Missing
workbook.SaveAs(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, Type.Missing);
}
else
return;
// Exit from the application
//app.Quit();
}
catch (System.Exception ex)
{
}
finally
{
app.Quit();
workbook = null;
app = null;
}
}

Just another Excel COM issue

I have an app that imports data from an excel file. It creates an excel COM object and reads data from it. After that i release all object and release all excel objects.
It does all this on a windows server, using excel installed on this machine. The import files are stored on user's machines.
If i try to import data from an file that is also open in Excel on the user's machine, then the app can't release the Excel COM objects.
Any ideea how can i fix this (close that instance anyway) ?
Thanks!
I've added my code :
public DataTable DoImportToDataTable(BackgroundWorker worker, string strPath, int columnCount, bool bIgnoreFirstLine = true)
{
bool importOk = false;
DataTable datatable = new System.Data.DataTable("ExcelContent");
Excel.Application excelApp = null; // the excel application instance
Excel.Workbook importFile = null; // the export workbook
Excel.Worksheet sheet = null; // the worksheet
Excel.Range range = null;
Excel.Sheets sheets = null;
try
{
excelApp = new Excel.Application();
excelApp.DisplayAlerts = false;
// try to open the file
importFile = excelApp.Workbooks.Open(strPath, Type.Missing, true, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
sheets = importFile.Worksheets;
sheet = (Excel.Worksheet)sheets.get_Item(1);
range = sheet.UsedRange;
int usedColumnsCount = range.Cells.Columns.Count;
int usedRowsCount = range.Cells.Rows.Count;
if (usedColumnsCount < columnCount)
{
throw new ImportException("Wrong file structure! Please check and correct the import file to match the requirements.");
}
Object[,] values = (Object[,])range.Value2;
data.Clear();
int row = 1;
// read data from used range
while (row <= usedRowsCount)
{
if (row == 1 && bIgnoreFirstLine)
{
row++;
continue;
}
if (worker.CancellationPending)
{
throw new Exception("Operation cancelled");
}
ArrayList line = new ArrayList();
bool bIsLineEmpty = true;
for (int i = 0; i < columnCount; i++)
{
if (values[row, i + 1] == null)
line.Add("");
else
{
line.Add((String)values[row, i + 1].ToString());
bIsLineEmpty = false;
}
}
if (bIsLineEmpty)
// return after first empty line in range
break;
datatable.Rows.Add(line.ToArray());
data.Add(line);
row++;
}
// cleanup
excelApp.DisplayAlerts = false;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
if (range != null) {
Marshal.FinalReleaseComObject(range);
range = null;
}
if (sheet != null) {
Marshal.FinalReleaseComObject(sheet);
sheet = null;
}
if (sheets != null)
{
Marshal.FinalReleaseComObject(sheets);
sheets = null;
}
if (importFile != null)
{
importFile.Close(Type.Missing, Type.Missing, Type.Missing);
Marshal.FinalReleaseComObject(importFile);
importFile = null;
}
if (excelApp != null)
{
excelApp.Quit();
Marshal.FinalReleaseComObject(excelApp);
excelApp = null;
}
importOk = true;
}
catch (COMException e)
{
message = e.Message;
}
catch (ImportException e)
{
message = e.ImportMessage;
}
catch (Exception e)
{
message = e.Message;
}
finally
{
if (!importOk)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
if (range != null)
{
Marshal.FinalReleaseComObject(range);
range = null;
}
if (sheet != null)
{
Marshal.FinalReleaseComObject(sheet);
sheet = null;
}
if (sheets != null)
{
Marshal.FinalReleaseComObject(sheets);
sheets = null;
}
if (importFile != null)
{
importFile.Close(Type.Missing, Type.Missing, Type.Missing);
Marshal.FinalReleaseComObject(importFile);
importFile = null;
}
if (excelApp != null)
{
excelApp.Quit();
Marshal.FinalReleaseComObject(excelApp);
excelApp = null;
}
}
}
return datatable;
}
I've just tried what you described, like this:
_Application app = new Application();
Workbook wb = app.Workbooks.Open(#"C:\Users\josip.INCENDO\Desktop\Payment (uplate) - primjer.xls");
wb.Close();
wb = null;
app.Quit();
app = null;
And it works perfectly fine, even if the user has opened document. Can you post the code maybe?
Have a look here: Excel 2007 Hangs When Closing via .NET
Always assign your excel objects to local variables, never going 'two dots down', like this:
//fail
Workbook wkBook = xlApp.Workbooks.Open(#"C:\mybook.xls");
//win
Worksheets sheets = xlApp.Worksheets;
Worksheet sheet = sheets.Open(#"C:\mybook.xls");
...
Marshal.ReleaseComObject(sheets);
Marshal.ReleaseComObject(sheet);
.NET creates a wrapper for the COM object that is invisible to you and is not released until the GC weaves its magic.

Categories