Is it possible to import data from Excel through memory? - c#

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();
}
}

Related

c# data to excel export gives empty file

I'm currently working on some Excel import/export using c#,
her is my export function:
private void myButton11_Click(object sender, EventArgs e)
{
Microsoft.Office.Interop.Excel.Application excel;
Microsoft.Office.Interop.Excel.Workbook excelworkbook;
Microsoft.Office.Interop.Excel.Worksheet excelsheet;
Microsoft.Office.Interop.Excel.Range excelCellFormat;
excel = new Microsoft.Office.Interop.Excel.Application();
excel.Visible = false;
excel.DisplayAlerts = false;
excelworkbook = excel.Workbooks.Add(Type.Missing);
excelsheet = (Microsoft.Office.Interop.Excel.Worksheet)excelworkbook.ActiveSheet;
excelsheet.Name = "dataToExcel";
// fill in data
excelsheet.Cells[1, 1] = "test";
// left it pretty much empty so you have a nice exemple
excelCellFormat = excelsheet.Range[excelsheet.Cells[1, 1], excelsheet.Cells[max+1, 13]];
excelCellFormat.EntireColumn.AutoFit();
Microsoft.Office.Interop.Excel.Borders border = excelCellFormat.Borders;
border.LineStyle = Microsoft.Office.Interop.Excel.XlLineStyle.xlContinuous;
border.Weight = 2d;
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Excel (*.xlsx)|*.xlsx";
sfd.Title = "Sauvegarde";
sfd.ShowDialog();
if(sfd.FileName != "")
{
System.IO.FileStream fs = (System.IO.FileStream)sfd.OpenFile();
// save excel
excelworkbook.SaveAs(fs,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value);
fs.Close();
}
excel.Quit();
// for a pdf version
//excelworkbook.ExportAsFixedFormat(Microsoft.Office.Interop.Excel.XlFixedFormatType.xlTypePDF,
// Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "//dataAsPDF.pdf",
// Microsoft.Office.Interop.Excel.XlFixedFormatQuality.xlQualityStandard,
// true, true, 1, 10, false);
}
my problem is, when saving using the external window, It saves properly... but as an empty file, like totally empty (opening it with notepad shows an empty file)
any idea what my problem could be?
thanks!
Here is a generic code sample which creates a new file, renames a sheet, adds a sheet then sets text of the first sheet cell A1 to Hello Excel.
Excel class
using System;
using System.Diagnostics;
using System.Linq;
using System.IO;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
namespace ExcelInteropApp.Classes
{
public class ExcelOperations
{
public delegate void OnAction(string sender);
public static event OnAction ActionHandler;
/// <summary>
/// create an excel file, rename sheet1 (default sheet),
/// create another worksheet, rename it and re-order to end.
/// </summary>
/// <param name="fileName">path and file name for excel file</param>
/// <param name="firstWorkSheetName">name for default sheet</param>
/// <param name="secondWorkSheetName">name for newly added sheet</param>
public static (bool success, Exception exception) CreateExcelFile(string fileName, string firstWorkSheetName, string secondWorkSheetName, bool open)
{
try
{
if (File.Exists(fileName))
{
File.Delete(fileName);
}
Excel.Application xlApp;
Excel.Workbooks xlWorkBooks;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Sheets xlWorkSheets;
xlApp = new Excel.Application { DisplayAlerts = false };
xlWorkBooks = xlApp.Workbooks;
xlWorkBook = xlWorkBooks.Add();
xlWorkSheets = xlWorkBook.Sheets;
xlWorkSheet = (Excel.Worksheet)xlWorkSheets[1];
xlWorkSheet.Name = firstWorkSheetName;
ActionHandler?.Invoke("renamed first sheet");
Excel.Worksheet xlNewSheet = (Excel.Worksheet)xlWorkSheets
.Add(xlWorkSheets[1],
Type.Missing,
Type.Missing,
Type.Missing);
xlNewSheet.Move(System.Reflection.Missing.Value, xlWorkSheets[xlWorkSheets.Count]);
xlNewSheet.Name = secondWorkSheetName;
Excel.Range xlRange1 = null;
xlRange1 = xlWorkSheet.Range["A1"];
xlRange1.Value = "Hello Excel";
Marshal.FinalReleaseComObject(xlRange1);
xlRange1 = null;
ActionHandler?.Invoke("Done with add sheet");
Marshal.FinalReleaseComObject(xlNewSheet);
xlNewSheet = null;
xlWorkBook.SaveAs(fileName);
ActionHandler?.Invoke("Saved file");
xlWorkBook.Close();
xlApp.UserControl = true;
xlApp.Quit();
Marshal.FinalReleaseComObject(xlWorkSheets);
xlWorkSheets = null;
Marshal.FinalReleaseComObject(xlWorkSheet);
xlWorkSheet = null;
Marshal.FinalReleaseComObject(xlWorkBook);
xlWorkBook = null;
Marshal.FinalReleaseComObject(xlWorkBooks);
xlWorkBooks = null;
Marshal.FinalReleaseComObject(xlApp);
xlApp = null;
ActionHandler?.Invoke($"Clean-up: {(Process.GetProcesses().Any((p) => p.ProcessName.Contains("EXCEL")) ? "Released" : "Not released")}");
if (open)
{
ActionHandler?.Invoke("Opening");
Process.Start(fileName);
}
else
{
ActionHandler?.Invoke("Not opening");
}
return (true, null);
}
catch (Exception exception)
{
return (false, exception);
}
}
}
}
Form code, one button and a list box
using System;
using System.IO;
using System.Windows.Forms;
using ExcelInteropApp.Classes;
namespace ExcelInteropApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void CreateExcelButton1_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
ExcelOperations.ActionHandler += ExcelOperationsOnActionHandler;
string fileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Demo.xlsx");
string firstSheet = "Karen";
string secondSheet = "Karen 1";
var (success, exception) = ExcelOperations.CreateExcelFile(fileName,firstSheet, secondSheet, openWhenDoneCheckBox.Checked);
if (success == false)
{
Console.WriteLine(exception.Message);
}
ExcelOperations.ActionHandler -= ExcelOperationsOnActionHandler;
}
private void ExcelOperationsOnActionHandler(string sender)
{
listBox1.Items.Add(sender);
}
}
}

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.

