How to add table heading drop-down with Apache Poi - java

I'm generating Excel tables with Apache POI, but my generated tables lack the drop-down menu on each header that appear when I "format as table" in Excel itself.
I'd like to generate this:
But instead I get this:
I'm following this blog post, and my code looks like this:
XSSFTable table = sheet.createTable();
table.setDisplayName("Data");
CTTable ctTable = table.getCTTable();
ctTable.setDisplayName("Data");
ctTable.setId(1L);
ctTable.setName("DATA");
CTTableStyleInfo table_style = ctTable.addNewTableStyleInfo();
table_style.setName("TableStyleMedium9");
table_style.setShowColumnStripes(false);
table_style.setShowRowStripes(true);
Each column is then created like this:
CTTableColumn column = ctColumns.addNewTableColumn();
column.setName(headers.get(i));
column.setId(i + 1);
What am I missing?

Thanks to Alan Hay for the clue - the solution is to add an auto-filter, but this needs to be added as a CTAutoFilter for each individual column of the CTTable. The working solution looks like this:
CTTableColumns ctColumns = ctTable.addNewTableColumns();
CTAutoFilter autofilter = ctTable.addNewAutoFilter();
ctColumns.setCount(table_headers.size());
for(int i = 0; i < table_headers.size(); i++) {
CTTableColumn column = ctColumns.addNewTableColumn();
column.setName(table_headers.get(i));
column.setId(i + 1);
CTFilterColumn filter = autofilter.addNewFilterColumn();
filter.setColId(i + 1);
filter.setShowButton(true);
}
When auto-sizing columns, it's also necessary to add extra width for the drop down menu:
for(int i = 0; i < table_headers.size(); i++) {
sheet.autoSizeColumn(i);
// Include width of drop down button
sheet.setColumnWidth(i, sheet.getColumnWidth(i) + 1000);
}

