I'm wondering if it is possible to write to an Excel file using C#/EPPlus while I have the file open. I continue to get exceptions while trying to write using my program and I can't find anything online.
Here is the code I have to append to an existing worksheet which works fine when the spreadsheet isn't opened
public static void AppendExistingMailingWorkbook(string workSheet, string filePath, IList<MailingReportItem> reportData)
{
//create a fileinfo object of an excel file on the disk
FileInfo file = new FileInfo(filePath);
Object thisLock = new Object();
lock (thisLock)
{
//create a new Excel package from the file
using (ExcelPackage excelPackage = new ExcelPackage(file))
{
ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[workSheet];
var rowToAppend = worksheet.Dimension.End.Row + 1;
for (int i = 0; i < reportData.Count; i++, rowToAppend++)
{
worksheet.Cells[rowToAppend, 1].Value = reportData[i].BatchDate.Date.ToString("MM/dd/yyyy");
worksheet.Cells[rowToAppend, 2].Value = reportData[i].BatchId;
worksheet.Cells[rowToAppend, 3].Value = reportData[i].FileName;
worksheet.Cells[rowToAppend, 4].Value = reportData[i].PageCount;
worksheet.Cells[rowToAppend, 5].Value = reportData[i].MailDate;
}
//save the changes
excelPackage.Save();
}
}
}
In Excel, set the workbook to be shared. From the office help:
Open workbook in Excel
Click Review > Share Workbook
On the Editing tab, select the Allow changes by more than one user ... check box.
On the Advanced tab, select the options that you want to use for tracking and updating changes, and then click OK.
If this is a new workbook, type a name in the File name box. Or, if this is an existing workbook, click OK to save the workbook.
If the workbook contains links to other workbooks or documents, verify the links and update any links that are broken.
Click File > Save.
When you're done, - Shared will appear at the top of the Excel window, next to the filename.
The file will then be opened non-exclusively, allowing others to edit it while Excel has it open.
Related
I am using Office.Interop.Excel to read data from Excel using C# ASP.Net & Dotnet 6.
I can read the Data and everything seems to be working fine.
But I have a challenge here.
The excel which I am reading data from would be updated every second.
But I am seeing an error while trying to open it and update random data.
The error says that the file is locked for editing.
Please have a look at the code below:
public double GetGoldPrice()
{
string filename = #"D:\Test.xlsx";
int row = 1;
int column = 1;
Application excelApplication = new Application();
Workbook excelWorkBook = excelApplication.Workbooks.Open(filename);
string workbookName = excelWorkBook.Name;
int worksheetcount = excelWorkBook.Worksheets.Count;
if (worksheetcount > 0)
{
Worksheet worksheet = (Worksheet)excelWorkBook.Worksheets[1];
string firstworksheetname = worksheet.Name;
var data = ((Microsoft.Office.Interop.Excel.Range) worksheet.Cells[row, column]).Value;
excelApplication.Quit();
return data;
}
else
{
Console.WriteLine("No worksheets available");
excelApplication.Quit();
return 0;
}
}
My end goal is to get live data from Excel whenever I fire the function.
The Excel would be open and can be editing any time.
Please help!
You said your file is xlsx so you would be better not using Interop but Open XML SDK 2.5. Then you can open the file in read only mode:
using (SpreadsheetDocument spreadsheetDocument =
SpreadsheetDocument.Open(fileName, false))
{
// Code removed here.
}
Check here to get familiar with Open XML SDK
I am trying to get a form that was created in visual studio WPF C# to submit to a new excel workbook will save onto a shared network drive. I have done a bit of digging trying to find the best solution and I have came across NPOI but all of the solutions seem pretty complicated compared to what I need to do. Is there some easy resource that I can reference to simply create a workbook and insert data into specific cells -- then save?
The two related packages I have seen in NuGet are DotNetCore.NPOI and NPOI which is the one I should be using?
What I have tried so far is:
private void Button_Click(object sender, RoutedEventArgs e)
{
using (var fs = new FileStream("Result12345.xlsx", FileMode.Create, FileAccess.Write))
{
IWorkbook workbook = new XSSFWorkbook();
ISheet excelSheet = workbook.CreateSheet("Sheet1");
workbook.Write(fs);
MessageBox.Show("Form submitted successfully");
}
}
This gets outputted to : Project Folder \bin\Debug\net6.0-windows and it seems to create the workbook and save (assuming all I need to do is put in the path of the network drive in the file stream then that should be easy) but how do i insert data into cells specific cells?
I have worked with Microsoft Excel via interop COM libraries and should be directly available within your WPF app by adding as reference.
First, in the solution explorer, open the references, right-click and add reference.
Then, pick the Office libraries you are interested in working with, now or future, such as other apps too.
At the top of whatever code, you will then add the "using" clauses
using Microsoft.Office.Interop.Excel;
using System;
And here is a sample code snippet so you have control of whatever active workbook, worksheet, looping through explicit rows/columns and also getting the text of a given cell.
public void tryingExcel()
{
var SomeSampleFile = #"C:\Users\Public\SomeExcelFile.xlsx";
//Start Excel and get Application object.
var XL = new Microsoft.Office.Interop.Excel.Application();
XL.DisplayAlerts = false;
XL.Workbooks.Add();
// _Workbook and _Worksheet are part of Microsoft.Office.Interop.Excel
// via "using" clause at top of code
_Workbook wb = XL.ActiveWorkbook;
wb.Sheets.Add();
_Worksheet ws = wb.ActiveSheet;
ws.Cells[2, 1] = "Date/Time:";
ws.Cells[2, 2] = DateTime.Now;
for (var ir = 4; ir < 10; ir++)
ws.Cells[ir, 2] = "testing " + ir;;
for (var ir = 4; ir < 10; ir++)
ws.Cells[ir, 4] = ws.Cells[ir, 2].Text.Trim();
XL.ActiveWorkbook.SaveAs(SomeSampleFile, XlFileFormat.xlOpenXMLWorkbook,
Type.Missing, Type.Missing, false, false,
XlSaveAsAccessMode.xlNoChange,
XlSaveConflictResolution.xlLocalSessionChanges,
Type.Missing, Type.Missing, Type.Missing, false);
XL.Quit();
}
I have figured it out like this:
private void Button_Click(object sender, RoutedEventArgs e)
{
using (var fs = new FileStream(#"\\ipaddress\sharename\Result12345.xlsx", FileMode.Create, FileAccess.Write))
{
IWorkbook workbook = new XSSFWorkbook();
ISheet excelSheet = workbook.CreateSheet("Sheet1");
//define cell to insert into
var cellTest = excelSheet.CreateRow(0).CreateCell(0);
//set cell value
cellTest.SetCellValue("Hello?");
//save the excel sheet
workbook.Write(fs);
MessageBox.Show("Form submitted successfully");
}
}
I guess I just didn't understand why I have to create a row / cell when they already exist. Rather than setting something like Cell(0,1).value = "Something"
I have a folder on my PC containing multiple Excel spreadsheets that are all marked as read-only.
The folder is synced to my company's Sharepoint via OneDrive.
When I try to programmatically read data from one of these sheets via Microsoft.Office.Interop.Excel, I keep getting the You cannot use this command on a protected sheet error.
Here's the code I use to open the file:
public ExcelReader(String filePath)
{
this.filePath = filePath;
FileName = filePath.Substring(filePath.LastIndexOf("\\")+1);
app = new Excel.Application();
app.DisplayAlerts = false;
workbook = app.Workbooks.Open(filePath, false, true); //open in read only
}
public void openSheet(String sheet)
{
SheetName = sheet;
worksheet = workbook.Sheets[sheet];
Excel.Range last = worksheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
ColumnsTotal = last.Column;
RowsTotal = last.Row;
}
The line that throws the exception is Excel.Range last = worksheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing);.
I figured that since I explicitly tell the Workbook to open in Read-only mode, and since I never modify the content of these files, the fact that files are read-only shouldn't be a problem.
What am I doing wrong here? How do I read the content of these files without unprotecting them (I can't do that for security reasons)?
I created a code in c# which creates and saves excel file. The code can successfully create and save excel file, but when I open the excel file created, it displays a warning message telling:
The file format and extension of 'filename.xls' don't match. The file could be corrupted or unsafe. Unless you trust its source, don't open it. Do you want to open it anyway?
I am using the following code:
private void button1_Click(object sender, EventArgs e)
{
saveFileDialogSummary.Filter = "Excel Flie|*.xls";
saveFileDialogSummary.FilterIndex = 0;
saveFileDialogSummary.RestoreDirectory = true;
saveFileDialogSummary.CreatePrompt = true;
saveFileDialogSummary.Title = "Export Excel File To";
Excel.Application ExcelApp = new Excel.Application();
ExcelApp.Application.Workbooks.Add(Type.Missing);
ExcelApp.Columns.ColumnWidth = 30;
for (int i = 0; i < dataGridViewSummary.Rows.Count; i++)
{
DataGridViewRow row = dataGridViewSummary.Rows[i];
for (int j = 0; j < row.Cells.Count; j++)
{
ExcelApp.Cells[i + 1, j + 1] = row.Cells[j].ToString();
}
}
DialogResult res = saveFileDialogSummary.ShowDialog();
if(res == DialogResult.OK){
ExcelApp.ActiveWorkbook.SaveCopyAs(saveFileDialogSummary.FileName);
ExcelApp.ActiveWorkbook.Saved = true;
ExcelApp.Quit();
}
}
What should I do to avoid receiving that warning message?
I know this problem may be resolved by now, but just trying to help you without modifying the code can still use .xls format in your's and suppress this warning while opening the file by setting a registry.
Open reg edit, navigate to HKEY_CURRENT_USER\Software\Microsoft\Office\14\Excel\Security
Create a DWord with name ExtensionHardening and set the value to 0.
This might get your system vulnerable, but it is not a big deal when working in organisation network, at-least when you're sure of downloading the type of doc and source.
Just change the .xls to .xlsx if you have the latest office installed.
The file extension .xls and .xlsx file contain different-different layout. the extension .xls use in version 2003 whereas then version .xlsx extension to be used.
You must export excel file to .xlsx format. It will support in all version as i used.
Add below DLLS into bin folder
1. ClosedXML.dll
2. DocumentFormat.OpenXml.dll
Code to Export to .xlsx
DataTable dt = new DataTable();
//Create column and inser rows
using (XLWorkbook wb = new XLWorkbook())
{
var ws = wb.Worksheets.Add(dt, Sheetname);
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.Charset = "";
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=" + p_FileName + ".xlsx");
using (MemoryStream MyMemoryStream = new MemoryStream())
{
wb.SaveAs(MyMemoryStream);
MyMemoryStream.WriteTo(HttpContext.Current.Response.OutputStream);
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}
}
The solution for "file format and extension don't match" is to close the work book**($workbook->close;)** at last after all necessary writings done on to the file.
I faced the same issue while opening the "XLS" file from mail. I created a file and inserted all my stuff init and without closing the workbook I send the mail as an attachment. Later I realized that have to close the workbook and send as an attachment.
How can I find some value from cell and replace by new value in Excel?
I tryed this but it doesn't works:
Microsoft.Office.Interop.Excel.Application xlapp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook wb =default(Microsoft.Office.Interop.Excel.Workbook);
wb = xlapp.Workbooks.Open(FileName.ToString());
wb.Worksheets[0].Cells.Replace("find","replace");
I would recommend you use NPOI which can be accessed either via codeplex or directly through Nuget in Visual Studio. It gives you the ability to easily upload, edit and create spreadsheets in .NET
Example of uploading a spreadsheet:
HSSFWorkbook hssfworkbook;
void InitializeWorkbook(string path)
{
//read the template via FileStream, it is suggested to use FileAccess.Read to prevent file lock.
//book1.xls is an Excel-2007-generated file, so some new unknown BIFF records are added.
using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read))
{
hssfworkbook = new HSSFWorkbook(file);
}
}
You can then use the IRow and ICell collections of the spreadsheet to locate and edit the data you need before doing an export.
More examples can be found here
If interested, you can use GemBox.Spreadsheet for this, like so:
SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY");
// Load your XLS, XLSX, ODS or CSV file.
ExcelFile wb = ExcelFile.Load(FileName.ToString());
ExcelWorksheet ws = wb.Worksheets[0];
// Replace all "find" occurances with "replace" text.
int row, column;
while(ws.Cells.FindText("find", out row, out column))
ws.Cells[row, column].ReplaceText("find", "replace");
// Save your XLS, XLSX, ODS or CSV file.
wb.Save(FileName.ToString());
Also you can find another searching in Excel example here.
All you have to do is replace
wb.Worksheets[0].Cells.Replace("find","replace");
with
wb.Worksheets[1].Cells.Replace("find","replace");