Accessing row cell count in Excel Spreadsheet - c#

I need to know how to get the count of cells in a Row object using OpenXML. Currently, I am using
row.Descendants<Cell>().Count<Cell>()
but this is not correct at all. Any ideas what method/property gives me the count of cells?

You can get the count using one of the followings:
row.Descendants<Cell>().Count<Cell>() //The one you used
row.Elements<Cell>().Count<Cell>()
row.Count()
I tested all of them and they are working correctly. Keep in mind the following points while validating the correctness of the returned count:
- Hidden columns are included in the calculations
- Merged cells are counted separately. If your excel sheet contains 3 columns A, B & C, but A & B are merged, then the count of the cells is 3 not 2
You can extract a list of all the merged cells in a sheet using:
SpreadsheetDocument ExcelSpreadSheet = SpreadsheetDocument.Open(ReportFile, true);
WorksheetPart ExcelWSP = GetWorksheetPartByName(ExcelSpreadSheet, TemplateEntity.ExcelSheetName);
MergeCells mergeList = ExcelWSP.Worksheet.Elements<MergeCells>().First();
The merge information is saved in the Reference property, and you can access it using the following:
((MergeCell)mergeList.ElementAt(i)).Reference

Related

I'm using the EEPlus Excel Spreadsheet Library in a C# project. How do I address a range of rows?

I would like to be able to perform actions on a range of rows in a column. Say the column is column A. I just want to do something to Row A2 to the bottom. How do I refer to this in my code?
ExcelPackage excelPackage = new ExcelPackage();
var sheet = excelPackage.Workbook.Worksheets.Add("This sheet is bullsheet");
sheet.Cells["A2:A20"].Value = 0;
sets the value of the column to 0 from A2 to A20.
But what if I want to set all the values in the column all the way to the end (however far it goes) to 0?
Or what if I want to include DataValidations for all the cells except the header?

EPPlus C# Export data to Excel. Table data overwrites Namebox instead of "Insert" and preserving other cells

I am using EPPlus C# library to generate Excel file. An Excel template is to be filled with SQL Server data that is coming in a DataTable. Template file uses NameBoxes, the data is filled within those nameboxes.
The issue is that for eg. I have namebox at position A1
and another namebox at position B1
when A1 is filled with a single row data.. it is fine. But if data in A1 has multple rows it overwrites A2 namebox (namebox at A2 is gone).
The namebox at A2 should be shifted down to A6.
(Same behaviour we see when doing "Insert" in a cell that shifts other cells ahead instead of overwriting them).
And what about the Insert method from Rows collection?
// Insert row at the 4the position.
worksheet.Rows.Insert(3);
I solved it by inserting new rows using the following logic:
// Get current cell's address
string oldAddress = nameBox.Start.Address;
// insert new rows in worksheet to preserve other nameboxes
nameBox.Worksheet.InsertRow(nameBox.Start.Row, dt.Rows.Count);
// move to old address
nameBox.Address = oldAddress;
// Fill Name box with Datatable
nameBox.LoadFromDataTable(dt, printHeaders);

Merging excel cells based on the cell value using c#

I am using excel with c# I want to merge all adjacent cells that contain a specific value using c# code.
I want to merge all the cells that contains the value (Merged cells) using c# code
i want it to be like this
First, you need to identify the cells where the range of repetitive value starts and where it ends.
Then, use this code to merge the cells:
String startRange = "A1";
String endRange = "D3";
String repetitiveValue = "Merged Cells";
Microsoft.Office.Interop.Excel.Range range = worksheet.Range[startRange, endRange];
range.Value2 = repetitiveValue;
range.Select();
range.Merge(Missing.Value);
You need to use one or the other Office library, which can help you with reading/writing spreadsheets & also with the cell merges.
Check SpreadSheetGear.net or PowerTools for OpenXml (for >= office 2007 formats)
http://ericwhite.com/blog/powertools-for-open-xml-expanded/

Excel charts with #N/A values

