javascript - 如何重复数据透视表中的所有标签 - Apache POI

标签 javascript java apache-poi pivot-table

如何按照下面的屏幕截图实现数据透视表中的重复所有项目,还需要知道如何在所有列中获取该下拉图标。现在下拉图标仅显示在第一列。 Apache POI 中可以实现重复所有项目吗?

下面是代码。

我得到的输出:

enter image description here

我需要的输出:

enter image description here

 public class TestPivotTable
 {
public static void main(String[] args) throws Exception
{
    Workbook wb = new XSSFWorkbook();
    String[][] data = new String[][]{{"AAA","BBB","CCC","DDD","EEE","FFF","GGG","HHH"}, 
 {"TOM","DUMMY","VAL","1001683","Description1","27/04/2017","CAT","7,80,936.58"},
        {"TOM","DUMMY","VAL","1001695","Description2","27/04/2017","CAT","136.28"},
        {"HARRY","DUMMY1","VAL1","1001692","Description3","03/05/2017","CAT1","191468.21"},
        {"HARRY","DUMMY1","VAL1","1001698","Description4","04/05/2017","CAT1","10.11"}};

    XSSFSheet sheet = (XSSFSheet) wb.createSheet("data");
    XSSFSheet pivot = (XSSFSheet) wb.createSheet("summary");
    for(String[] dataRow : data){
        XSSFRow row = sheet.createRow(sheet.getPhysicalNumberOfRows());
        for(String dataCell : dataRow){
            XSSFCell cell = row.createCell(row.getPhysicalNumberOfCells());
            cell.setCellValue(dataCell);
        }
    }
    XSSFTable table = sheet.createTable();    
    CTTable cttable = table.getCTTable();
    table.setDisplayName("table");
    cttable.setRef("A1:D4");
    cttable.setId(1);

    CTTableColumns columns = cttable.addNewTableColumns();
    columns.setCount(3);

    int g = 1;
    for (String colName : data[0]){
        CTTableColumn column = columns.addNewTableColumn();
        column.setId(++g);
        column.setName(colName);      
    }
  AreaReference areaReference = new AreaReference("A1:H"+ (sheet.getLastRowNum() + 
  1),SpreadsheetVersion.EXCEL2007);
  FileOutputStream fileOut=null;
  try {
    XSSFPivotTable pivotTable =  pivot.createPivotTable(areaReference, new CellReference("A1"), 
  sheet);

    pivotTable.getCTPivotTableDefinition().setRowHeaderCaption("AAA");

    List<Integer> iterList = new ArrayList<Integer>();

    iterList.add(0);
    iterList.add(1);
    iterList.add(2);
    iterList.add(3);
    iterList.add(4);
    iterList.add(5);
    iterList.add(6);

    for (Integer j : iterList) {

        pivotTable.addRowLabel(j);
        TreeSet<String> uniqueItems = new java.util.TreeSet<String>();
        for (int r = areaReference.getFirstCell().getRow()+1; r < 
   areaReference.getLastCell().getRow()+1; r++) {
            uniqueItems.add(sheet.getRow(r).getCell(j).toString());
        }
        System.out.println(uniqueItems);
        CTPivotField ctPivotField = 
   pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(j);
        int i = 0;
        for (String item : uniqueItems) {
            ctPivotField.getItems().getItemArray(i).unsetT();
            ctPivotField.getItems().getItemArray(i).setX((long)i);


pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().
 getCacheFieldArray(j)
            .getSharedItems().addNewS().setV(item);
            i++;
        }
       // ctPivotField.setAutoShow(false);
        ctPivotField.setDefaultSubtotal(false);
         ctPivotField.setOutline(false);
       // ctPivotField.setCompact(false);
       // ctPivotField.setSubtotalTop(true);
        if (ctPivotField.getDefaultSubtotal()) i++; 
        for (int k = ctPivotField.getItems().getItemList().size()-1; k >= i; k--) {
            ctPivotField.getItems().removeItem(k);
        }
        ctPivotField.getItems().setCount(i);

    }

    System.out.println("----end---");

    pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 7, "SUM");

    fileOut = new FileOutputStream("newoutputfile.xlsx");
    wb.write(fileOut);
}catch(Exception e) {
    System.out.println("Exception While Creating Pivot Table"+e);
}finally {
    fileOut.close();
    wb.close();
}

}

}

最佳答案

数据透视表的“重复所有项目标签”设置是在Office Open XML之后实现的。已发布。这就是为什么它不是其中的一部分。它使用特殊扩展XML来自 namespace x14 。但是apache poi只提供Office Open XML .

所以如果我们想使用扩展 XML来自 namespace x14 ,我们需要在低 XML 上这样做级别。

首先,我们需要将更新的数据透视表版本设置为 6 而不是 3。

然后我们需要设置<x14:pivotField fillDownLabels="1"/>对于每个 CTPivotField 。这是“重复所有项目标签”设置。

扩展您显示的代码的完整示例:

import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.ss.*;
import java.io.*;
import java.util.ArrayList;
import java.util.TreeSet;
import java.util.List;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;

