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.
Related
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);
}
}
}
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();
}
}
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 8 years ago.
I am making a Program to convert a csv( common selected value file) file into xls(microsoft excel file) file
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Excel = Microsoft.Office.Interop.Excel;
namespace ConversionToXLSFile
{
public partial class Converter : System.Web.UI.Page
{
//Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
//xlWorkBook = xlApp.Workbooks.Add(misValue);
//xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
protected void Page_Load(object sender, EventArgs e)
{
//List<string> row = new List<string>();
string fullPath = #"D:\Work\Sep-14\ConversionToXLSFile\ConversionToXLSFile\File\diff_16122014095440.csv";
string[] fileRows = File.ReadAllLines(fullPath, Encoding.UTF8);
foreach (string rows in fileRows)
{
var columns = rows.Split(';');
for (int j = 0; j < fileRows.Length; j++)
{
for (int i = 0; i < columns.Length; i++)
{
List<string> elements = new List<string>();
foreach (string col in columns)
{
elements.Add(col);
xlWorkSheet.Cells[j, i] = col;
}
}
}
}
xlWorkBook.SaveAs("d:\\csharp-Excel.xls", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
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;
Console.WriteLine("Exception Occured while releasing object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
private void Add(dynamic dynamic)
{
throw new NotImplementedException();
}
}
}
As far as I can see, you've commented out the code where you assign the variables xlApp, xlWorkBook and xlWorkSheet...
//Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
//xlWorkBook = xlApp.Workbooks.Add(misValue);
//xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
Take the // out of each line and you won't get null reference exceptions when you try to use them.
I am Generating a Excel sheet from datatable dyanamically. I am able to add text into different cells as i needed. But i do not have any idea about how to add picture into a specified range..
Excel.Application oApp = new Excel.Application();
oApp.Application.Workbooks.Add(Type.Missing);
oApp.Range["B2", "C4"].Merge(Type.Missing);
Here i want to add picture..
I am trying like
System.Drawing.Image imgg = System.Drawing.Image.FromFile("c:\\D.jpg");
Now how could i add/copy my imgg into this range?? e.g.
App.Range["B2", "C4"]
You can get benefited with the following
using System;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Excel.Application xlApp ;
Excel.Workbook xlWorkBook ;
Excel.Worksheet xlWorkSheet ;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
//add some text
xlWorkSheet.Cells[1, 1] = "Text1";
xlWorkSheet.Cells[2, 1] = "Text2";
xlWorkSheet.Shapes.AddPicture("C:\\sample.jpg", Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoCTrue, 50, 50, 300, 45);
xlWorkBook.SaveAs("MyExcelFile.xls", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
releaseObject(xlApp);
releaseObject(xlWorkBook);
releaseObject(xlWorkSheet);
MessageBox.Show ("File created !");
}
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();
}
}
}
}
Have you tried giving position with excelpicture?
var picture = worksheet.Drawings.AddPicture("image_name", imgg);
picture.SetPosition(int row,int rowoffsetpixels,int column,int coloumoffsetpixels);//position for the image
You can add an image to your Excel spreadsheet quite easily (this assumes that you are using Microsoft.Office.Interop.Excel assembly reference, in C#) like this:
private Worksheet _xlSheet;
private Image _platypusLogo;
. . .
private void AddImage()
{
Clipboard.SetDataObject(_platypusLogo, true);
var cellRngImg = (Range)_xlSheet.Cells[IMAGE_ROW, IMAGE_COLUMN];
_xlSheet.Paste(cellRngImg, _platypusLogo);
}
Note that "IMAGE_ROW" and "IMAGE_COLUMN" are int constants or you can just use hard-coded ints, if you want to fly in the face of Steve McConnell's advice in Code Complete about constantifying all numbers other than sometimes 0 and 1
An image needs to be assigned to _platypusLogo. If you are using a C# utility app to dynamically generate the Excel spreadsheet, you could add a PictureBox control to a form, and then assign an image to it via its Image property (the control is named, by default, pictureBox1), and then assign it to the spreadsheet this way:
_platypusLogo = pictureBox1.Image;
Of course, you can assign to _platypusLogo directly/exclusively in code, too, if you prefer.
I have created excel workbook using .NET interop. The excel workbook is created successfully through my C# code. When the user makes any changes in the excel, I want to do some stuff. I have used the ExcelWorkSheet.Change event. But this event is not firing. Here is my code-
using Excel = Microsoft.Office.Interop.Excel;
public class xxx
{
static Excel.Application xlApp;
static Excel.Workbook xlWorkBook;
static Excel.Worksheet xlWorkSheet;
static Excel.Worksheet xlWorkSheet1;
static Excel.DocEvents_ChangeEventHandler EventDel_CellsChange;
public static void ExportToExcel()
{
xlApp = new Excel.ApplicationClass();
object misValue = System.Reflection.Missing.Value;
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
xlWorkSheet1 = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(2);
---------------- data is dumped to the excel here----------------
((Microsoft.Office.Interop.Excel._Worksheet)xlWorkSheet).Activate();
xlApp.EnableEvents = true;
EventDel_CellsChange = new Excel.DocEvents_ChangeEventHandler(Worksheet_Change);
xlWorkSheet.Change += EventDel_CellsChange;
xlWorkBook.SaveAs("D:\\Test.xlsx", Excel.XlFileFormat.xlWorkbookDefault, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlShared, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
releaseObject(xlWorkSheet1);
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "application/vnd.ms-excel";
response.AddHeader("Content-Disposition", "attachment; filename=Test.xlsx;");
response.TransmitFile(("D:\\Test.xlsx");
response.Flush();
response.End();
}
public static void Worksheet_Change(Excel.Range Target)
{
try
{
xlApp.EnableEvents = false;
Excel.Range range = xlWorkSheet.get_Range("Y2");
range.Formula = "=A2";
}
catch (Exception ex)
{
}
finally
{
xlApp.EnableEvents = true;
}
}
}
No change is reflected in the Excel file when the user makes some changes.
Please help me out.
Thanks in advance
The Worksheet_Change event is not global - it only applies to that particular worksheet. In your code you wire up the event handler to the xlSheet1.Change event, then close the workbook and release all the Excel objects.
EDIT: I popped your code behind a Form and adapted it slightly. I could get the event to fire and the formula in cell Y2 is set. I'm not 100% sure of your circumstances, but try this code and then compare with your own. Hope it helps.
public partial class Form1 : Form
{
private static Excel.Application xlApp;
private static Excel.Workbook xlWorkBook;
private static Excel.Worksheet xlWorkSheet;
private static Excel.Worksheet xlWorkSheet1;
private static Excel.DocEvents_ChangeEventHandler EventDel_CellsChange;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
xlApp = new Excel.Application();
xlApp.Visible = true;
object misValue = System.Reflection.Missing.Value;
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
xlWorkSheet1 = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(2);
//---------------- data is dumped to the excel here----------------
((Microsoft.Office.Interop.Excel._Worksheet)xlWorkSheet).Activate();
xlApp.EnableEvents = true;
EventDel_CellsChange = new Excel.DocEvents_ChangeEventHandler(Worksheet_Change);
xlWorkSheet.Change += EventDel_CellsChange;
}
public static void Worksheet_Change(Excel.Range Target)
{
try
{
xlApp.EnableEvents = false;
Excel.Range range = xlWorkSheet.get_Range("Y2");
range.Formula = "=A2";
}
catch (Exception ex)
{
}
finally
{
xlApp.EnableEvents = true;
}
}
}