I have written a C# program that does a lot of iterative calculations and then returns a huge list of data. Because the data changes each time I run the program, I draw it in an Excel spreadsheet with predefined functions and graphs that are useful to interpret the data. However, all my charts in the spreadsheet depend on a single column of data, through with other columns and axis are calculated using formulas. However, the total amount of data is not always constant.
For instance, sometimes I get 22 elements of data in the list, and sometimes the number flows into 100s. To have a stable bound, I cap the charts to graph only the first 50 rows of data, and in my program, I fill the remaining columns with the value "#N/A". However, when I open the spreadsheet, the rows with superfluous data is graphed as 0s. I want the charts to graph only the rows with valid data.
Here is what my code looks like, it is relatively very simple, so I am not going to modify this, I want to know what changes I can make in the spreadsheet.
FileInfo newFile = new FileInfo("Report.xlsx");
ExcelPackage pack = new ExcelPackage(newFile);
ExcelWorksheet ws = pack.Workbook.Worksheets[1];
int cellCount = 2;
for(int i = 0; i < 49; i++)
{
String cell = "B" + cellCount;
if (i < data.Count)
ws.Cells[cell].Value = data.ElementAt(i);
else
ws.Cells[cell].Value = "#N/A";
cellCount++;
}
Console.Out.WriteLine("saving");
pack.Save();
System.Diagnostics.Process.Start("Report.xlsx");
To access the Excel documents, I use EPPLUS. Here is what my charts look like:
As the graph shows, the last 5-6 rows contain NULL values, however, they are graphed as well, with values of 0. The blue line represents the data in the third column, and red line represents the last column (that is never going to be null because it's dependant on a fixed row).
How do I force Excel to ignore the last few NULL rows?

Interop - Setting a range for an Excel chart to an entire row

How do I set the source data of an excel interop chart to several entire rows?
I have a .csv file that is created by my program to display some results that are produced. For the sake of simplicity let's say these results and chart are displayed like this: (which is exactly how I want it to be)
Now the problem I am having is that the number of people is variable. So I really need to access the entire rows data.
Right now, I am doing this:
var range = worksheet.get_range("A1","D3");
xlExcel.ActiveChart.SetSourceData(range);
and this works great if you only have three Persons, but I need to access the entire row of data.
So to restate my question, how can I set the source data of my chart to several entire rows?
I tried looking here but couldn't seem to make that work with rows instead of columns.
var range = worksheet.get_range("A1").CurrentRegion;
xlExcel.ActiveChart.SetSourceData(range);
EDIT: I am assuming that the cells in the data region won't be blank.
To test this,
1) place cursor on cell A1
2) press F5
3) click on "Special"
4) choose "Current Region" as option
5) click "OK"
This will select the cells surrounding A1 which are filled, which I believe is what you are looking for.
The translation of that in VBA code points to CurrentRegion property. I think, that should work.
Check Out the option Range.EntireRow I'm not 100% on how to expand that to a single range containing 3 entire rows, but it shouldn't be that difficult to accomplish.
Another thing you can do is scan to get the actual maximum column index you need (this is assuming that there are guaranteed to be no gaps in the names), then use that index as you declare your range.
Add Code
int c = 2;//column b
while(true)
{
if (String.IsNullOrEmpty(worksheet.GetRange(1,c).Value2))
{
c--;
break;
}
c++;
}
Take a column from A to D that you're sure has no empty cells.
Do some loop to find the first empty one in that column and it will be one after the last.
Range Cell = SHeet.Range["A1"]; //or another column you're sure there's no empty data
int LineOffset = 0;
while (Cell.Offset[LineOffset, 0].Value != "") //maybe you should cast the left side to string, not sure.
{
LineOffset++;
}
int LastLine = LineOffset - 1;
Then you can get Range[Sheet.Cells[1,1], Sheet.Cells[LastLine, 4]]
Out of the box here, but why not transpose the data? Three columns for Name, Height, Weight. Convert this from an ordinary range to a Table.
When any formula, including a chart's SERIES formula references a column of a table, it always references that column, no matter how long the table gets. Add another person (another row) and the chart displays the data with the added person. Remove a few people, and the chart adjusts without leaving blanks at the end.
This is illustrated in my tutorial, Easy Dynamic Charts Using Lists or Tables.

Categories

Resources