public class TestPivotTable {
 public static void main(String[] args) throws Exception {
  Workbook wb = new XSSFWorkbook();
  Object[][] data = new Object[][]{
   {"AAA","BBB","CCC","DDD","EEE","FFF","GGG","HHH"}, 
   {"TOM","DUMMY","VAL","1001683","Description1","27/04/2017","CAT",780936.58},
   {"TOM","DUMMY","VAL","1001695","Description2","27/04/2017","CAT",136.28},
   {"HARRY","DUMMY1","VAL1","1001692","Description3","03/05/2017","CAT1",191468.21},
   {"HARRY","DUMMY1","VAL1","1001698","Description4","04/05/2017","CAT1",10.11}
  };

  XSSFSheet sheet = (XSSFSheet) wb.createSheet("data");
  XSSFSheet pivot = (XSSFSheet) wb.createSheet("summary");
  for(Object[] dataRow : data){
   XSSFRow row = sheet.createRow(sheet.getPhysicalNumberOfRows());
   for(Object dataCell : dataRow){
    XSSFCell cell = row.createCell(row.getPhysicalNumberOfCells());
    if (dataCell instanceof String) {
     cell.setCellValue((String)dataCell);
    } else if (dataCell instanceof Double) {
     cell.setCellValue((Double)dataCell);
    }
   }
  }

  AreaReference areaReference = new AreaReference("A1:H"+ (sheet.getLastRowNum() + 1), SpreadsheetVersion.EXCEL2007);
  XSSFPivotTable pivotTable =  pivot.createPivotTable(areaReference, new CellReference("A1"), sheet);
  pivotTable.getCTPivotTableDefinition().setRowHeaderCaption("AAA");

  List<Integer> iterList = new ArrayList<Integer>();
  iterList.add(0);
  iterList.add(1);
  iterList.add(2);
  iterList.add(3);
  iterList.add(4);
  iterList.add(5);
  iterList.add(6);

  //set updated pivot table version to 6
  //necessary to make extended pivot table setting available
  pivotTable.getCTPivotTableDefinition().setUpdatedVersion((short)6); 

  for (Integer j : iterList) {

   //create row label - apache poi creates as much fields for each as rows are in the pivot table data range
   pivotTable.addRowLabel(j);

   //determine unique labels in column j
   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(sheet.getRow(r).getCell(j).getStringCellValue());
   }
   System.out.println(uniqueItems);
   
   //build pivot table and cache
   CTPivotField ctPivotField = pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(j);
   int i = 0;
   for (String item : uniqueItems) {
    //take the items as numbered items: <item x="0"/><item x="1"/>
    ctPivotField.getItems().getItemArray(i).unsetT();
    ctPivotField.getItems().getItemArray(i).setX((long)i);
    //build a cache definition which has shared elements for those items 
    //<sharedItems><s v="TOM"/><s v="HARRY"/></sharedItems>
    pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(j)
     .getSharedItems().addNewS().setV(item);
    i++;
   }

   //ctPivotField.setAutoShow(false);
   ctPivotField.setDefaultSubtotal(false);
   //ctPivotField.setSubtotalTop(false);
   //ctPivotField.setSubtotalCaption(null);
   //ctPivotField.setCompact(false);
   ctPivotField.setOutline(false);

   //remove further items
   if (ctPivotField.getDefaultSubtotal()) i++; //let one default item be if there shall be subtotals
   for (int k = ctPivotField.getItems().getItemList().size()-1; k >= i; k--) {
    ctPivotField.getItems().removeItem(k);
   }
   ctPivotField.getItems().setCount(i);

   //set <x14:pivotField fillDownLabels="1"/> for each CTPivotField
   //this is the "Repeat All Items Label" setting
   CTExtensionList extList = ctPivotField.addNewExtLst();
   CTExtension ext = extList.addNewExt();
   String extXML = 
      "<x14:pivotField"
    + " xmlns:x14=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main\""
    + " fillDownLabels=\"1\"/>";
   org.apache.xmlbeans.XmlObject xlmObject = org.apache.xmlbeans.XmlObject.Factory.parse(extXML);
   ext.set(xlmObject);
   ext.setUri("{2946ED86-A175-432a-8AC1-64E0C546D7DE}");  
   
  }

  System.out.println("----end---");

  pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 7, "SUM");

  FileOutputStream fileOut = new FileOutputStream("newoutputfile.xlsx");
  wb.write(fileOut);
  fileOut.close();
  wb.close();
 }
}

注意:我已删除 XSSFTable从您的代码创建,因为它是不必要的并且做得错误并导致损坏 Excel如果像您所做的那样完成,则归档。

关于javascript - 如何重复数据透视表中的所有标签 - Apache POI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58848489/

相关文章:

java - 从表名中获取主键的值

java - 在java中嵌入jape规则(Gate)

apache-poi - 编辑/写入工作簿,无需以不同名称保存

javascript - 打开侧面菜单时更改正文的 alpha 值

javascript - 如何在不刷新页面的情况下,点击按钮后显示本地存储的内容?

javascript - 如果我的 props 在 React 中发生变化,如何更新状态以强制重新渲染?

java - jUnit4.0 : how to know current test method name?

apache-poi - Apache POI XWPFRun 对象中的分隔文本行

java - 使用哪个API作为行业标准生成pdf生成word文档

javascript - 基于两个属性,使用 underscore.js 在 javascript 中过滤和唯一对象数组