I have a list that is filtered from SQL and an excel sheet that stocks them. In that list I have a column named A.
If that column exists, a comment should appear at the header of that column.
Its position might change, so I can't use this:
int commentIndex = worksheet.Comments.Add("F5");
Comment comment = worksheet.Comments[commentIndex];
comment.Note = "Hello Aspose!";
Here is my column
if (dt.Columns[i].ColumnName==A)
{
// code to be filled
}
dt=data table that has the columns from SQL.
Here is I did it and solved the issue:
int commentIndex = ws.Comments.Add(0, i);
Aspose.Cells.Comment comment = ws.Comments[commentIndex];
comment.Note = "Blalala";
Related
I have an excel file that contains the names of the columns in the first row.
How can I find the number of the last non-empty column in the first row?
I use the library ClosedXML.Excel;
Try this:
var workbook = new XLWorkbook(fileName);
int col = workbook.Worksheet(1)
.Row(1)
.LastCellUsed()
.Address
.ColumnNumber;
I'm using the snippet below to convert an Excel range with data into a table. In some cases, I need to delete the table, but preserve comments in the cells. Is there a way I can achieve that? Also, is there a way to toggle the headers on/off? I tried the different options under XlListObjectHasHeaders: Microsoft.Office.Interop.Excel.XlYesNoGuess. but those didn't work. thanks for your help.
finalRange.Worksheet.ListObjects.AddEx(
SourceType: Microsoft.Office.Interop.Excel.XlListObjectSourceType.xlSrcRange,
Source: finalRange,
XlListObjectHasHeaders: Microsoft.Office.Interop.Excel.XlYesNoGuess.xlYes);
I delete the table structure like this -
finalRange.Worksheet.ListObjects.Item[1].Delete();
EDIT (solution for multiple tables):
foreach (var table in sheet.ListObjects)
{
Microsoft.Office.Interop.Excel.ListObject tempObj = (Microsoft.Office.Interop.Excel.ListObject)table;
Microsoft.Office.Interop.Excel.Range tempRange = tempObj.Range;
tempRange.ClearContents();
}
These both presuppose your Table variable is lo:
Excel.ListObject lo = ws.ListObjects["Table1"];
To hide the header row in an Excel table:
lo.ShowHeaders = false;
To Remove the table but retain the comments, use the range.Clear method instead of the table.Delete.
Excel.Range tableRange = lo.Range;
tableRange.ClearContents();
I'm importing some excel sheet to a DataGridView. I need to import, reorder the column in my project and then get the new indexes.
I have tried DataGridViewColumn.Index, DataGridViewColumn.DisplayIndex, Refresh(), but the index never changes.
How I can do this, please?
Thanks.
DataGridView Column Index is created when column is created. If you want to change the order in a GUI you change the DisplayIndex if you want to change the order int the DataGridView you either create a new DataGridView or put the column in a temporary list, remove all columns and add them again.
If you want to change the actual index of an element in you Data Source, you need to update your Data Source structure. but if you need to change the display position of a column, you can is DisplayIndex property. This is a sample to change the column index:
var items = new List<dynamic>
{
new
{
Element1 = "Test Value",
Id = 1
},
new
{
Element1 = "Test Value",
Id = 1
}
};
dataGridView1.DataSource = items;
dataGridView1.Columns[1].DisplayIndex = 0;
MessageBox.Show(dataGridView1[0, 0].Value.ToString());
I have tried the below C# CODING:
wsDt.Cells["A10:G10"].AutoFilter = false;
but the filter is not removed from my excel.
Any other way to remove it.
Thanks...
In Excel, when you use the Format as Table option it will not only style the data but will also create a Named Range - Table1. This option also automatically enables the Filter Buttons. After formatting as a table, you can uncheck Filter Buttons in the Table Tools -> Table Styles Options.
What works for me is doing the same programmatically.
LoadFromDataTable(DataTable, bool, TableStyles) basically
pastes data to the worksheet starting at the ExcelRange
applies a Table Format
uses the DataTable.TableName to name the range
enables Filter Button
Disable the Filter Button
use the DataTable.TableName to reference the named range
set ShowFilter to false
enter code here
//imagine a table with 5 columns
DataTable dt = new DataTable();
dt.TableName = "UniqueTableName";
//define the cells where the headers will appear
int topRow = 1;
int leftMostColumn = 1;
int rightMostColumn = 5;
//bind the DataTable using LoadFromDataTable()
OfficeOpenXml.ExcelRange excelRange = worksheet.Cells[topRow, leftMostColumn, topRow, rightMostColumn];
excelRange.LoadFromDataTable(dt, true, OfficeOpenXml.Table.TableStyles.Light8);
//turn of the filtering
OfficeOpenXml.Table.ExcelTable table = worksheet.Tables[dt.TableName];
table.ShowFilter = false;
This seems to be an EPPlus bug and I don't think it has been resolved as of the latest release (4.04), at least I could figure out a solution. My workaround is to simply load the spreadsheet values a row at a time with a loop:
int sheetRow = 3;
for (int outer = 0; outer < outerSourceTable.Rows.Count; outer++)
{
var outerThingId = Convert.ToInt32(outerSourceTable.Rows[outer]["OuterThingId"]);
var outerThingName = Convert.ToString(outerSourceTable.Rows[outer]["OuterThing"]);
var innerThingsTable = _repository.GetInnerThings(outerThingId);
if (innerThingsTable.Rows.Count > 0)
{
myWorksheet.Cells[sheetRow, 1].Value = outerThingName;
// Load the data into the worksheet. We need to load a row at a time
// to avoid the auto-filter bug
for (int inner = 0; inner < innerThingsTable.Rows.Count; inner++)
{
var innerName = Convert.ToString(innerThingsTable.Rows[inner]["Name"]);
var innerDescr = Convert.ToString(innerThingsTable.Rows[inner]["Description"]);
myWorksheet.Cells[sheetRow, 2].Value = innerName;
myWorksheet.Cells[sheetRow, 3].Value = innerDescr;
sheetRow++;
}
sheetRow++;
}
}
If you populate your excel data using the LoadFromCollection() call. You can then reference it using the default Excel table name of "Table 1".
This is the same idea as Patricks answer but demonstrates the use without DataTable.
excelWorksheet.Cells.LoadFromCollection(myCollection);
ExcelTable table = excelWorksheet.Tables["Table1"];
table.ShowFilter = false;
Sometimes excel creates the Table as a named range. In my instance the Table was the only thing in the first worksheet, so the following helped me:
var ws = wb.Worksheets.First();
ws.NamedRanges.FirstOrDefault()?.Ranges.FirstOrDefault()?.SetAutoFilter(false);
It's a simple question but after searching a lot I didn't find a solution for it. I want to get ColumnName of a DataGridView by column tag. I had put tags on each column with column name.
EDIT:
Also I store a decimal value in tag.
This is my code:
DataGridViewColumn dgCol = new DataGridViewColumn();
dgCol.Name = "MyCol";
dgCol.Tag = 10;
DataGridView1.Columns.Add(dgCol );
While tag is of type Object. Now I want to set value of cell but I had column tag not the name neither I know column index.
DataGridView1.Rows[1].Cells[" _**Dont Have ColumnName**_ "].Value = 100;
But I had column tag. So is there any way from which I got column name from column tag?
You can iterate through all columns:
DataGridViewColumn getcol;
foreach(DataGridViewColumn c in DataGridView1.Columns)
{
if(c.Tag as String == "10")
{
getcol = c;
}
}
Now you can use this getcol.
DataGridView1.Rows[1].Cells[getcol.Name].Value = 100;
this is an improvement to my previous answer
You can use linq also and it is shorter and neat.
var col = dataGridView1.Columns.Cast<DataGridViewColumn>().Where(c => c.Tag == "10").Single();
dataGridView1.Rows[1].Cells[col.Name].Value = "100";
Try this out:
you can get columns name by following ways.
Suppose i have two columns: col1 and col2
1. Directly using the column object
dataGridView1.Rows[0].Cells[col1.Name].Value = "100";
2. or by directly columns index
dataGridView1.Rows[0].Cells[dataGridView1.Columns[0].Name].Value = "100";
Hope this helps