I would like to apply format on a specific range of cells of a pivot table containing values for a given data field. More specifically I want to create a border around the range of values.
This is possible in VBA with PivotTable.PivotSelect method which has a data field name as parameter and then we can apply format on this selection.
I have not found any solution yet in Aspose documentation for this.
I am aware of PivotTable.getDataBodyRange() Aspose method which returns the area of the data field values, but the thing is that I want to select only a specific data field.
You can format specific data area values in the Pivot Table via Aspose.Cells for Java. See the following example for your complete reference. I demonstrated to apply formatting via both ways (i.e., directly apply formatting and via pivot format conditions).
e.g.
Sample code:
//Instantiating a Workbook object
Workbook workbook = new Workbook();
//Obtaining the reference of the newly added worksheet
int sheetIndex = workbook.getWorksheets().add();
Worksheet sheet = workbook.getWorksheets().get(sheetIndex);
Cells cells = sheet.getCells();
//Setting the value to the cells
Cell cell = cells.get("A1");
cell.setValue("Sport");
cell = cells.get("B1");
cell.setValue("Quarter");
cell = cells.get("C1");
cell.setValue("Sales");
cell = cells.get("A2");
cell.setValue("Golf");
cell = cells.get("A3");
cell.setValue("Golf");
cell = cells.get("A4");
cell.setValue("Tennis");
cell = cells.get("A5");
cell.setValue("Tennis");
cell = cells.get("A6");
cell.setValue("Tennis");
cell = cells.get("A7");
cell.setValue("Tennis");
cell = cells.get("A8");
cell.setValue("Golf");
cell = cells.get("B2");
cell.setValue("Qtr3");
cell = cells.get("B3");
cell.setValue("Qtr4");
cell = cells.get("B4");
cell.setValue("Qtr3");
cell = cells.get("B5");
cell.setValue("Qtr4");
cell = cells.get("B6");
cell.setValue("Qtr3");
cell = cells.get("B7");
cell.setValue("Qtr4");
cell = cells.get("B8");
cell.setValue("Qtr3");
cell = cells.get("C2");
cell.setValue(1500);
cell = cells.get("C3");
cell.setValue(2000);
cell = cells.get("C4");
cell.setValue(600);
cell = cells.get("C5");
cell.setValue(1500);
cell = cells.get("C6");
cell.setValue(4070);
cell = cells.get("C7");
cell.setValue(5000);
cell = cells.get("C8");
cell.setValue(6430);
PivotTableCollection pivotTables = sheet.getPivotTables();
//Adding a PivotTable to the worksheet
int index = pivotTables.add("=A1:C8", "E3", "PivotTable2");
//Accessing the instance of the newly added PivotTable
PivotTable pivotTable = pivotTables.get(index);
//Unshowing grand totals for rows.
pivotTable.setRowGrand(false);
//Dragging the first field to the row area.
pivotTable.addFieldToArea(PivotFieldType.ROW, 0);
//Dragging the second field to the column area.
pivotTable.addFieldToArea(PivotFieldType.COLUMN, 1);
//Dragging the third field to the data area.
pivotTable.addFieldToArea(PivotFieldType.DATA, 2);
pivotTable.refreshData();
pivotTable.calculateData();
/*
//Apply formatting to specific data area values via Pivot format condition.
PivotFormatConditionCollection pfcc = pivotTable.getPivotFormatConditions();
int pIndex = pfcc.add();
PivotFormatCondition pfc = pfcc.get(pIndex);
FormatConditionCollection fcc = pfc.getFormatConditions();
CellArea dataBodyRange = pivotTable.getDataBodyRange();
fcc.addArea(dataBodyRange);
int idx = fcc.addCondition(FormatConditionType.CELL_VALUE);
FormatCondition fc = fcc.get(idx);
fc.setFormula1("6000");
fc.setOperator(OperatorType.GREATER_OR_EQUAL);
//fc.getStyle().setBackgroundColor(com.aspose.cells.Color.getRed());
fc.getStyle().setBorder(BorderType.LEFT_BORDER, CellBorderType.THICK, com.aspose.cells.Color.getRed());
fc.getStyle().setBorder(BorderType.TOP_BORDER, CellBorderType.THICK, com.aspose.cells.Color.getRed());
fc.getStyle().setBorder(BorderType.RIGHT_BORDER, CellBorderType.THICK, com.aspose.cells.Color.getRed());
fc.getStyle().setBorder(BorderType.BOTTOM_BORDER, CellBorderType.THICK, com.aspose.cells.Color.getRed());
*/
///*
//Apply formatting directly to specific data fields
CellArea dataArea = pivotTable.getDataBodyRange();
for(int dataRowNum = dataArea.StartRow; dataRowNum <= dataArea.EndRow;dataRowNum++){
for(int dataColNum = dataArea.StartColumn;dataColNum <= dataArea.EndColumn;dataColNum++){
cell = cells.get(dataRowNum,dataColNum);
int value = cell.getIntValue();
System.out.println(value);
if (value > 6000) {
Style style = cell.getStyle();
com.aspose.cells.Font font = style.getFont();
font.setColor(com.aspose.cells.Color.getBlue());
style.setBorder(BorderType.LEFT_BORDER, CellBorderType.THICK, com.aspose.cells.Color.getRed());
style.setBorder(BorderType.TOP_BORDER, CellBorderType.THICK, com.aspose.cells.Color.getRed());
style.setBorder(BorderType.RIGHT_BORDER, CellBorderType.THICK, com.aspose.cells.Color.getRed());
style.setBorder(BorderType.BOTTOM_BORDER, CellBorderType.THICK, com.aspose.cells.Color.getRed());
pivotTable.format(dataRowNum, dataColNum, style);
}
}
}
workbook.save("f:\\files\\out1.xlsx");
Should you have any confusion or further queries, you may also post your queries in respective forum.
PS. I am working as Support developer/ Evangelist at Aspose.
Related
I have a DataTable bound to a DataGridView. When I re-order the rows, the column index of the string I'm looking for gets messed up.
I get the index of the Serial Num column... this works, even after I've moved it.
Dim snIndex As Integer = asset_MasterDataGrid.Columns.[Single](Function(c) c.Header.ToString() = "Serial Num").DisplayIndex
Then I direct cast the row i'm clicking
Dim item As DataRowView = DirectCast(asset_MasterDataGrid.SelectedItem, DataRowView)
Then I grab the string of the cell in the Serial Num column.
Dim sn As String = item.Row(snIndex)
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/f4EqC.png
This of course doesn't work, and when I re-order my serial number column to lets say... index 0, it grabs the asset ID cell string. I'm trying to find the Serial number of whatever row I click on, no matter where the serial number column is.
Any ideas on how to correct this issue?
You can access a column of a DataRowView by its name rather than the index:
Dim item As DataRowView = DirectCast(asset_MasterDataGrid.SelectedItem, DataRowView)
Dim sn As String = item("Serial Num")
This should work provided that you know the name of the serial number column.
If you are clicking a datagrid header to reorder your selection, the linked data will not be reordered, the index will still be the same, the selected item will be what you select, but its index in the DataTable has not changed
to seach column index try this (C#)
var index = 0;
for (var i = 0, i < asset_MasterDataGrid.Columns.Count; i++)
if (((DataColumn)asset_MasterDataGrid).ColumnName == "Serial Num")
{
index = i;
break;
}
obvious this is your column with your serial.
Now to get your value with this serial number you need to seach in your DataGrid for it (not in your dataTable)
I have a datagridview (DGV) which contains some columns and a generic list which contains the focus information for all those columns available in the DGV. Now when I enter e cell in DGV, I want to get it's focus information from the list in a string variable. I am receiving the DGVs currentCell and fieldName (DGVs column name for which I want to load focus info) as input parameters. Below is my code:
private Rectangle GetFocusSettingsForField(string fieldName, DataGridViewCell currentCell)
{
NA27Bo bo = new NA27Bo();
Rectangle rectangle = new Rectangle();
string projectId = dgvEntryVerify["ProjectId", currentCell.RowIndex].Value.ToString();
string batchId = dgvEntryVerify["BatchId", currentCell.RowIndex].Value.ToString();
string imageId = dgvEntryVerify["ImageId", currentCell.RowIndex].Value.ToString();
string noOnImage = dgvEntryVerify["NumberOnImage", currentCell.RowIndex].Value.ToString();
int serialNo = Convert.ToInt32(dgvEntryVerify["SerialNumber", currentCell.RowIndex].Value.ToString());
PropertyInfo[] properties = bo.GetType().GetProperties();
string actualFieldName = "";
for (int i = 0; i < properties.Length; i++)
{
if (properties[i].Name.Contains(fieldName + "Focus"))
{
actualFieldName = properties[i].Name;
}
}
// Here I want to get the data from property "actualFieldName" of the list
//string value = data from property "actualFieldName" of the list
}
I am using VS2012, C#, Winforms but Framework 2.0 (framework can't be changed).
I've read all the similiar posts about this darn control (DataGridViewComboBoxCell) and setting it's value programmatically but implementing all the suggestions hasn't worked. I could probably change the UI to get around this problem but I don't like to be beat!
private void PopulateAreaForRoleAssociation()
{
// If businessRoleList is null then no data has been bound to the dgv so return
if (businessRoleList == null)
return;
// Ensure businessArea repository is instantiated
if (businessAreaRepository == null)
businessAreaRepository = new BusinessAreaRespository();
// Get a reference to the combobox column of the dgv
DataGridViewComboBoxColumn comboBoxBusinessAreaColumn = (DataGridViewComboBoxColumn)dgvBusinessRole.Columns["BusinessArea"];
// Set Datasource properties to fill combobox
comboBoxBusinessAreaColumn.DisplayMember = "Name";
comboBoxBusinessAreaColumn.ValueMember = "Id";
comboBoxBusinessAreaColumn.ValueType = typeof(Guid);
// Fill combobox with businessarea objects from list out of repository
comboBoxBusinessAreaColumn.DataSource = businessAreaRepository.GetAll();
// loop through the businessRoles list which the dgv is bound to and get out each dgv row based upon the current id in the loop
businessRoleList.Cast<BusinessRole>().ToList().ForEach(delegate(BusinessRole currentRole)
{
DataGridViewRow currentRowForRole = dgvBusinessRole.Rows.Cast<DataGridViewRow>().ToList().Find(row => ((BusinessRole)row.DataBoundItem).Id == currentRole.Id);
// Get a reference to the comboBox cell in the current row
DataGridViewComboBoxCell comboBoxCell = (DataGridViewComboBoxCell)currentRowForRole.Cells[2];
// Not sure if this is necessary since these properties should be inherited from the combobox column properties
comboBoxCell.DisplayMember = "Name";
comboBoxCell.ValueMember = "Id";
comboBoxCell.ValueType = typeof(Guid);
// Get the business area for the current business role
BusinessArea currentAreaForRole = businessAreaRepository.FetchByRoleId(currentRole.Id);
// if the role has an associated area then set the value of the cell to be the appropriate item in the combobox
// and update the cell value
if (currentAreaForRole != null)
{
foreach (BusinessArea area in comboBoxCell.Items)
{
if (currentAreaForRole.Id == area.Id)
{
comboBoxCell.Value = area.Id;
dgvBusinessRole.UpdateCellValue(2, comboBoxCell.RowIndex);
}
}
}
});
}
The dgv is first bound to a binding list holding BusinessRole objects, then the combobox column is bound to a basic list of BusinessArea objects that come out of a repository class. I then loop through the bindinglist and pull out the row of the dgv that is bound to the current item in the bindinglist loop.
With that row I make a database call to see if the BusinessRole entity is associated with a BusinessArea entity. If it is then I want to select the item in the combobox column that holds the BusinessAreas.
The problem is that when the grid is loaded, all the data is there and the comboboxes are populated with a list of available areas, however any values that are set are not displayed. The code that sets the value is definately getting hit and the value I am setting definately exists in the list.
There are no data errors, nothing. It's just refusing to update the UI with the value I programmatically set.
Any help would be greatly appreciated as always.
Thanks
This code works for my first combo box I have in my row with the following code, but I try it with the next one in the row and it doesn't work. I could use the help with the rest I have 3 more to do. I do set the combo boxes on a second form from this form with the same code as is on the last line of the try block but using the cell information instead of the dataset
try
{
string strQuery = "select fundCode from vwDefaultItems where IncomeType = '" + stIncome + "'";
SqlDataAdapter daDefault = new SqlDataAdapter(strQuery, conn);
DataSet dsDefault = new DataSet();
daDefault.Fill(dsDefault);
strDefFund = dsDefault.Tables[0].Rows[0].ItemArray[0].ToString();
dgvCheckEntry.Rows[curRow].Cells[7].Value = dsDefault.Tables[0].Rows[0].ItemArray[0].ToString();
}
catch (Exception eq)
{
}
I have problem related to datagridview in Winform.
I have a list of table names in my left panel. When I click on Table I show the table content in right panel. I am showing data in a datagridview by fetching data and assigning datasource to dgv.
I am setting following property to dgv.
dgTemp.Dock = DockStyle.Fill;
dgTemp.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dgTemp.AutoSize = true;
dgTemp.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
dgTemp.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
dgTemp.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
dgTemp.ReadOnly = true;
dgTemp.AutoGenerateColumns = true;
dgTemp.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dgTemp.AllowUserToAddRows = false;
My problem is there can be any number of columns in Datasource I am assigning to dgv. So if there are very few number of columns (say 1 or 2) the dgv size stands very small and the empty space on right side give very ugly look.
I can't use auto autosizecolumnmode to fill since when there is more columns all columns get shrink and expanding columns dont give me Scroll at bottom
so My requirement is
All space in datagridview should be filled. (should cover all area)
When there is more column, there should appear scroll, so it give better look
are there any events or properties which I can use ??
Thanks in anticipation.
Try this :
dgTemp.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
Update :
dataGridView1.FirstDisplayedScrollingRowIndex = 5; //use 5 because you want to start from 5
//you can have a horizontal scroll bar with this code :
dataGridView1.FirstDisplayedScrollingColumnIndex = 10; //you can choose every column you wanna start with that column
Update 2 :
int rows = dataGridView1.Rows.Count;
int columns = dataGridView1.Columns.Count;
if (rows < 5 && columns < 10)
{
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
}
else
{
dataGridView1.FirstDisplayedScrollingRowIndex = 5; //use 5 because you want to start from 5
//you can have a horizontal scroll bar with this code :
dataGridView1.FirstDisplayedScrollingColumnIndex = 10; //you can choose every column you wanna start with that column
}
I am trying edit the header cell value when using a grid view in virtual mode, but I can't get it working.
In my CellValueNeeded event I have the following code:
grvResults.Rows[e.RowIndex].HeaderCell.Value = record.RecordNumber;
Unfortunately, my header cells are still displaying blank.
How can I get the row header values to display? The end result is I need my rows to show what row number they are, to better keep track of data.
Update: The full event code is below:
private void grvResults_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
const int BATCH_REQUEST_SIZE = 50;
int row = e.RowIndex + 1;
LogRecord record = null;
// Check if this record for this row is cached
if (!_recordCache.ContainsKey(row))
{
// Retrieve the requested record + a batch more to speed up operations and lessen queries
int page = (row / BATCH_REQUEST_SIZE) + 1;
var records = _currentStore.GetFilteredRecords(_filters, _currentSessionId, BATCH_REQUEST_SIZE, page);
if (records.Count > 0)
{
// Add all the records to the cache
for (int x = 0; x < records.Count; x++)
if (!_recordCache.ContainsKey(row + x))
_recordCache.Add(row + x, records[x]);
}
}
// Get the record from the cache
record = _recordCache[row];
if (record != null)
{
// Set the header cell to the record number
grvResults.Rows[e.RowIndex].HeaderCell.Value = record.RecordNumber;
// Match the cell to the field
string cellFieldName = grvResults.Columns[e.ColumnIndex].Name;
if (record.Fields.Any(x => x.FieldName.Equals(cellFieldName, StringComparison.CurrentCultureIgnoreCase)))
e.Value = record.Fields.Where(x => x.FieldName.Equals(cellFieldName, StringComparison.CurrentCultureIgnoreCase)).Single().StringValue;
}
}
In the brief experiments I've done the HeaderCell.Value always shows in the row header, regardless of where it was set or whether the grid was in virtual mode.
One possibility is that the row header is too narrow to see the value.
Another is that RecordNumber is not a string - the Value displayed in the row header must be a string.
Same thing was happening to me, I noticed I was applying the header to the new row and then overwriting it with a row with values but with no header, so just try this:
grvResults.Rows[e.RowIndex-1].HeaderCell.Value = record.RecordNumber;
(rowindex -1)