I am using C# to create a spreadsheet, here is the code:
try
{
_excel = new Excel.Application();
_excel.Visible = false;
_workbook = _excel.Workbooks.Add( Type.Missing );
_worksheet = (Excel.Worksheet)_workbook.Sheets[1];
createColumnHeaders();
_workbook.SaveCopyAs( savePath );
}
catch (Exception ex)
{
Logger.Error( "Error creating spreadsheet: {0}", ex.Message );
}
finally
{
// Cleanup
}
This runs nicely, saves the sheet into the savePath. However, if I change SaveCopyAs() to
SaveAs( savePath,
Excel.XlFileFormat.xlWorkbookNormal,
Type.Missing,
Type.Missing,
false,
false,
XlSaveAsAccessMode.xlNoChange,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing );
then the application gets a COMException saying
'C:\//temp/00-04.20.18-24-07-2014/' cannot be accessed. The file may be corrupted,
located on a server that is not responding, or read-only.
This is a pain since I really need to be saving in .xls format, not .xlsx. Any ideas why this exception occurs for SaveAs()?
It's kinda obvious what went wrong here. That's not a valid path of course, // should only ever appear as the lead characters for a path to name the machine that contains the file system.
You'll have to de-tune the "Windows works like Unix" expectation when you work with Microsoft application software. Forward slashes in a path are not a problem when you make direct operating system calls. Windows supports them well, not in the least because Windows NT once supported Posix out of the box. The same is not true for other apps, particularly the kind whose source-code base is 25 years old. But is not limited to just old code, VS has problems too. Microsoft treats these kind of bugs reports a bit like Jeff Atwood treats pluralization bugs.
The proper path separator character without any surprises is a backslash.
Related
Unable to create the excel file at particular path when the application is run from IIS. But its created when the code is debuged using visual studio 2008.Even i have tried out using absolute path and using server.mappath() function but in vain.Server throws the error : HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /Error.aspx
The code is given below:
private void CreateExcel(DataTable dt)
{
try
{
FilePath = "\\\\192.168.1.252\\GNC Reports\\TallyExport.xls";
Excel.Application oXL = new Excel.Application();
//Get a new workbook.
Excel._Workbook oWB = (Excel._Workbook)(oXL.Workbooks.Add(Type.Missing));
// *************** Sheet 1
Excel._Worksheet oSheet = (Excel._Worksheet)oWB.Sheets["Sheet1"];
oSheet.Name = "Journal";
WriteWxcel(oSheet, dt, 3);
//***************** Sheet 2
oSheet = (Excel._Worksheet)oWB.Sheets["Sheet2"];
oSheet.Name = "Payroll";
WriteWxcel(oSheet, dt, 4);
// ************* Sheet 3
oSheet = (Excel._Worksheet)oWB.Sheets["Sheet3"];
oSheet.Name = "Receipt";
WriteWxcel(oSheet, dt, 2);
//Save Excel File
oWB.SaveAs(FilePath, Excel.XlFileFormat.xlWorkbookNormal, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
oXL.Quit();
}
catch (Exception ex)
{
BussinessLayer.CMSException.Instance.HandleMe(this, ex);
}
}
Using Office Interop from server-like scenarios (IIS/ASP.NET/Windows Service...) is NOT supported by MS - see http://support.microsoft.com/default.aspx?scid=kb;EN-US;q257757#kb2
Another point is that since windows vista there have been several security-related changed which prevent doing any "desktop-like" things (for example printing, writing to a network share...) from a Windows Service...
Alternative to Interop:
There are many options to read/edit/create Excel files without Interop:
MS provides the free OpenXML SDK V 2.0 - see http://msdn.microsoft.com/en-us/library/bb448854%28office.14%29.aspx (XLSX only)
This can read+write MS Office files (including Excel).
Another free option see http://www.codeproject.com/KB/office/OpenXML.aspx (XLSX only)
IF you need more like handling older Excel versions (like XLS, not only XLSX), rendering, creating PDFs, formulas etc. then there are different free and commercial libraries like ClosedXML (free, XLSX only), EPPlus (free, XLSX only), Aspose.Cells, SpreadsheetGear, LibXL and Flexcel etc.
I'm trying to write a C# application that will find a document open in MS Word and write some text to the end of the document using word interop. Is this possible?
I know it's possible to kind of solve this problem using Process and Sendkeys built into the .NET Framework, but I'd like to solve the problem using Word Interop so I can add more functionality down the road (also sendkeys would really only solve the problem in certain special cases.)
Thanks!
Update:
I got the following partial solution working:
Application wordApp = new Application();
wordApp.Visible = true;
wordApp.Documents.Add();
Range rng = wordApp.ActiveDocument.Range(0, 0);
rng.Text = "New Text";
But I'd like to use an already open instance of word instead of creating a new one. Thanks!
Update 2:
I'm close! The following code works with UAC turned off
Application wordApp = (Word.Application)Marshal.GetActiveObject("Word.Application");
Range rng = wordApp.ActiveDocument.Range(0, 0);
rng.Text = "New Text";
But I'm not sure how to get it working with UAC enabled. UAC isn't causing any errors or exceptions, it just doesn't write the text to the open document.
Thanks for everyones help so far, the end is now in sight :)!
Update 3:
Just tried it again with UAC turned on and it worked... strange. Still if you know of any good resources about interop and UAC in general, please post a link here!
Have you looked at using Marshal.GetActiveObject("Word.Application") to get the running application, rather than creating a new one?
Definitely Evan. The Microsoft Office Interop Assemblies let you do just about anything from C#! SendKeys() is an issue.
http://msdn.microsoft.com/en-us/library/15s06t57(v=vs.80).aspx
I guess I should elaborate about SendKeys(): it doesn't even work reliably anymore as it was a primary hacker tool. The MS Office Interop Assemblies allow you to do an enormous array of things with each of the Office components. I have used them extensively with MS Excel, and some with Word, and you can do just about anything a user can do programatically.
You can try below .Here i am giving example with image insert.
WordC.Application wordApp = new WordC.Application();
// create Word document object
WordC.Document aDoc = null;
object readOnly = false;
object isVisible = false;
wordApp.Visible = false;
// wordApp.DisplayAlerts = false;
//docFileName is the filename with complete path. ex c://test.doc
aDoc = wordApp.Documents.Open(docFileName, Type.Missing, ref readOnly, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, ref isVisible, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
aDoc.Activate();
aDoc.InlineShapes.AddPicture(imgFilename, Type.Missing, Type.Missing, Type.Missing);
aDoc.Save();
aDoc.Close(Type.Missing, Type.Missing, Type.Missing);
wordApp.Quit(Type.Missing, Type.Missing, Type.Missing);
using Excel = Microsoft.Office.Interop.Excel;
I need to save a excel file (.xls) from my datagridview. All works fine, writing data, changing cell format etc. But problem appears while saving the doc.
string format = "yyyy_MM_dd_HH-mm";
string pathtoexport = #"C:\DM\SMS\Przychodzace\Znalezione_SMS_" + DateTime.Now.ToString(format) + ".xls";
oWB.SaveAs(pathtoexport, Excel.XlFileFormat.xlWorkbookNormal, missing, missing,
false, false, Excel.XlSaveAsAccessMode.xlNoChange,
missing, missing, missing, missing, missing);
}
Well some days ago it was working, but now it can only say
HRESULT: 0x800A03EC"}
I need .xls to import it to SQL. Any advices?
Before the problem was at Excel.XlFileFormat.xlWorkbookDefault, when Iv changed it to Normal it was doing well. Now it doesnt work. LOst much time to handle it on my own with google, but I failed.
oWB.SaveAs(MyFile + #"C:\SMS\XMLCopy.xls",
Excel.XlFileFormat.xlWorkbookNormal, missing, missing,
false, false, Excel.XlSaveAsAccessMode.xlNoChange,
missing, missing, missing, missing, missing);
string format = "yyyy_MM_dd_HH-mm";
string pathtoexport = "C:\\DM\\SMS\\Przychodzace\\Znalezione_SMS_" + DateTime.Now.ToString(format) + ".xls";
oWB.SaveAs(pathtoexport, Excel.XlFileFormat.xlWorkbookNormal, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Now it works. Thanks for help.
Try with Excel.XlFileFormat.xlWorkbookDefault
I can't see anything obviously wrong with your code. Is it possible that there is some problem with accessing that path? If you try to save a file manually to that exact path (assuming that you're logged in under the same account as the interop process runs under), does it work?
Otherwise, are you using some kind of Excel template file or something that could have become corrupted?
If you/your customer can afford, there is Aspose.Cells which is great for generating Excel documents from scratch, without the need for Office being installed on a machine.
On the other hand, the solution costs money.
Looks to me like an Interop version conflict. Are you experiencing the problem on the same machine as it used to work on or have you moved to another? If you're on the same try to back track and figure out any changes or updates. If you're on another then verify that you have the correct version installed there.
This might sound stupid but I've encountered all sorts of wierdness when moving from dev -> test -> prod due to inconsistencies between the environments.
If you haven't already, try removing the reference from the project and reapplying it.
It could also be due to permissions (or lack there of). Have you tried creating a plain text file from the same piece of code?
I'm trying to open an excel workbook and trying to get a worksheet in it. Excelapp.workbooks.Open line is throwing an Exception as
System.Runtime.InteropServices.COMException from HRESULT: 0x800A03EC at Microsoft.Office.Interop.Excel.Workbooks.Open
Here is my code:
Excel.Application excelApp = new Excel.ApplicationClass();
Excel.Workbook excelWorkbook = excelApp.Workbooks.Open(strWBPath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing, true);
StrWbPath is my Excel location. I'm refering to 2007 excel and added Microsoft.office.interop.excel of version 12.0.0.0.
(Sorry for answering this old question, but it's google result #1 for this problem and the correct answer is missing).
The error occurs because excel thinks the Workbook has been corrupted. When opening the Excel file, the last parameter tells excel how to handle this situation. Pass Microsoft.Office.Interop.Excel.XlCorruptLoad.xlExtractData to instruct it to retrieve the data (This will open a popup telling the user excel tried to extract the data if the file is corrupted).
However, I noticed this problem can also be caused if the workbook you are trying to open has a different locale than your excel (was saved on a machine using another language setting) OR your system not having the en-us locale set.
While this is extremely stupid, it's easy to overcome. For me the solution was to just set the current locale to en-us before opening the file:
static System.Globalization.CultureInfo oldCI;
oldCI = System.Threading.Thread.CurrentThread.CurrentCulture;
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
xlWorkBook = xlApp.Workbooks.Open(filePath, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, Microsoft.Office.Interop.Excel.XlCorruptLoad.xlExtractData);
System.Threading.Thread.CurrentThread.CurrentCulture = oldCI;
credit goes to this page
What if you try System.Reflection.Missing.Value instead of Type.Missing?
Regards,
M.
Which class are you using?
Microsoft.Office.Interop.Excel.ApplicationClass
if this then try changing it to
Microsoft.Office.Interop.Excel.Application
In case it helps someone else, I lost tons of time on this one. I was passing Microsoft.Office.Interop.Excel.XlCorruptLoad.xlRepairFile for the CorruptedLoad parameter for all files, thinking it meant "open the file, and if it's corrupt, attempt a repair". This worked for most files.
However, for some files, I was still getting the exception (Exception from HRESULT: 0x800A03EC). Yet if you open the file in Excel manually, it is not corrupt.
It turned out that for those files, you must not supply the CorruptedLoad parameter. Then it opens successfully. So in the end I adjusted my code to first try without any CorruptedLoad parameter, and only if that returns the exception, then try passing xlRepairFile for that parameter. I also adjusted my understanding of that parameter to mean "open and repair this file regardless of whether it's corrupt".
The problem: Loading an excel spreadsheet template. Using the Save command with a different filename and then quitting the interop object. This ends up saving the original template file. Not the result that is liked.
public void saveAndExit(string filename)
{
excelApplication.Save(filename);
excelApplication.Quit();
}
Original file opened is c:\testing\template.xls
The file name that is passed in is c:\testing\7777 (date).xls
Does anyone have an answer?
(The answer I chose was the most correct and thorough though the wbk.Close() requires parameters passed to it. Thanks.)
Excel interop is pretty painful. I dug up an old project I had, did a little fiddling, and I think this is what you're looking for. The other commenters are right, but, at least in my experience, there's a lot more to calling SaveAs() than you'd expect if you've used the same objects (without the interop wrapper) in VBA.
Microsoft.Office.Interop.Excel.Workbook wbk = excelApplication.Workbooks[0]; //or some other way of obtaining this workbook reference, as Jason Z mentioned
wbk.SaveAs(filename, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, XlSaveAsAccessMode.xlNoChange,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing);
wbk.Close();
excelApplication.Quit();
Gotta love all those Type.Missings. But I think they're necessary.
Rather than using an ExcelApplication, you can use the Workbook object and call the SaveAs() method. You can pass the updated file name in there.
Have you tried the SaveAs from the Worksheet?
Ditto on the SaveAs
Whenever I have to do Interop I create a separate VB.NET class library and write the logic in VB. It is just not worth the hassle doing it in C#