gpt4 book ai didi

java - 如何使用 poi 设置数据透视表中行标签的默认值

转载 作者:行者123 更新时间:2023-12-02 00:11:18 27 4
gpt4 key购买 nike

我正在处理 Excel 报告。我需要生成数据透视表,其中某些特定字段作为行标签中的默认值,而不是选择所有字段。我正在使用 apache POI。

This what I am getting automatically when I load excel sheet

This is what I need

AreaReference source = new AreaReference("A1:D5", SpreadsheetVersion.EXCEL2007);
CellReference position = new CellReference(10,0);

XSSFPivotTable pivotTable = sheet1.createPivotTable(source, position,wb.getSheet("1econtent"));

pivotTable.addReportFilter(2);
pivotTable.addRowLabel(0);

pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1,"% of value");

pivotTable.getCTPivotTableDefinition().getDataFields().getDataFieldArray(1).setShowDataAs(org.openxmlformats.schemas.spreadsheetml.x2006.main.STShowDataAs.PERCENT_OF_COL);
DataFormat dataformat = wb.createDataFormat();
short numFmtId = dataformat.getFormat("0.00%");
pivotTable.getCTPivotTableDefinition().getDataFields().getDataFieldArray(1).setNumFmtId(numFmtId);
pivotTable.getCTPivotTableDefinition().getPivotTableStyleInfo().setName("PivotStyleMedium10");

我尝试了很多方法,但没有找到答案。

最佳答案

apache poi 中创建数据透视表到目前为止还只是初级阶段。

Apache poi添加与数据源中的行一样多的“默认”类型 ( <item t="default"/> ) 的数据透视字段项。这是因为他们不想查看数据,因此他们假设与数据源中的行一样多的不同值。这很好,因为 Excel 将在打开时重建其数据透视缓存。

但是如果我们想要预选项目,那么这就不行了。那么我们必须知道有哪些项目可以预选。

因此,我们至少需要与预选编号项目一样多的项目:<item x="0"/><item x="1"/><item x="2"/>... 。我们必须构建一个缓存定义,其中包含这些项目的共享元素。

为了满足该要求,我们需要确定数据源中所有行的唯一标签。然后,对于每个唯一标签,将该项目作为编号项目。然后构建一个缓存定义,其中包含这些项目的共享元素。然后隐藏所有不需要的项目。

让我们看一个完整的示例,它可以创建您在问题图片中显示的内容。您问题中的代码不完整,因此我必须预测您有哪些数据作为数据源。请在进一步的问题中尽量避免这种情况,并始终提供 Minimal, Reproducible Example 。否则您将无法得到进一步的答案。

import java.io.FileOutputStream;

import org.apache.poi.ss.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.xssf.usermodel.*;

class CreatePivotTablePercentAndFilter {

public static void main(String[] args) throws Exception {

try (Workbook workbook = new XSSFWorkbook();
FileOutputStream fileout = new FileOutputStream("ooxml-pivottable.xlsx") ) {

Sheet pivotSheet = workbook.createSheet("Pivot");
Sheet dataSheet = workbook.createSheet("Data");

setCellData(dataSheet);

AreaReference areaReference = new AreaReference("A1:D5", SpreadsheetVersion.EXCEL2007);

XSSFPivotTable pivotTable = ((XSSFSheet)pivotSheet).createPivotTable(areaReference, new CellReference("A4"), dataSheet);

pivotTable.addRowLabel(0);

pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1);
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1,"% of value");

pivotTable.getCTPivotTableDefinition().getDataFields().getDataFieldArray(1).setShowDataAs(
org.openxmlformats.schemas.spreadsheetml.x2006.main.STShowDataAs.PERCENT_OF_COL);
DataFormat dataformat = workbook.createDataFormat();
short numFmtId = dataformat.getFormat("0.00%");
pivotTable.getCTPivotTableDefinition().getDataFields().getDataFieldArray(1).setNumFmtId(numFmtId);

/*
Apache poi adds 5 pivot field items of type "default" (<item t="default"/>) for each row label here.
This is because there are 5 rows (A1:D5) and, because they don't want have a look at the data,
they are assuming max 5 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 preselect being 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.

To fulfill that we need determine the unique labels in column.
Then for each unique label take the item as numbered item.
Then build a cache definition which has shared elements for those items.
Then set all not wanted items hidden.
*/

//determine unique labels in column 0
java.util.TreeSet<String> uniqueItems = new java.util.TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
for (int r = areaReference.getFirstCell().getRow()+1; r < areaReference.getLastCell().getRow()+1; r++) {
uniqueItems.add(dataSheet.getRow(r).getCell(areaReference.getFirstCell().getCol()).getStringCellValue());
}
System.out.println(uniqueItems);
int i = 0;
for (String item : uniqueItems) {
//take the items as numbered items: <item x="0"/><item x="1"/><item x="2"/>
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(0).getItems().getItemArray(i).unsetT();
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(0).getItems().getItemArray(i).setX((long)i);
//build a cache definition which has shared elements for those items
//<sharedItems><s v="Jack"/><s v="Jane"/><s v="Tarzan"/><s v="Terk"/></sharedItems>
pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(0)
.getSharedItems().addNewS().setV(item);
i++;
}

//Now we can predefinite a filter.
//If the need is selecting multiple items, first MultipleItemSelectionAllowed needs to be set.
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(0).setMultipleItemSelectionAllowed(true);
//Then set H(idden) true for all items which not shall be selected. All except "Jane" in this case.
i = 0;
for (String item : uniqueItems) {
if (!"Jane".equals(item))
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(0).getItems().getItemArray(i).setH(true);
i++;
}

workbook.write(fileout);
}
}

static void setCellData(Sheet sheet) {
Row row;
Cell cell;
Object[][] data = new Object[][]{
new Object[]{"Names", "Values", "ColC", "ColD"},
new Object[]{"Jane", 10d, "?", "?"},
new Object[]{"Tarzan", 5d, "?", "?"},
new Object[]{"Terk", 10d, "?", "?"},
new Object[]{"Jack", 10d, "?", "?"}
};
for (int r = 0; r < data.length; r++) {
row = sheet.createRow(r);
Object[] rowData = data[r];
for (int c = 0; c < rowData.length; c++) {
cell = row.createCell(c);
if (rowData[c] instanceof String) {
cell.setCellValue((String)rowData[c]);
} else if (rowData[c] instanceof Double) {
cell.setCellValue((Double)rowData[c]);
}
}
}
}
}

关于java - 如何使用 poi 设置数据透视表中行标签的默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58119428/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com