C#, create excel 97-2003 (.xls) Interop - c#

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?

Related

Can we create Excel File using File.Create?

I want to create an Excel file, at specific location and specific name in c#.
Can we use File.Create("Filename.xlsx") for this?
This creates the file, but when we try to open it; it says problem in extension.
I have tried another way, using excelApp. But that way, it creates Excel file default at "~Documents\Sheet1.xlsx". So i can't specify location and filename in that case.
Excel.Application excelApp = new Excel.Application();
Excel.Workbook excelWorkBook = excelApp.Workbooks.Add(1);
The question is similar to - Specify Path and filename while creating excel
Since i am unable to comment, i have to ask again.
I have tried the answer provided in link.
My code:
Excel.Application excelApp = new Excel.Application();
object missing = System.Reflection.Missing.Value;
Excel.Workbook excelWorkBook = excelApp.Workbooks.Add(missing);
//....
Fill excelWorkbook after creating worksheets
....//
excelWorkBook.Save();
Now, as per suggestion, instead of Save, i have used SaveAs.
excelWorkBook.SaveAs(#"E:\\MyExcelBook\\abcd.xlsx",
Excel.XlFileFormat.xlOpenXMLWorkbook, missing, missing,
false, false, Excel.XlSaveAsAccessMode.xlNoChange,
missing, missing, missing, missing, missing);
It gives me error:
*The file could not be accessed. Try one of the following:\n\n• Make sure the specified folder exists. \n• Make sure the folder that contains the file is not read-only.\n• Make sure the file name does not contain any of the following characters: < > ? [ ] : | or \n• Make sure the file/path name doesn't contain more than 218 characters.
Please tell me where am i doing wrong?
Just because you save an "empty" file with an extension of .xlsx doesn't mean excel is able to read such a file. You can use OpenXML, ClosedXML (my preferred), interop (yucky) and I'm sure many other methods of creating an excel document
File.Create(...) is not much different than right clicking in file explorer, choosing new text document, and renaming it from "New Text Document.txt" to "New Text Document.xlsx". Yeah that extension is excel, but excel can't read an empty file that states it's an excel file.
You can use any of the libraries available to you to create excel files:
ClosedXML
OpenXML
Interop
etc. Most "Save" methods or "SaveAs" methods within these libraries would (probably) create the file in the working directory by default, but you can specify a directory to create them in as well.
Just as the answer in the linked question shows:
workbook.SaveAs(#"c:\documents\book1.xlsx",
Excel.XlFileFormat.xlOpenXMLWorkbook, missing, missing,
false, false, Excel.XlSaveAsAccessMode.xlNoChange,
missing, missing, missing, missing, missing);

Excel interop - saving my newly created spreadsheet throws an exception

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.

Word Interop app to write text to the end of an open document

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

Error while opening an excel workbook using C# 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".

Using Interop with C#, Excel Save changing original. How to negate this?

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#

Categories

Resources