I have a Visual Studio solution that contains two projects (1) a C# console application; and (2) a C# Excel Workbook.
The console application creates some data, which I would then like to pass into the workbook.
To do this I have created a method in the Excel workbook project, which receives data from the console application. However, I cannot create an instance of the Excel book. At the moment I am trying:
Excel.Application excelApplication = new Excel.Application();
Excel.Workbook excelWorkBook = excelApplication.Workbooks.Add("MyBook.xls");
I could hard code the path to the xls file, but I don't really want to do this as I would prefer to wrap everything up into a single .exe
Any ideas?
So basically what you're asking is how to wrap two files (an exe and an excel file), into a single exe.
There is a simple (and fairly clumsy) way of doing this which revolves around using Resources in C#, meaning your program will have to do something similar to the following:
Take excel file source out of Resources, and write it to a file when the program is run (temporary file)
Use the Current Directory + excel temp file name to feed into the Worksheet.Add method
Once edited, store the temporary file's data back into the Resources of your exe.
Another possibility would be, instead of using a temporary file, read a stream of bytes directly into Worksheets.Add if this is supported by the API (feel free to tell me if this is so).
EDIT: Great tutorial on using resources in C#.
Related
folks,
Environment
Windows 8.1
Visual Studio 2013
C#
Issue
How do I write values and make charts on visible Excel sheets using NPOI (https://npoi.codeplex.com/).
Why do I want that?
I'm developing an application to measure temperature in an apparatus. To put together experimental data in one place, I'd like to record data on an Excel sheet and make a chart on the sheet. In addition, I'd like to keep the Excel sheet visible and check the chart updated in real time.
You could also make graphs on Windows Form apps with MeasurementStudio by NationalInstruments for example but considering the flexibility of Excel charts (size and xy range changeable, easy-to-use user interface, etc...), I'd like to stick to Excel.
You can easily do this with Microsoft.Office.Interop.Excel by
ExcelApp.visible = true;. However, this module requires users to release every COM object generated. Otherwise, the objects remain and eat up memory. This is the reason I prefer to use NPOI.
How can I achieve this? Any answers would be appreciated.
You cannot do this with NPOI. NPOI reads and writes data from serialized Excel files. You cannot access those files while Excel has them open, and even if you could, Excel simply wouldn't re-read the files so your modifications wouldn't show up.
The problem you describe comes down to "I want to interact with a running Excel instance without using Excel interop". That's not going to work.
I was wondering if you had a couple of minutes to read over a WCF issue I've been working on trying to resolve.
I have a WCF service which utilizes XL Spreadsheets on the backend as part of it's calculation engine. I'm using a 3rd party .Net based component called Aspose to access, manipulate and retrieve data from the spreadsheet.
Unfortunately, Aspose ran into a couple of calculation bugs. In in order to overcome these issues, as a temporary fix, I save a temporary copy of the current spreadsheet. I then open the spreadsheet (which forces a recalc) with the Microsoft Excel .Net library - Microsoft.Office.Interop.Excel. Then I reopen that temp spreadsheet using Aspose to collect the result values
This fix has worked fine as I've been implementing/debugging the solution locally.
When I deployed the service to IS 7.0, the MS .Net Excel library fails when attempting to open the file.
I think this some kind of permissions issue with the deployed IIS service.
This is a snippet of the code that is failing
String fullPath1 = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "BCBSDiabetesCalculator.xlsm");
// Open to force Excel to perform calculation itself
Microsoft.Office.Interop.Excel.Application excelApp1 = new Microsoft.Office.Interop.Excel.Application();
var excelWorkbook1 = excelApp1.Workbooks.Open(fullPath1);
The following code block where I opening a filestream and passing it to the Aspose library call works.
//Get the Excel file into stream
FileStream stream = new FileStream(fileName, FileMode.Open);
//Instantiate LoadOptions specified by the LoadFormat.
LoadOptions loadOptions = new LoadOptions(LoadFormat.Xlsx);
//Create a Workbook object and opening the file from the stream
_workbook = new Workbook(stream, loadOptions);
if (_workbook == null)
{
}
// Make sure that we close the stream.
stream.Close();
Do you have any insight/ideas on how to resolve this?
When you use Microsoft.Office.Interop.Excel to open a file, this assumes Office is installed on the system spawning the process. But, the interop dll will spawn a separate Excel process which you can identify using the Task Manager. This Excel process is the actual desktop software being run in the background (it can be coded to run in the forground as well). So if you do have Excel installed on the server, spawning a separate process from within IIS is most likely the culprit. That being said, doing this should be avoided. Running Office automation on servers is a fragile solution at best, as errors with the Excel process could lead to zombie processes or worse. Microsoft advocates against this.
If possible, ( this is a suggestion since I have not used ASpose), use OpenXML. If you save the excel file to this format and ASpose can open it, you will not spawn an Excel process instance. If you have to do server side work with Office, and you can use OpenXML, it will avoid having to run the desktop applications through the interop dlls and save you lots of headaches.
I have a process that builds an Excel report, then opens it for the user. The problem is if someone leaves the file open, it stays locked and nobody else can build the report until the first person exits the excel file.
Is there a way to open an Excel file without locking it, using either Process.Start or Microsoft's Interop.Excel library?
I use the Interop library to build the file each time the report is run, and save it as a static file name in a shared network folder where this application is run from
using Excel = Microsoft.Office.Interop.Excel;
...
xlsBook.SaveAs(newFileName, Excel.XlFileFormat.xlWorkbookNormal);
And open the file using Process.Start
Process.Start(newFileName);
You can try to open the file in read-only mode:
var app = new Microsoft.Office.Interop.Excel.Application();
var workbook = app.Workbooks.Open(filename, ReadOnly: true);
Or you can try to save it in shared mode:
workbook.SaveAs(filename, AccessMode: XlSaveAsAccessMode.xlShared);
If the end user only has to read the file instead of also modifying it, you could create a shadow copy and then open that copy.
Simply copy the original file to a temporary location and open it from there. The original file remains untouched and can thus be opened by others.
I have UI tests. When the UI tests finish, they open the result files in an Excel document (Excel 2007 is installed on the test environment) - but the problem is that the excel document is not saved anywhere on the computer. They exist only when the AutoRecover feature saves the temporary files as a .xar file, so this is useless to us.
We use a C# .NET program to launch the UI tests (and do a bunch of other things), so I'm looking to see if it's possible to save this OPENED excel document programmatically.
Is that possible?
Thanks
This may help you How to: Save Workbooks
Example
This example creates a new workbook, prompts the user for a file name, and then saves the workbook.
Set NewBook = Workbooks.Add
Do
fName = Application.GetSaveAsFilename
Loop Until fName <> False
NewBook.SaveAs Filename:=fName
I have a dataset that I have modified into an xml document and then used a xsl sheet to transform into an Excel xml format in order to allow the data to be opened programatically from my application. I have run into two problems with this:
Excel is not the default Windows application to open Excel files, therefore when Program.Start("xmlfilename.xml") is run, IE is opened and the XML file is not very readable.
If you rename the file to .xlsx, you receive a warning, "This is not an excel file, do you wish to continue". This is not ideal for customers.
Ideally, I would like Windows to open the file in Excel without modifying the default OS setting for opening Excel files. Office interop is a possibility, but seems like a little overkill for this application. Does anyone have any ideas to make this work?
The solution is in .Net/C#, but I am open to other possibilities to create a clean solution.
If you insert the following into the 2nd line of your XML it directs Windows to open with Excel
<?mso-application progid="Excel.Sheet"?>
Process.Start(#"C:\Program Files\Microsoft Office\Officexx\excel.exe", "yourfile.xml");
That being said, you will still get the message box. I suppose that you could use the Interop, but I am not sure how well it will work for you.
What if you save the file as an xlsx, the extension for XML-Excel?
As Sam mentioned, the xlsx file extension is probably a good route to go. However, there is more involved than just saving the xml file as xlsx. An xlsx is actually a zip file with a bunch of xml files inside folders. I found some good sample code here which seems to give some good explanations although I haven't personally given it a try.
Apologies in advance for plugging a third party library, and I know it's not free, but I use FlexCel Studio from TMS Software. If you're looking to do more than just dump data (formatting, dynamic cross-tabs, etc) it works very well. We generate hundreds of reports a week using it.
FlexCel accepts strongly-typed datasets, it can group data according to relationships, and the generated Excel file looks so much cleaner than what you can get from a Crystal Reports excel export. I've done the crystal reports thing, and the OLE automation thing. FlexCel is a steal at $125 EU.
Hope this helps.
OpenXML in MSDN - http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.workbooks.openxml(v=office.11).aspx
using Excel = Microsoft.Office.Interop.Excel;
string workbookPath= #"C:\temp\Results_2013Apr02_110133_6692.xml";
this.lblResultFile.Text = string.Format(#" File:{0}",workbookPath);
if (File.Exists(workbookPath))
{
Excel.Application excelApp = new Excel.Application();
excelApp.Visible = true;
Excel.Workbook excelWorkbook = excelApp.Workbooks.OpenXML(workbookPath, Type.Missing, Excel.XlXmlLoadOption.xlXmlLoadPromptUser);
}
else
{
MessageBox.Show(String.Format("File:{0} does not exists", workbookPath));
}