XSSF (POI) - 更改枢轴上的字体 table
XSSF (POI) - Changing the font on a pivot table
我正在使用 Apache POI 3.12:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.12</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.12</version>
</dependency>
如何更改枢轴内的字体 table?
在将一个单元格 (I7) 的字体更改为 8pt 大小后检查生成的 .xlsx 显示以下更改:
styles.xml,作为第二个条目的标签内:
<font>
<sz val="8"/>
<color indexed="8"/>
<name val="Calibri"/>
<family val="2"/>
<scheme val="minor"/>
</font>
within the <cellXfs> tag as the 5th entry:
<xf numFmtId="0" fontId="1" fillId="0" borderId="0" xfId="0" applyNumberFormat="1" applyFont="1"/>
New tag: dxfs:
<dxfs count="1">
<dxf>
<font>
<sz val="8"/>
</font>
</dxf>
</dxfs>
pivottable.xml
<formats count="1">
<format dxfId="0">
<pivotArea collapsedLevelsAreSubtotals="1" fieldPosition="0">
<references count="2">
<reference field="4294967294" count="1" selected="0">
<x v="0"/>
</reference>
<reference field="0" count="1">
<x v="0"/>
</reference>
</references>
</pivotArea>
</format>
</formats>
sheet1.xml
<c r="I7" s="4">
注意:我可能会将此作为自我回答关闭,因为我仍在尝试自己解决它。但是,我已经在这里待了将近一个星期。
POI Pivot table sample
这是一个部分答案,因为它需要使用 excel 来设置而不是纯 poi。
一般步骤:
- 在 excel 中创建一个包含枢轴 table 的电子表格,或者使用 sample 作为 poi。
- 打开 excel 中的电子表格并保存。
- 在 poi 中打开电子表格。
- 创建 CTDxfs 条目。这是 "font" table 秒。
- 使用 CTDXfs id 创建一个 pivotArea 定义。
关于代码:
private static CTFormats getFormats(XSSFPivotTable pivotTable) {
CTFormats formats = pivotTable.getCTPivotTableDefinition().getFormats();
if(formats==null)
formats=pivotTable.getCTPivotTableDefinition().addNewFormats();
return formats;
}
private static int createDXFs(XSSFWorkbook wb,int font) {
CTDxfs dxfs=wb.getStylesSource().getCTStylesheet().getDxfs();
if(dxfs==null)
dxfs=wb.getStylesSource().getCTStylesheet().addNewDxfs();
dxfs.setCount(dxfs.getCount()+1);
CTDxf dxf=dxfs.addNewDxf();
CTFontSize fontSize=dxf.addNewFont().addNewSz();
fontSize.setVal(font);
return (int) dxfs.getCount()-1;
}
public static void setAxisFont(CTFormats pivotTableFormats,int dxfId) {
CTFormat format=pivotTableFormats.addNewFormat();
format.setDxfId(dxfId);
CTPivotArea pivotArea = format.addNewPivotArea();
pivotArea.setDataOnly(false);
pivotArea.setLabelOnly(true);
pivotArea.setOutline(false);
pivotArea.setFieldPosition(0L);
pivotArea.setAxis(STAxis.AXIS_ROW);
pivotArea.setType(STPivotAreaType.BUTTON);
}
public static void setColHeaderFont(CTFormats pivotTableFormats,int dxfId,int colInd) {
CTFormat format=pivotTableFormats.addNewFormat();
format.setDxfId(dxfId);
CTPivotArea pivotArea = format.addNewPivotArea();
pivotArea.setDataOnly(false);
pivotArea.setLabelOnly(true);
pivotArea.setOutline(false);
CTPivotAreaReferences references = pivotArea.addNewReferences();
CTPivotAreaReference reference = references.addNewReference();
reference.setField(new Long(Integer.MAX_VALUE)*2);
CTIndex x = reference.addNewX();
x.setV(colInd); //Column
}
public static void setLabelFont(CTFormats pivotTableFormats,int dxfId, int rowInd) {
CTFormat format=pivotTableFormats.addNewFormat();
format.setDxfId(dxfId);
CTPivotArea pivotArea = format.addNewPivotArea();
pivotArea.setDataOnly(false);
pivotArea.setLabelOnly(true);
pivotArea.setFieldPosition(0L);
CTPivotAreaReferences references = pivotArea.addNewReferences();
CTPivotAreaReference reference = references.addNewReference();
reference.setField(0L);
CTIndex x = reference.addNewX();
x.setV(rowInd); //Row
}
public static void setDataElementFont(CTFormats pivotTableFormats,int dxfId,int col,int row) {
CTFormat format=pivotTableFormats.addNewFormat();
format.setDxfId(dxfId);
CTPivotArea pivotArea = format.addNewPivotArea();
//Default values, don't need to explicitly define.
//pivotArea.setDataOnly(true);
//pivotArea.setLabelOnly(false);
CTPivotAreaReferences references = pivotArea.addNewReferences();
CTPivotAreaReference reference = references.addNewReference();
reference.setField(new Long(Integer.MAX_VALUE)*2);
CTIndex x = reference.addNewX();
x.setV(col); //Column
reference = references.addNewReference();
reference.setField(0L);
x = reference.addNewX();
x.setV(row); //Row
}
备注:
- setOutline(false) 需要访问列 headers.
- setDataOnly(false) 允许更改影响标签和数据。
- setLabelOnly(true) 限制仅更改标签值。如果你想改变整个column/row,设置为false。
- unsigned int max 的引用字段值将引用定义为列,另一个有效值为 0,将引用定义为行。
- 如果 col/row 引用未定义,例如 setColHeaderFont/setLabel 字体,它会影响整个 column/row。这对于格式化特定列可能是可取的。
警告 maven 用于 poi 3.12 的 poi-ooxml-schemas 不包括 CTFormats。这可以通过排除它并包括 1.1 版本来覆盖:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.1</version>
</dependency>
这是一个完整的答案,但比之前使用 excel 的答案复杂得多。
一般步骤:
- 在 excel 中创建一个包含枢轴 table 的电子表格,或使用 sample 作为 poi。
- 创建数据透视缓存定义。
- 创建 CTDxfs 条目。这是 "font" for tables。 (查看其他答案)
- 使用 CTDXfs id 创建一个 pivotArea 定义。 (查看其他答案)
步骤 2 本身看起来无害,但却是整个过程的关键。当 Excel 打开 .xlsx 文档时,它会重新验证所有 pivotTable 条目,删除任何不再存在的条目,包括 CTDXfs 条目。然后它生成缓存,然后应用任何格式。但是,如果缓存尚不存在,则在验证过程中将删除所有格式规则!
下面是我用来生成 pivotCache 的代码块。这比普通的 Whosebug 答案要长得多,但不确定这是首选还是 "general guidance" 如何去做。
如果您需要维护或扩展它,请将 .xlsx 重命名为 .zip,解压缩,然后查看 xl\pivotTables\pivotTable1.xml、xl\pivotCache\pivotCacheDefinition1.xml 将其保存在 excel 之前和之后。如果这工作正常,将 pivotCacheDefinition 保存在 excel.
中后应该基本保持不变
public class PivotUtilitiesExample {
public static void updateCache(XSSFPivotTable pivotTable) {
updateCache(pivotTable,STAxis.AXIS_ROW);
updateCache(pivotTable,STAxis.AXIS_COL);
updateCache(pivotTable,STAxis.AXIS_PAGE);
}
/**
* Updates the pivotCacheDefinition.xml file. This must be run before any formatting is done.
* However, it must also be run *AFTER* the pivotTable's source data is created and all label definitions are defined.
* the labels are sorted by default.
* @param pivotTable
* @param rowLabel if true, updates rowLabels, if false, updates columnLabels.
*/
private static void updateCache(XSSFPivotTable pivotTable,STAxis.Enum axisType) {
XSSFSheet sheet=(XSSFSheet) pivotTable.getDataSheet();
AreaReference pivotArea = new AreaReference(pivotTable.getPivotCacheDefinition().
getCTPivotCacheDefinition().getCacheSource().getWorksheetSource().getRef());
CellReference firstCell = pivotArea.getFirstCell();
CellReference lastCell = pivotArea.getLastCell();
List<Integer> labelColumns=getLabelColumns(pivotTable,axisType);
for(int labelCtr=0;labelCtr<labelColumns.size();++labelCtr) {
CTSharedItems sharedItems=getSharedItems(pivotTable,labelColumns.get(labelCtr));
//The pivotField entry associated will be the nth axis="axisRow" entry where N is the row label #.
CTPivotField pivotField=getPivotField(pivotTable,axisType,labelCtr);
CTItems items=pivotField.getItems();
ArrayList<String> toCache=new ArrayList<String>(lastCell.getRow()-firstCell.getRow());
//To make this work, sharedItems and pivotFields must be properly populated.
//sharedItems should look like:
//<cacheField name="Names" numFmtId="0"> (Cell A1)
//<sharedItems count="3"> (Count of unique rows)
//<s v="Jane"/> (Cell B1)
//<s v="Tarzan"/> (Cell C1)
//<s v="Terk"/> (Cell D1)
//</sharedItems>
//pivotFields should have an entry like this:
//<pivotField axis="axisRow" showAll="0">
//<items count="4">
//<item x="0"/>
//<item x="1"/>
//<item x="2"/>
//<item t="default"/>
//</items>
//Initially, POI will populate with:
//<pivotField axis="axisRow" showAll="0">
//<items count="4">
//<item t="default"/>
//<item t="default"/>
//<item t="default"/>
//<item t="default"/>
//</items>
//Start with firstCell.getRow()+1 since the first row is the column name.
for(int i=firstCell.getRow()+1;i<=lastCell.getRow();++i) {
String s=sheet.getRow(i).getCell(firstCell.getCol()+labelColumns.get(labelCtr)).getStringCellValue();
//Only add unique entries.
if(!toCache.contains(s))
toCache.add(s);
}
//Blank entries cannot be sorted unless they are specially entered after an M tag.
// For most projects this'll be overkill.
boolean containsBlank=false;
if(toCache.contains("")) {
toCache.remove("");
containsBlank=true;
}
//Remove the old cache list.
for(int i=items.sizeOfItemArray()-1;i>=0;--i)
items.removeItem(i);
for(int i=sharedItems.sizeOfBArray()-1;i>=0;--i)
sharedItems.removeB(i);
for(int i=sharedItems.sizeOfDArray()-1;i>=0;--i)
sharedItems.removeD(i);
for(int i=sharedItems.sizeOfEArray()-1;i>=0;--i)
sharedItems.removeE(i);
for(int i=sharedItems.sizeOfMArray()-1;i>=0;--i)
sharedItems.removeM(i);
for(int i=sharedItems.sizeOfNArray()-1;i>=0;--i)
sharedItems.removeN(i);
for(int i=sharedItems.sizeOfSArray()-1;i>=0;--i)
sharedItems.removeS(i);
sharedItems.setCount(sharedItems.getDomNode().getChildNodes().getLength());
items.setCount(items.sizeOfItemArray());
for(int i=0;i<toCache.size();++i) {
CTString string;
CTItem item;
string=sharedItems.addNewS();
sharedItems.setCount(sharedItems.getDomNode().getChildNodes().getLength());
string.setV(toCache.get(i));
item=items.addNewItem();
items.setCount(items.sizeOfItemArray());
item.setX(i);
}
//Create the special blank tag.
if(containsBlank) {
int mPosition;
sharedItems.addNewM();
mPosition=sharedItems.sizeOfSArray();
CTString s=sharedItems.addNewS();
s.setV("");
s.setU(true);
sharedItems.setCount(sharedItems.getDomNode().getChildNodes().getLength());
sharedItems.setContainsBlank(true);
CTItem item=items.addNewItem();
item.setM(true);
item.setX(sharedItems.sizeOfSArray());
item=items.addNewItem();
item.setX(mPosition);
items.setCount(items.sizeOfItemArray());
}
//Add the t="default" entry, required for subtotals.
if(!pivotField.isSetDefaultSubtotal() || pivotField.getDefaultSubtotal()==true) {
CTItem item;
item=items.addNewItem();
items.setCount(items.sizeOfItemArray());
item.setT(STItemType.DEFAULT);
}
}
}
//Returns the label columns for all AXIS. Default POI only has a method for RowLabelColumns.
private static List<Integer> getLabelColumns(XSSFPivotTable pivotTable,STAxis.Enum axisType) {
List<Integer> labelColumns;
if(axisType.equals(STAxis.AXIS_ROW))
labelColumns=pivotTable.getRowLabelColumns();
else if(axisType.equals(STAxis.AXIS_COL)) {
List<CTField> fieldList = pivotTable.getCTPivotTableDefinition().getColFields().getFieldList();
labelColumns=new ArrayList(fieldList.size());
for(CTField field:fieldList)
labelColumns.add(field.getX());
} else if(axisType.equals(STAxis.AXIS_PAGE)) {
List<CTPageField> fieldList = pivotTable.getCTPivotTableDefinition().getPageFields().getPageFieldList();
labelColumns=new ArrayList(fieldList.size());
for(CTPageField field:fieldList)
labelColumns.add(field.getFld());
} else {
throw new UnsupportedOperationException("Error, STAxis: "+axisType+" is not supported");
}
return labelColumns;
}
//Returns the sharedItems entry associated with a particular labelColumn.
private static CTSharedItems getSharedItems(XSSFPivotTable pivotTable,int columnIndex) {
XSSFSheet sheet=(XSSFSheet) pivotTable.getDataSheet();
AreaReference pivotArea = new AreaReference(pivotTable.getPivotCacheDefinition().
getCTPivotCacheDefinition().getCacheSource().getWorksheetSource().getRef());
CellReference firstCell = pivotArea.getFirstCell();
String labelName=sheet.getRow(firstCell.getRow()).getCell(firstCell.getCol()+columnIndex).getStringCellValue();
List<CTCacheField> cacheFieldList = pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldList();
CTSharedItems sharedItems=null;
//The sharedItem entry associated will have name=labelColumn's name.
for(int i=0;i<cacheFieldList.size();++i)
if(labelName.equals(cacheFieldList.get(i).getName())) {
sharedItems=cacheFieldList.get(i).getSharedItems();
break;
}
//Should never be true.
if(sharedItems==null) {
throw new RuntimeException("Error, unable to find sharedItems entry in pivotCacheDefinition.xml");
}
return sharedItems;
}
//Return the nth pivotField entry from the pivotTable definition of a particular Axis.
private static CTPivotField getPivotField(XSSFPivotTable pivotTable,STAxis.Enum axisType,int index) {
CTPivotFields pivotFields = pivotTable.getCTPivotTableDefinition().getPivotFields();
CTPivotField pivotField=null;
for(int i=0,axisRowNum=-1;i<pivotFields.getPivotFieldList().size();++i) {
if(axisType.equals(pivotFields.getPivotFieldList().get(i).getAxis()))
++axisRowNum;
if(axisRowNum==index) {
pivotField=pivotFields.getPivotFieldList().get(i);
break;
}
}
if(pivotField==null)
throw new RuntimeException("Error, unable to find pivotField entry in pivotTable.xml");
return pivotField;
}
}
我正在使用 Apache POI 3.12:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.12</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.12</version>
</dependency>
如何更改枢轴内的字体 table? 在将一个单元格 (I7) 的字体更改为 8pt 大小后检查生成的 .xlsx 显示以下更改:
styles.xml,作为第二个条目的标签内:
<font>
<sz val="8"/>
<color indexed="8"/>
<name val="Calibri"/>
<family val="2"/>
<scheme val="minor"/>
</font>
within the <cellXfs> tag as the 5th entry:
<xf numFmtId="0" fontId="1" fillId="0" borderId="0" xfId="0" applyNumberFormat="1" applyFont="1"/>
New tag: dxfs:
<dxfs count="1">
<dxf>
<font>
<sz val="8"/>
</font>
</dxf>
</dxfs>
pivottable.xml
<formats count="1">
<format dxfId="0">
<pivotArea collapsedLevelsAreSubtotals="1" fieldPosition="0">
<references count="2">
<reference field="4294967294" count="1" selected="0">
<x v="0"/>
</reference>
<reference field="0" count="1">
<x v="0"/>
</reference>
</references>
</pivotArea>
</format>
</formats>
sheet1.xml
<c r="I7" s="4">
注意:我可能会将此作为自我回答关闭,因为我仍在尝试自己解决它。但是,我已经在这里待了将近一个星期。 POI Pivot table sample
这是一个部分答案,因为它需要使用 excel 来设置而不是纯 poi。
一般步骤:
- 在 excel 中创建一个包含枢轴 table 的电子表格,或者使用 sample 作为 poi。
- 打开 excel 中的电子表格并保存。
- 在 poi 中打开电子表格。
- 创建 CTDxfs 条目。这是 "font" table 秒。
- 使用 CTDXfs id 创建一个 pivotArea 定义。
关于代码:
private static CTFormats getFormats(XSSFPivotTable pivotTable) {
CTFormats formats = pivotTable.getCTPivotTableDefinition().getFormats();
if(formats==null)
formats=pivotTable.getCTPivotTableDefinition().addNewFormats();
return formats;
}
private static int createDXFs(XSSFWorkbook wb,int font) {
CTDxfs dxfs=wb.getStylesSource().getCTStylesheet().getDxfs();
if(dxfs==null)
dxfs=wb.getStylesSource().getCTStylesheet().addNewDxfs();
dxfs.setCount(dxfs.getCount()+1);
CTDxf dxf=dxfs.addNewDxf();
CTFontSize fontSize=dxf.addNewFont().addNewSz();
fontSize.setVal(font);
return (int) dxfs.getCount()-1;
}
public static void setAxisFont(CTFormats pivotTableFormats,int dxfId) {
CTFormat format=pivotTableFormats.addNewFormat();
format.setDxfId(dxfId);
CTPivotArea pivotArea = format.addNewPivotArea();
pivotArea.setDataOnly(false);
pivotArea.setLabelOnly(true);
pivotArea.setOutline(false);
pivotArea.setFieldPosition(0L);
pivotArea.setAxis(STAxis.AXIS_ROW);
pivotArea.setType(STPivotAreaType.BUTTON);
}
public static void setColHeaderFont(CTFormats pivotTableFormats,int dxfId,int colInd) {
CTFormat format=pivotTableFormats.addNewFormat();
format.setDxfId(dxfId);
CTPivotArea pivotArea = format.addNewPivotArea();
pivotArea.setDataOnly(false);
pivotArea.setLabelOnly(true);
pivotArea.setOutline(false);
CTPivotAreaReferences references = pivotArea.addNewReferences();
CTPivotAreaReference reference = references.addNewReference();
reference.setField(new Long(Integer.MAX_VALUE)*2);
CTIndex x = reference.addNewX();
x.setV(colInd); //Column
}
public static void setLabelFont(CTFormats pivotTableFormats,int dxfId, int rowInd) {
CTFormat format=pivotTableFormats.addNewFormat();
format.setDxfId(dxfId);
CTPivotArea pivotArea = format.addNewPivotArea();
pivotArea.setDataOnly(false);
pivotArea.setLabelOnly(true);
pivotArea.setFieldPosition(0L);
CTPivotAreaReferences references = pivotArea.addNewReferences();
CTPivotAreaReference reference = references.addNewReference();
reference.setField(0L);
CTIndex x = reference.addNewX();
x.setV(rowInd); //Row
}
public static void setDataElementFont(CTFormats pivotTableFormats,int dxfId,int col,int row) {
CTFormat format=pivotTableFormats.addNewFormat();
format.setDxfId(dxfId);
CTPivotArea pivotArea = format.addNewPivotArea();
//Default values, don't need to explicitly define.
//pivotArea.setDataOnly(true);
//pivotArea.setLabelOnly(false);
CTPivotAreaReferences references = pivotArea.addNewReferences();
CTPivotAreaReference reference = references.addNewReference();
reference.setField(new Long(Integer.MAX_VALUE)*2);
CTIndex x = reference.addNewX();
x.setV(col); //Column
reference = references.addNewReference();
reference.setField(0L);
x = reference.addNewX();
x.setV(row); //Row
}
备注:
- setOutline(false) 需要访问列 headers.
- setDataOnly(false) 允许更改影响标签和数据。
- setLabelOnly(true) 限制仅更改标签值。如果你想改变整个column/row,设置为false。
- unsigned int max 的引用字段值将引用定义为列,另一个有效值为 0,将引用定义为行。
- 如果 col/row 引用未定义,例如 setColHeaderFont/setLabel 字体,它会影响整个 column/row。这对于格式化特定列可能是可取的。
警告 maven 用于 poi 3.12 的 poi-ooxml-schemas 不包括 CTFormats。这可以通过排除它并包括 1.1 版本来覆盖:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.1</version>
</dependency>
这是一个完整的答案,但比之前使用 excel 的答案复杂得多。
一般步骤:
- 在 excel 中创建一个包含枢轴 table 的电子表格,或使用 sample 作为 poi。
- 创建数据透视缓存定义。
- 创建 CTDxfs 条目。这是 "font" for tables。 (查看其他答案)
- 使用 CTDXfs id 创建一个 pivotArea 定义。 (查看其他答案)
步骤 2 本身看起来无害,但却是整个过程的关键。当 Excel 打开 .xlsx 文档时,它会重新验证所有 pivotTable 条目,删除任何不再存在的条目,包括 CTDXfs 条目。然后它生成缓存,然后应用任何格式。但是,如果缓存尚不存在,则在验证过程中将删除所有格式规则!
下面是我用来生成 pivotCache 的代码块。这比普通的 Whosebug 答案要长得多,但不确定这是首选还是 "general guidance" 如何去做。
如果您需要维护或扩展它,请将 .xlsx 重命名为 .zip,解压缩,然后查看 xl\pivotTables\pivotTable1.xml、xl\pivotCache\pivotCacheDefinition1.xml 将其保存在 excel 之前和之后。如果这工作正常,将 pivotCacheDefinition 保存在 excel.
中后应该基本保持不变public class PivotUtilitiesExample {
public static void updateCache(XSSFPivotTable pivotTable) {
updateCache(pivotTable,STAxis.AXIS_ROW);
updateCache(pivotTable,STAxis.AXIS_COL);
updateCache(pivotTable,STAxis.AXIS_PAGE);
}
/**
* Updates the pivotCacheDefinition.xml file. This must be run before any formatting is done.
* However, it must also be run *AFTER* the pivotTable's source data is created and all label definitions are defined.
* the labels are sorted by default.
* @param pivotTable
* @param rowLabel if true, updates rowLabels, if false, updates columnLabels.
*/
private static void updateCache(XSSFPivotTable pivotTable,STAxis.Enum axisType) {
XSSFSheet sheet=(XSSFSheet) pivotTable.getDataSheet();
AreaReference pivotArea = new AreaReference(pivotTable.getPivotCacheDefinition().
getCTPivotCacheDefinition().getCacheSource().getWorksheetSource().getRef());
CellReference firstCell = pivotArea.getFirstCell();
CellReference lastCell = pivotArea.getLastCell();
List<Integer> labelColumns=getLabelColumns(pivotTable,axisType);
for(int labelCtr=0;labelCtr<labelColumns.size();++labelCtr) {
CTSharedItems sharedItems=getSharedItems(pivotTable,labelColumns.get(labelCtr));
//The pivotField entry associated will be the nth axis="axisRow" entry where N is the row label #.
CTPivotField pivotField=getPivotField(pivotTable,axisType,labelCtr);
CTItems items=pivotField.getItems();
ArrayList<String> toCache=new ArrayList<String>(lastCell.getRow()-firstCell.getRow());
//To make this work, sharedItems and pivotFields must be properly populated.
//sharedItems should look like:
//<cacheField name="Names" numFmtId="0"> (Cell A1)
//<sharedItems count="3"> (Count of unique rows)
//<s v="Jane"/> (Cell B1)
//<s v="Tarzan"/> (Cell C1)
//<s v="Terk"/> (Cell D1)
//</sharedItems>
//pivotFields should have an entry like this:
//<pivotField axis="axisRow" showAll="0">
//<items count="4">
//<item x="0"/>
//<item x="1"/>
//<item x="2"/>
//<item t="default"/>
//</items>
//Initially, POI will populate with:
//<pivotField axis="axisRow" showAll="0">
//<items count="4">
//<item t="default"/>
//<item t="default"/>
//<item t="default"/>
//<item t="default"/>
//</items>
//Start with firstCell.getRow()+1 since the first row is the column name.
for(int i=firstCell.getRow()+1;i<=lastCell.getRow();++i) {
String s=sheet.getRow(i).getCell(firstCell.getCol()+labelColumns.get(labelCtr)).getStringCellValue();
//Only add unique entries.
if(!toCache.contains(s))
toCache.add(s);
}
//Blank entries cannot be sorted unless they are specially entered after an M tag.
// For most projects this'll be overkill.
boolean containsBlank=false;
if(toCache.contains("")) {
toCache.remove("");
containsBlank=true;
}
//Remove the old cache list.
for(int i=items.sizeOfItemArray()-1;i>=0;--i)
items.removeItem(i);
for(int i=sharedItems.sizeOfBArray()-1;i>=0;--i)
sharedItems.removeB(i);
for(int i=sharedItems.sizeOfDArray()-1;i>=0;--i)
sharedItems.removeD(i);
for(int i=sharedItems.sizeOfEArray()-1;i>=0;--i)
sharedItems.removeE(i);
for(int i=sharedItems.sizeOfMArray()-1;i>=0;--i)
sharedItems.removeM(i);
for(int i=sharedItems.sizeOfNArray()-1;i>=0;--i)
sharedItems.removeN(i);
for(int i=sharedItems.sizeOfSArray()-1;i>=0;--i)
sharedItems.removeS(i);
sharedItems.setCount(sharedItems.getDomNode().getChildNodes().getLength());
items.setCount(items.sizeOfItemArray());
for(int i=0;i<toCache.size();++i) {
CTString string;
CTItem item;
string=sharedItems.addNewS();
sharedItems.setCount(sharedItems.getDomNode().getChildNodes().getLength());
string.setV(toCache.get(i));
item=items.addNewItem();
items.setCount(items.sizeOfItemArray());
item.setX(i);
}
//Create the special blank tag.
if(containsBlank) {
int mPosition;
sharedItems.addNewM();
mPosition=sharedItems.sizeOfSArray();
CTString s=sharedItems.addNewS();
s.setV("");
s.setU(true);
sharedItems.setCount(sharedItems.getDomNode().getChildNodes().getLength());
sharedItems.setContainsBlank(true);
CTItem item=items.addNewItem();
item.setM(true);
item.setX(sharedItems.sizeOfSArray());
item=items.addNewItem();
item.setX(mPosition);
items.setCount(items.sizeOfItemArray());
}
//Add the t="default" entry, required for subtotals.
if(!pivotField.isSetDefaultSubtotal() || pivotField.getDefaultSubtotal()==true) {
CTItem item;
item=items.addNewItem();
items.setCount(items.sizeOfItemArray());
item.setT(STItemType.DEFAULT);
}
}
}
//Returns the label columns for all AXIS. Default POI only has a method for RowLabelColumns.
private static List<Integer> getLabelColumns(XSSFPivotTable pivotTable,STAxis.Enum axisType) {
List<Integer> labelColumns;
if(axisType.equals(STAxis.AXIS_ROW))
labelColumns=pivotTable.getRowLabelColumns();
else if(axisType.equals(STAxis.AXIS_COL)) {
List<CTField> fieldList = pivotTable.getCTPivotTableDefinition().getColFields().getFieldList();
labelColumns=new ArrayList(fieldList.size());
for(CTField field:fieldList)
labelColumns.add(field.getX());
} else if(axisType.equals(STAxis.AXIS_PAGE)) {
List<CTPageField> fieldList = pivotTable.getCTPivotTableDefinition().getPageFields().getPageFieldList();
labelColumns=new ArrayList(fieldList.size());
for(CTPageField field:fieldList)
labelColumns.add(field.getFld());
} else {
throw new UnsupportedOperationException("Error, STAxis: "+axisType+" is not supported");
}
return labelColumns;
}
//Returns the sharedItems entry associated with a particular labelColumn.
private static CTSharedItems getSharedItems(XSSFPivotTable pivotTable,int columnIndex) {
XSSFSheet sheet=(XSSFSheet) pivotTable.getDataSheet();
AreaReference pivotArea = new AreaReference(pivotTable.getPivotCacheDefinition().
getCTPivotCacheDefinition().getCacheSource().getWorksheetSource().getRef());
CellReference firstCell = pivotArea.getFirstCell();
String labelName=sheet.getRow(firstCell.getRow()).getCell(firstCell.getCol()+columnIndex).getStringCellValue();
List<CTCacheField> cacheFieldList = pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldList();
CTSharedItems sharedItems=null;
//The sharedItem entry associated will have name=labelColumn's name.
for(int i=0;i<cacheFieldList.size();++i)
if(labelName.equals(cacheFieldList.get(i).getName())) {
sharedItems=cacheFieldList.get(i).getSharedItems();
break;
}
//Should never be true.
if(sharedItems==null) {
throw new RuntimeException("Error, unable to find sharedItems entry in pivotCacheDefinition.xml");
}
return sharedItems;
}
//Return the nth pivotField entry from the pivotTable definition of a particular Axis.
private static CTPivotField getPivotField(XSSFPivotTable pivotTable,STAxis.Enum axisType,int index) {
CTPivotFields pivotFields = pivotTable.getCTPivotTableDefinition().getPivotFields();
CTPivotField pivotField=null;
for(int i=0,axisRowNum=-1;i<pivotFields.getPivotFieldList().size();++i) {
if(axisType.equals(pivotFields.getPivotFieldList().get(i).getAxis()))
++axisRowNum;
if(axisRowNum==index) {
pivotField=pivotFields.getPivotFieldList().get(i);
break;
}
}
if(pivotField==null)
throw new RuntimeException("Error, unable to find pivotField entry in pivotTable.xml");
return pivotField;
}
}