How to work with excel file in memory - c#

at the moment my current process is as followed. Query database - > Save file locally -> Open Workbook using Excel Interop Dll, Make Changes To Work Book, Save As using Excel Interop Dll. The reason for save as is because I require some addition settings so the file isn't set to read only.
The issue I'm coming across is that it's saving locally twice. First time is fine, second time a prompt will appear asking if I would like to override. I'm wondering how can I remove the Save File Locally process and have it in memory to work with? If I am able to work with the file in memory, I would have the prompt on Save As asking me if I would like to override the previous file.
Code:
//Save File Locally
System.IO.File.WriteAllBytes(saveFileDialog.FileName, Report.FileArray);
var fileLocation = saveFileDialog.InitialDirectory + saveFileDialog.FileName;
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
// Open Workbook Using Excel Interop Dll
Workbook wb = excel.Workbooks.Open(fileLocation);
Worksheet ws1 = wb.Worksheets.get_Item("English");
//Make Changes To WorkBook
ws1.Range["E5"].Value = StartDate;
ws1.Range["G5"].Value = EndDate;
// Save AS Using Excel Interop With shared settings to remove read only access
wb.SaveAs(fileLocation, AccessMode: XlSaveAsAccessMode.xlShared);
Process.Start(fileLocation);

You'd better disable the prompt, to what I remember this is possible but it imply a lot of umnaged code...
Try this
Microsoft.Office.Interop.MSProject.Application msProjectApp = new Microsoft.Office.Interop.MSProject.Application();
msProjectApp.DisplayAlerts = false;
Edit
Microsoft.Office.Interop.Excel.Application msProjectApp = new Microsoft.Office.Interop.Excel.Application();
msProjectApp.Visible = true; //show the application and not need to start a process
msProjectApp.DisplayAlerts = false;

//Save File Locally
System.IO.File.WriteAllBytes(saveFileDialog.FileName, Report.FileArray);
var fileLocation = saveFileDialog.InitialDirectory + saveFileDialog.FileName;
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
// Open Workbook Using Excel Interop Dll
Workbook wb = excel.Workbooks.Open(fileLocation);
Worksheet ws1 = wb.Worksheets.get_Item("English");
//Make Changes To WorkBook
ws1.Range["E5"].Value = StartDate;
ws1.Range["G5"].Value = EndDate;
// Save Only
wb.Save();
Remove Process.Start
excel.Visible = true;
excel.DisplayAlerts = false;

If you "own" the workbook and can set it up beforehand to play nice and are only loading in data, I find the OleDB Access SQL connection approach to be a better way to load raw data into SQL.

Related

Saving a .xlsm as .xlsx using Interop.Excel [duplicate]

This question already has answers here:
How do I save an XLSM file as an XLSX file without prompting the user about lost data? [duplicate]
(1 answer)
Save a *.xlsm file as *.xlsx and suppress the pop-up
(1 answer)
Closed 13 days ago.
This post was edited and submitted for review 13 days ago.
I have a C# program that runs a macro existing inside an xlsm file and after this macro has finished its operations, I would like to save this xlsm as .xlsx file. This is the code that runs and saves the macro file as xlsx:
void RunMacro(string macroFilename, string xlsxFilePath)
{
Excel.Application app = new Excel.Application();
Excel.Workbook workbook;
workbook = app.Workbooks.Open(macroFilename);
app.Visible = true;
app.Run("Main");
workbook.SaveAs(xlsxFilePath, Excel.XlFileFormat.xlOpenXMLWorkbook);
app.Workbooks.Close();
app.Quit();
}
Now, the issue is that in the line workbook.SaveAs(), I will get a prompt like this from Excel:
So how can I make it programatically that "Yes" is the default option here and this prompt is automatically closed without needing to click on anything?
EDIT:
The following threads (linked as the reason for closing this question) are not a solution:
How do I save an XLSM file as an XLSX file without prompting the user about lost data?
Save a *.xlsm file as *.xlsx and suppress the pop-up
Basically, there are two proposed solutions in these threads:
Set application.DisplayAlerts = false and call workbook.SaveAs(xlsxFilePath, Excel.XlFileFormat.xlOpenXMLWorkbook);
This still results in a prompt coming up where it is necessary to select 'Yes'. Here is my code:
void RunMacro(string macroFilename, string xlsxFilePath)
{
Excel.Application app = new Excel.Application();
Excel.Workbook workbook;
workbook = app.Workbooks.Open(macroFilename);
app.Visible = true;
app.DisplayAlerts = false;
app.Run("Main");
workbook.SaveAs(xlsxFilePath,Excel.XlFileFormat.xlOpenXMLWorkbook);
app.Workbooks.Close();
app.Quit();
}
Use Workbook.SaveCopyAs(xlsxFilePath)
This method call does circumvent the Excel prompt, but the xlsx file that it produces is corrupted:
Here is the code:
void RunMacro(string macroFilename, string xlsxFilePath)
{
Excel.Application app = new Excel.Application();
Excel.Workbook workbook;
workbook = app.Workbooks.Open(macroFilename);
app.Visible = true;
app.Run("Main");
workbook.SaveCopyAs(xlsxFilePath);
app.Workbooks.Close();
app.Quit();
}