It is not exactly clear from the example you quoted whether applying the Table styling should create the filter dropdowns for you or not.
However you can explicitly call setAutoFilter() as below to have the filter dropdowns set.
e.g.
CellReference start = table.getStartCellReference();
CellReference end= table.getEndCellReference();
sheet.setAutoFilter(new CellRangeAddress(...);

Related

Select specific range/scope of a pivot table to apply format on (Aspose.Cells for Java)

Is there an equivalent of this VBA function PivotTable.PivotSelect in Aspose.Cells product ?
I am looking for a way to create a border on a whole selection of cells containing specific data field values, or on a specific scope as you prefer.
The VBA macro to perform this action is the following, by giving only the data field name parameter :
v_wbx.Sheets(v_SheetName).**PivotTables(v_CurrentPivotName).PivotSelect **DataFieldName**, xlDataAndLabel, True**
Selection.Borders(xlDiagonalDown).LineStyle = xlNone
Selection.Borders(xlDiagonalUp).LineStyle = xlNone
With Selection.Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.Color = v_Color
.TintAndShade = 0
.Weight = v_Weight
End With
With Selection.Borders(xlEdgeTop)
.LineStyle = xlContinuous
.Color = v_Color
.TintAndShade = 0
.Weight = v_Weight
End With
With Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.Color = v_Color
.TintAndShade = 0
.Weight = v_Weight
End With
With Selection.Borders(xlEdgeRight)
.LineStyle = xlContinuous
.Color = v_Color
.TintAndShade = 0
.Weight = v_Weight
End With
Is this covered by Aspose.Cells ? I looked into documentation but haven't found any solution.
I'm aware that the "scope" selection is available with the Aspose conditional formatting, but here I want to create the border around the WHOLE selection of cells by specifying the data field name, and NOT use any Conditional Format rule.
This is done via VBA using this enum : https://learn.microsoft.com/en-us/office/vba/api/excel.xlptselectionmode and the function mentioned before.
I precise I'm using the trial version of the product to evaluate the range of features.
Please share your positive or negative feedback on this topic, thank you
You can format specific data area values in the Pivot Table via Aspose.Cells for Java. See the following example for your reference. You can apply formatting via both ways (i.e., use directly apply formatting and via pivot format condition).
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");
You may also post your queries in the dedicated forum.
PS. I am working as Support developer/ Evangelist at Aspose.

Convert text to a Hyperlink using CSV writer in java

I have a java class using csv writer which creates csv file.As know everything will be in text format,I want a specific column data to be a hyperlink.For example consider a table with 1 rows and 4 columns
OUTPUT is : when opened in excel .Each entry will be in a new cell
Col1 Col2 Col3 Col4
OUTPUT when opened in Open Office
Col1,Col2,Col3,Col4
The above data is when I open my csv file in excel.This creation is done by my csv writer in java.
What I wanted here is that Col3 should be a hyperlink
Below is my code
public String[] convertEntry(Info ItemInfo) {
String[] columns = new String[NUMBER_OF_COLUMNS];
columns[1] = "Col1;
columns[2] = "Col2";
columns[3] = "Col3";
columns[4] = "Col4";
return columns;
}
Hope am clear.Any help is appreciated
It's ugly but:
this,is,a,=HYPERLINK("http://www.google.com"),test,csv
Will automatically create it. Otherwise you can turn on the configuration for autocompletion in Excel so they always change. But CSV is supposed to be text, I would suggest leaving it as just the URL and having the user know what they are doing to change it.
EDIT:
public String[] convertEntry(Info ItemInfo) {
String[] columns = new String[NUMBER_OF_COLUMNS];
columns[1] = "Col1;
columns[2] = "Col2";
columns[3] = "=HYPERLINK(" + ItemInfo.Col3 + ")";
columns[4] = "Col4";
return columns;
}
Just wrap the value in the =HYPERLINK() function and it will automatically be a link in excel.

How to set Multiple default value in Apache POI pivot table report filter

I need some help, I'm working on a project where I need to create a pivot table with report filter. Now I want to set Multiple default value to the report filter. I've gone through this previously posted question Click here!
I couldn't find anything online related this. Thanks in advance.
There has not much changed at creating pivot tables using apache poi since my last answer. So my code in the linked Q/A in your question only can extended a little bit for fulfilling the requirement selecting multiple items as default in page filter. A code which would be general able creating pivot tables from all kind of data, as Excel can do, is further on not possible.
If the need is selecting multiple items, first MultipleItemSelectionAllowed needs to be set in appropriate pivot field.
Then for each item which not shall be selected H(idden) needs set true.
Example:
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.ss.SpreadsheetVersion;
import java.util.Random;
import java.io.*;
class PivotTableTest4 {
private static void setCellData(Sheet sheet) {
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("Name");
cell = row.createCell(1);
cell.setCellValue("Value1");
cell = row.createCell(2);
cell.setCellValue("Value2");
cell = row.createCell(3);
cell.setCellValue("City");
for (int r = 1; r < 15; r++) {
row = sheet.createRow(r);
cell = row.createCell(0);
cell.setCellValue("Name " + ((r-1) % 5 + 1));
cell = row.createCell(1);
cell.setCellValue(r * new java.util.Random().nextDouble());
cell = row.createCell(2);
cell.setCellValue(r * new java.util.Random().nextDouble());
cell = row.createCell(3);
cell.setCellValue("City " + ((r-1) % 4 + 1));
}
}
public static void main(String[] args) {
try {
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet();
//Create some data to build the pivot table on
setCellData(sheet);
XSSFPivotTable pivotTable = sheet.createPivotTable(
new AreaReference(new CellReference("A1"), new CellReference("D15"), SpreadsheetVersion.EXCEL2007), new CellReference("H5"));
//Configure the pivot table
//Use first column as row label
pivotTable.addRowLabel(0);
//Sum up the second column
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1);
//Avarage the third column
pivotTable.addColumnLabel(DataConsolidateFunction.AVERAGE, 2);
//Add fourth column as page filter
pivotTable.addReportFilter(3);
/*
Apache poi adds 15 pivot field items of type "default" (<item t="default"/>) here.
This is because there are 15 rows (A1:D15) and, because they don't have a look at the data,
they are assuming max 15 different values. This is fine because Excel will rebuild its pivot cache while opening.
But if we want preselect items, then this is not fine. Then we must know what items there are that can be preselected.
So we need at least as much items as we want preselecting as numbered items: <item x="0"/><item x="1"/><item x="2"/>...
And we must build a cache definition which has shared elements for those items.
*/
for (int i = 0; i < 4; i++) {
//take the first 4 items as numbered items: <item x="0"/><item x="1"/><item x="2"/><item x="3"/>
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(3).getItems().getItemArray(i).unsetT();
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(3).getItems().getItemArray(i).setX((long)i);
//build a cache definition which has shared elements for those items
//<sharedItems><s v="City 1"/><s v="City 2"/><s v="City 3"/><s v="City 4"/></sharedItems>
pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(3).getSharedItems().addNewS().setV("City " + (i+1));
}
//Now we can predefinite a page filter. Second item, which is "City 2", in this case.
//pivotTable.getCTPivotTableDefinition().getPageFields().getPageFieldArray(0).setItem(1);
//If the need is selecting multiple items, first MultipleItemSelectionAllowed needs to be set.
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(3).setMultipleItemSelectionAllowed(true);
//Then set H(idden) true for all items which not shall be selected. First ("City 1") and fourth ("City 4") in this case.
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(3).getItems().getItemArray(0).setH(true);
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(3).getItems().getItemArray(3).setH(true);
FileOutputStream fileOut = new FileOutputStream("PivotTableTest4.xlsx");
wb.write(fileOut);
fileOut.close();
wb.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
This needs the full jar of all of the schemas, ooxml-schemas-1.3.jar, as mentioned in the FAQ.

Apache POI - Excel Get value by given ranges

User will insert ranges value for example A1:A3 to retrieve the data. How i can get the value based on the given ranges using Apache POI?
or is there any library that i can use?
Below is the solution that i got. Using AreaReference function.
AreaReference aref = new AreaReference(sheet.getSheetName() + "!A3:A9", SpreadsheetVersion.EXCEL2007);
CellReference[] crefs = aref.getAllReferencedCells();
for (int i=0; i<crefs.length; i++) {
XSSFSheet s = workbook.getSheet(crefs[i].getSheetName());
Row r = s.getRow(crefs[i].getRow());
Cell c = r.getCell(crefs[i].getCol());
}
import org.apache.poi.ss.util.SheetUtil
final Cell cell= SheetUtil.getCellWithMerges(sheet, 5, 2);
visit http://poi.apache.org/apidocs/4.1/org/apache/poi/ss/util/SheetUtil.html

Apache POI : Update cells in a named range

I am using Apache POI library to read/write to xlsx. In my original xlsx, I have a namedrange "XYZ".
I want to update the values of cells within this name range. How can I do that?
I did this:
XSSFName name = workbook.getName("XYZ");
String formula = name.getRefersToFormula();
System.out.println("Formula = " + formula);
Now, I dont know how to get a handle to individual cell in this named range.
Can anyone please point me to the correct API that I can use?
Rgds
Sapan
There is an example from the Busy Developers' Guide for retrieving the cells in the range. Then you can use Cell.setCellValue() to update.
// setup code
String cname = "TestName";
Workbook wb = getMyWorkbook(); // retrieve workbook
// retrieve the named range
int namedCellIdx = wb.getNameIndex(cname);
Name aNamedCell = wb.getNameAt(namedCellIdx);
// retrieve the cell at the named range and test its contents
AreaReference aref = new AreaReference(aNamedCell.getRefersToFormula());
CellReference[] crefs = aref.getAllReferencedCells();
for (int i=0; i<crefs.length; i++) {
Sheet s = wb.getSheet(crefs[i].getSheetName());
Row r = s.getRow(crefs[i].getRow());
Cell c = r.getCell(crefs[i].getCol());
// extract the cell contents based on cell type etc.
}

Categories