Apache 兴趣点 Excel Table-TotalsRow

Apache POI Excel Table-TotalsRow

在编写将结果集导出到 Excel 的工具时,我遇到了一个问题。我在 headers 列上成功创建了带有格式和过滤器的 table,没问题。问题是我无法弄清楚如何制作总行 "work." 我想使用真正的总行以便它们响应应用的过滤器,但到目前为止我可以得到一个带有小计的行但不是不是 table 的一部分,否则我可以得到一个空白的小计行。

我相信一定有一些神奇的东西,比如公式计算器或类似的东西,但我还没有在 javadoc 或示例代码中偶然发现它。我使用 this location 处的代码并进行了以下修改。在设置列 headers:

的循环内
     if(i == 0)
         column.setTotalsRowLabel("Totals:");
     else
         column.setTotalsRowFunction(STTotalsRowFunctionImpl.COUNT);          

然后循环外:

cttable.setTotalsRowShown(true);
cttable.setTotalsRowCount(1);

不走运,如果我为总计添加一个空白行,它的格式将作为 table 的一部分,但不会显示任何值。如果我为任何总单元格设置公式,该公式有效,但 Excel 不喜欢 table 并删除总行,尽管公式在那里并且有效,但不是总计行。

当我查看下面的原始 XML 时,除了 table,它与 Excel sheet 几乎没有区别,而工作 sheet 有很大的不同。

更新: 我离开这个项目已经有一段时间了,最​​近又回到了它。我已经放弃了 POI 自动执行此操作,而是转而尝试通过 DOM 操作对其进行后门处理。

我是如此接近,我不能放弃。这一切都归结为最终作品中的命名空间问题sheet。此代码:

Element b = (Element) wb.getSheetAt(0).getCTWorksheet().getSheetData().getRowList().get(4).getCArray()[3].getDomNode();
Element f = b.getOwnerDocument().createElementNS("main", "f");
b.removeAttribute("t");
b.removeChild(b.getElementsByTagName("v").item(0));
f.appendChild(b.getOwnerDocument().createTextNode("SUBTOTAL(103,MYTABLE[Human])"));
b.appendChild(f);

在 sheet1.xml 文件中生成以下内容:

<c r="D5">
    <main:f>SUBTOTAL(103,MYTABLE[Human])</f>
</c>

如果我使用 createElement("f"),我得到:

<c r="D5">
    <f xmlns="">SUBTOTAL(103,MYTABLE[Human])</f>
</c>

如果我手动编辑存档中的 sheet 并删除名称空间标记或限定符,它就可以工作!如果不保存工作簿然后继续打开它并修复文件 IO 问题,我看不出如何解决 NS 问题。有人对此有任何提示吗?

如果我为命名空间使用正确的完整 URI,只要我不尝试使用 POI 计算公式,工作簿就会保存并且一切正常。我使用工作簿 setForceFormulaRecalculation on 并且它在 Excel 打开时工作。我认为它仍然是 POI 中的一个错误,但我需要快速修复,这对我来说是对的。

注意:我意识到这是一个非常古老的问题 post,但以防万一将来有人可能正在寻找解决方案,因为我刚刚遇到了同样的问题。 .

您的方向是正确的,但我看不到您在哪里将公式应用于实际总计行中的单元格。如果您不设置此项,总计行将存在,但在打开文件时为空。

创建时 table

cttable.setTotalsRowShown(true);
cttable.setTotalsRowCount(1);
cttable.addNewAutoFilter();

创建列时

column.setTotalsRowFunction(STTotalsRowFunctionImpl.COUNT); 

填充所有 table 数据后

Row totalsRow = sheet.createRow(tableLastRow);
Cell totalsCell = totalsRow.createCell(lastColumnPosition);
totalsCell.setCellFormula("SUBTOTAL(103,MYTABLE[Human])");

您必须为特定于您的代码的值填充 tableLastRow 和 lastColumnPosition。这适用于 Apache POI 3.17 和 Excel 2016.