Excel Interop - Set filename before saving

Is it possible to set the excel filename before file saving?
I have following simple code:
using Excel = Microsoft.Office.Interop.Excel;
Excel.Application excel = new Excel.Application();
excel.Visible = true;
Excel.Workbook workbook = excel.Workbooks.Add(Excel.XlSheetType.xlWorksheet);
Excel.Worksheet sheet = workbook.Sheets[1];
sheet.Cells[1, 1] = "Hello World!";
Is it possible to predefine this name before saving?
Thanks.
There is no explicit, foolproof way to do this prior to saving, unfortunately. The closest you could come is to use a template. If you have a template called FOO.xltx, you could create your workbook like this:
Application.Workbooks.Add "X:\path\to\FOO.xltx"
The only quirk is that the name for the new documents will be appended with an incrementing number (FOO1 the first time, then FOO2,FOO3, etc.).
To create a template, just create a new document, and when you save it, select Excel Template (*.xltx) from the Save as type dropdown.
You have to use saveas to save the file with the filename you want. Then when the user clicks save it will just update the file that was previously created. Unfortunately there is no other way. Here is the code:
workbook.SaveAs(Filename: FILENAMEHERE);
Here is the MSDN doc for it: https://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.workbook.saveas.aspx

Reading Excel XLTM files programmatically

