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.
在编写将结果集导出到 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.