Export to specific Excel worksheet name

I am trying to export data to an Excel template. I have multiple tabs in the workbook. The worksheet tab I want to export to is called "Feasibility". Question is: how can I export to this specific worksheet name?
using Excel = Microsoft.Office.Interop.Excel;
//excel output variables
private string excelFileName = SqlDB.GetFolderTemplates() + SqlDB.GetFileEngOrd();
private static Excel.Application xlsApp;
private static Excel.Workbooks workbooks;
private static Excel.Workbook workbook;
private Excel.Worksheet worksheet;
private void btnFeasibility_Click(object sender, EventArgs e)
{
xlsApp = new Excel.ApplicationClass();
if (xlsApp == null)
{
MessageBox.Show(Constants.EXCEL_INSTALL);
return;
}
try
{
xlsApp.Visible = true;
workbooks = xlsApp.Workbooks;
workbook = xlsApp.Workbooks.Open(excelFileName);
//PROBLEM IS HERE -- HOW CAN I GO TO THE WORKSHEET NAMED "FEASIBILITY"
worksheet = (Excel.Worksheet)workbook.Sheets[1];
worksheet.Select();
worksheet.Cells[3, 4] = newEngOrd.CustName;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
//release excel
System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheet);
worksheet = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
workbook = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlsApp);
xlsApp = null;
GC.GetTotalMemory(false);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.GetTotalMemory(true);
MessageBox.Show("Export Complete");
}
}
Run a for look through all the sheets, and see if the name match.
int foundNr=-1;
InteropExcel.Sheets sheets = workbook.Sheets;
InteropExcel.Sheet tempSheet = null;
for (int sheetIndex = 1; sheetIndex <= sheets.Count; sheetIndex++)
{
tempSheet = (InteropExcel.Worksheet)sheets[sheetIndex];
if (tempSheet.Name == "Feasibility")
{
foundNr = sheetIndex;
Marshal.FinalReleaseComObject(tempSheet);
tempSheet = null;
break
}
Marshal.FinalReleaseComObject(tempSheet);
tempSheet = null;
}
if (foundNr != -1)
{
sheet = (InteropExcel.Worksheet)sheets[foundNr];
}
The way I do release is to assign null to your COM variables. Then you call FinalReleaseComObject if it is not null in the finally statement. That way it gets released even if there is an exception in the method.
Excel process not closing
InteropExcel.Sheets sheets = null
try
{
sheets = ....;
}
finally
{
if (sheets != null)
{
Marshal.FinalReleaseComObject(sheets);
sheets = null;
}
}
did you tried the Name property?
check this Worksheet documentation: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.worksheet_members.aspx

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;
}
}

Need help on getting a simple method to readxml

Need help on getting a simple method to readxml.
Here are the steps that I have taken:
Added reference from Microsoft Excel 12.0 Object Library COM.
Copied code exactly from another source
http://csharp.net-informations.com/excel/csharp-read-excel.htm
The only difference that I would require this to be a method and Not
an onclick event.
The error I'm getting is Error 10 An object reference is required for the non-static field, method, or property on code releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
What are the steps required?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
namespace projectName
{
class frmReadXml
{
public static void executeRead()
{
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet = new Excel.Worksheet();
Excel.Range range;
string str;
int rCnt = 0;
int cCnt = 0;
xlWorkBook = xlApp.Workbooks.Open("csharp.net-informations.xls", 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 (rCnt = 1; rCnt <= range.Rows.Count; rCnt++)
{
for (cCnt = 1; cCnt <= range.Columns.Count; cCnt++)
{
str = (string)(range.Cells[rCnt, cCnt] as Excel.Range).Value2;
MessageBox.Show(str);
}
}
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();
}
}
}
}
make releaseObject as static method
private static void releaseObject(object obj)
Because your function:
public static void executeRead()
is declared as static, it only has access to other functions that are also defined as static. Either remove the static on this function, or add it to the others. Since none of these seem to access any class members of the frmReadExcel, I suggest you make them all static.

Categories