I need to read XLTM files without opening it.
With Excel interop, i can read but it will open the file too.
The below link shows reading xlsx file with OLDB. But same wont work for XLTM.
http://codehill.com/2009/01/reading-excel-2003-and-2007-files-using-oledb/
Is there any way i can read XLTM file with out opening the file it self.
Thanks in Advance.
You can definitely use the Excel interop assembly, just set visibility and screenUpdation off like :
Microsoft.Office.Interop.Excel.Application xltmApp = new Microsoft.Office.Interop.Excel.Application();
xltmApp.Visible = false;
xltmApp.ScreenUpdating = false;
Workbook xltmBook = xltmApp.Workbooks.Open(#"C:\test.xltm");
...do stuff
Then close document properly see: http://msdn.microsoft.com/en-us/library/h1e33e36.aspx
Also if you want you can turn off dialog boxes during saving see: Trying to exit C# Excel Workbook without a dialog box.

Releasing Excel*32 process after operation complete

Trying to figure out why my EXCEL*32 process remains in use until both the my application AND the excel file are closed. I must be missing something after creation, it's like the application is holding onto the EXCEL *32 resource after this code. Any suggestions to get it to 'let go' after it's export operation is completed?
Also, I do not want to close the newly created Excel sheet, I just want to release the resource being used in relation to my actual .net application.
Application xls = new Application();
xls.SheetsInNewWorkbook = 1;
// Create our new excel application and add our workbooks/worksheets
Workbook Workbook = xls.Workbooks.Add();
Worksheet CrossoverPartsWorksheet = xls.Worksheets[1];
// Create our new excel application and add our workbooks/worksheets
Workbook Workbook = xls.Workbooks.Add();
Worksheet CrossoverPartsWorksheet = xls.Worksheets[1];
/////////////////////////////////////////
// < DO EXCEL EXPORT OPERATIONS HERE > //
/////////////////////////////////////////
// Release our resources.
Marshal.ReleaseComObject(Workbook);
Marshal.ReleaseComObject(CrossoverPartsWorksheet);
Marshal.ReleaseComObject(xls);
When you write
Workbook Workbook = xls.Workbooks.Add();
CLR creates RCW (Runtime Callable Wrapper) objects not only for Workbook, but for Workbooks collection too(coz you need object that then will be used for Add() method). And if CLR creates RCW object and you do not keep reference - you can't finalize it.
So, the main rule:
You should avoid double-dot-calling expressions:
var workbooks = xls.Workbooks;
var workbook = workbooks.Add();
Marshal.ReleaseComObject(workbook);
Marshal.ReleaseComObject(workbooks);
Marshal.FinalReleaseComObject(xls) is what your looking for.

Open excel with EPPlus without saving to file

Rright now I'm opening excel using
System.Diagnostics.Process.Start(fileInfo);
to open my package after saving it to a file.
Is it possible to open excel without having to save the file to a location? I would like the user to decide whether or not to save the file.
If you're generating the file yourself using EPPlus (or any other libraries that generate the file directly), you'll need to save it before you can open it in Excel. I'd recommend just saving it in the temp directory, then showing it to the user and letting them choose what to do with it.
If you generate the file using Office Automation, you can display it to the user before saving it.
I think this answer will help new developer.
I think best option for viewing Excel without saving is Microsoft.Office.Interop.Excel
Open Nuget Package Console Install-Package Microsoft.Office.Interop.Excel
create Excel file here is the official documentation Excel
at the end of filling Excel file just type app.Visible = true; app is the object name
I know this is late, but I had the same issue.
I used to use Microsoft.Office.Interop.Excel to export data to an xlsx file without saving it. It would present itself nicely as Book1.xlsx to the end-user who could them save it or close it without saving as required.
I have also moved to EPPlus to improve the speed of my exports and therefore, as you have experienced, cannot present the open file to the end-user without it first being saved.
The approach I have taken, using the SaveFileDialog component is to prompt the user for a name before the EPPlus file is created. This at least allows the end-user to identify where the file should be saved, rather than using a 'hard-coded' directory.
Private Sub btnExportXlsxEPPlus_Click(sender As Object, e As EventArgs) Handles btnExportXlsxEPPlus.Click
Try
Dim filInf As FileInfo = New FileInfo(GetFileToSave())
Using excelPackage As ExcelPackage = New ExcelPackage
excelPackage.Workbook.Properties.Author = "enLIGHTen"
excelPackage.Workbook.Properties.Title = "enLIGHTen Report"
excelPackage.Workbook.Properties.Subject = "enLIGHTen export data"
excelPackage.Workbook.Properties.Created = Date.Now
Dim worksheet As ExcelWorksheet = excelPackage.Workbook.Worksheets.Add("Sheet 1")
worksheet.Cells("A1").Value = "My EPPlus spreadsheet!"
worksheet.Cells(1, 2).Value = "This is cell B1!"
excelPackage.SaveAs(filInf)
End Using
Using excelPackage As ExcelPackage = New ExcelPackage(filInf)
Dim firstWorksheet As ExcelWorksheet = excelPackage.Workbook.Worksheets(1)
Dim namedWorksheet As ExcelWorksheet = excelPackage.Workbook.Worksheets("SomeWorksheet")
Dim anotherWorksheet As ExcelWorksheet = excelPackage.Workbook.Worksheets.FirstOrDefault(Function(x) x.Name Is "SomeWorksheet")
Dim valA1 As String = firstWorksheet.Cells("A1").Value.ToString
Dim valB1 As String = firstWorksheet.Cells(1, 2).Value.ToString
excelPackage.Save()
End Using
Dim proc As Process
Try
proc = New Process()
Process.Start(filInf.FullName)
Catch ex As Exception
MsgBox("File cannot be opened", MsgBoxStyle.Information, "Cannot open file")
End Try
Catch
End Try
End Sub
Public Function GetFileToSave()
Dim strFilename As String = ""
SaveFileDialog1.Filter = "Excel Workbook (*.xlsx)|*.xlsx"
If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
strFilename = SaveFileDialog1.FileName
Return strFilename
End If
End Function

Categories