Update already opened Excel workbook C# - c#

I have excel document that gets updated frequently from sensors and external data sources.
In C# i am opening the file and doing work with the data. What do i need to do to update my sheet variable without trying to reopen the file again.
void test(){
Application xlApp = new Application();
excelBook = xlApp.Workbooks.Open(filePath);
Worksheet sheet = excelBook.Worksheets[sheetName];
if (sheet != null){
var r = sheet.UsedRange.Value2;
while(true){
string json = JsonConvert.SerializeObject(r, Formatting.Indented);
//do work with the json data here
//........
//make sure we have latest updated sheet
//these are not working.
excelBook.RefreshAll();
excelBook.AutoUpdateSaveChanges = true;
}
}
}

Related

How can I export data to an Excel file with APP WinUI3?

I don't know how to export data from a ListView to Excel using a Winui3 APP tecnology.
With WPF I used "Excel = Microsoft.Office.Interop.Excel"
but in WinUI3 technology it doesn't work
Excel._Workbook MyExBook;
Excel.Workbooks MyExBooks;
Excel._Worksheet MyExSheet;
Excel.Sheets MyExSheets;
Excel.Range MyExRange;
ButExcel.IsEnabled = false;
try
{
MyExApp = new Excel.Application();
MyExBooks = MyExApp.Workbooks;
MyExBook = MyExBooks.Add();
MyExSheets = MyExBook.Worksheets;
MyExSheet = (Excel.Worksheet)MyExSheets[1];
}
catch
{
ButExcel.IsEnabled = true;
return;
}
There's no reason to use Excel itself to generate xlsx files. These files are ZIP packages containing well-defined XML files. There several libraries that can easily generate real Excel files, eg Epplus, ClosedXML, NPOI and many more.
These libraries offer several convenience methods that can load data from collections, DataTables or DataReaders directly. For example, using EPPlus, you can create an Excel file from a list of Products with :
var producs=new List<Product>();
//Load the list somehow
using (var p = new ExcelPackage())
{
var sheet = pck.Workbook.Worksheets.Add("sheet");
var range = sheet.Cells["C1"].LoadFromCollection(products);
p.SaveAs(new FileInfo(#"c:\workbooks\myworkbook.xlsx"));
}
You can load the data with headers, as a table, using one of the predefined styles too:
var tableRange = sheet.Cells["C1"].LoadFromCollection(products, true, TableStyles.Dark1);
// to get access to the created table:
var table = sheet.Tables.GetFromRange(tableRange);
ClosedXML allows writing similar code :
var wb = new XLWorkbook();
var ws = wb.Worksheets.Add("Inserting Data");
var rangeWithPeople = ws.Cell(7, 6).InsertData(people.AsEnumerable());
...
wb.SaveAs("InsertingData.xlsx");
To create a table you need to use InsertTable instead of InsertData:
var table= ws.Cell(7, 6).InsertTable(people.AsEnumerable(),"MyTable");
Both libraries also work with DataTable results

How to read data from Excel which is open and getting updated every seconds using C# ASP.NET?

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

C# cannot read from read-only Excel file

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

C#: Writing file to Excel issue

I am using ClosedXML to write my data into Excel. But here is the problem. When I write my data the old data gets removed and saves only data which I am calling. I know that is because of "new" and "Add" word I am using. Is there any other way I can specify to write files?
var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("Common");
worksheet.Cell(2, 1).Value = "Sent";
workbook.SaveAs(#"..\..\File.xlsx");
Try this: This should work
string pathfile = #"..\..\File.xlsx";
XLWorkbook workbook = new XLWorkbook(pathfile);
IXLWorksheet worksheet = workbook.Worksheet("Common");
worksheet.Cell(2, 1).Value = "Sent";
workbook.Save();
You may be able to instantiate
var workbook = new XLWorkbook()
in global scope and then append to it in whatever method you're using.

Convert xls or xlsx file with multiple sheets into one csv file using interop

I am trying to convert a xls or xlsx file with multiple sheets into one CSV file using c# and the interop library. I am only getting the one sheet in the CSV file. I know I can specify the sheet to save as or change the active sheet to save that one but I am looking for a solution to append all the sheets to the same CSV file that will work with both xls and xlsx files. I am automating this and don't care what is in the excel document just want to pull the string values out and append it to the csv file. Here is the code I am using:
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
app.Visible = false;
app.DisplayAlerts = false;
Workbook wkb = app.Workbooks.Open(fullFilePath);
wkb.SaveAs(newFileName, XlFileFormat.xlCSVWindows);
Is this even possible?
I'm just getting started tackling a similar situation, but I believe this may address your needs:
http://www.codeproject.com/Articles/246772/Convert-xlsx-xls-to-csv
This uses the ExcelDataReader api that you can get from NuGet
http://exceldatareader.codeplex.com/
Like Tim was saying, you're going to have to make sure and possibly validate that the columns and structure are the same between sheets. You may also have to eat the header rows on all the sheets after the first one. I'll post an update and some code samples once I've finished.
Update [7/15/2013]. Here's my finished code. Not very fancy, but it gets the job done. All of the sheets are tables in the DataSet, so you just loop through the tables adding onto your destination. I'm outputting to a MongoDB, but I'm guessing you can swap that out for a StreamWriter for your CSV file rather easily.
private static void ImportValueSetAttributeFile(string filePath)
{
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);
// Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
// DataSet - The result of each spreadsheet will be created in the result.Tables
DataSet result = excelReader.AsDataSet();
// Free resources (IExcelDataReader is IDisposable)
excelReader.Close();
var connectionString = ConfigurationManager.ConnectionStrings[0].ConnectionString;
var database = ConfigurationManager.AppSettings["database"];
var mongoAccess = new MongoDataAccess(connectionString, database);
var cdm = new BaseDataManager();
int ind = 0;
for (int i = 0; i < result.Tables.Count; i++)
{
int row_no = 1;
while (row_no < result.Tables[ind].Rows.Count) // ind is the index of table
// (sheet name) which you want to convert to csv
{
var currRow = result.Tables[ind].Rows[row_no];
var valueSetAttribute = new ValueSetAttribute()
{
CmsId = currRow[0].ToString(),
NqfNumber = currRow[1].ToString(),
ValueSetName = currRow[2].ToString(),
ValueSetOid = currRow[3].ToString(),
Definition = currRow[4].ToString(),
QdmCategory = currRow[5].ToString(),
Expansion = currRow[6].ToString(),
Code = currRow[7].ToString(),
Description = currRow[8].ToString(),
CodeSystem = currRow[9].ToString(),
CodeSystemOid = currRow[10].ToString(),
CodeSystemVersion = currRow[11].ToString()
};
cdm.AddRecords<ValueSetAttribute>(valueSetAttribute, "ValueSetAttributes");
row_no++;
}
ind++;
}
}

Categories