Java Apache POI Excel表格TotalsRow
在编写将结果集导出到Excel的工具时,我遇到了一个问题。我正在成功地创建列标题上带有格式和过滤器的表,没有问题。问题是我不知道如何使总计行“工作”。我想使用真正的总计行,以便它们响应应用的过滤器,但到目前为止,我可以获得一个包含该函数的小计但不属于表的行,或者可以获得一个空小计行 我相信一定有一些魔力,比如公式计算器或类似的东西,但我还没有在javadocs或示例代码中偶然发现它。我使用的代码在与以下修改。在设置列标题的循环中:Java Apache POI Excel表格TotalsRow,java,xml,excel,formatting,apache-poi,Java,Xml,Excel,Formatting,Apache Poi,在编写将结果集导出到Excel的工具时,我遇到了一个问题。我正在成功地创建列标题上带有格式和过滤器的表,没有问题。问题是我不知道如何使总计行“工作”。我想使用真正的总计行,以便它们响应应用的过滤器,但到目前为止,我可以获得一个包含该函数的小计但不属于表的行,或者可以获得一个空小计行 我相信一定有一些魔力,比如公式计算器或类似的东西,但我还没有在javadocs或示例代码中偶然发现它。我使用的代码在与以下修改。在设置列标题的循环中: if(i == 0) column.
if(i == 0)
column.setTotalsRowLabel("Totals:");
else
column.setTotalsRowFunction(STTotalsRowFunctionImpl.COUNT);
然后在循环之外:
cttable.setTotalsRowShown(true);
cttable.setTotalsRowCount(1);
不走运,如果我为总计添加一个空行,它将被格式化为表的一部分,但不会显示任何值。如果我为任何合计单元格设置了一个公式,则该公式有效,但Excel不喜欢该表并删除了合计行,尽管该公式存在且有效,只是不作为合计行
当我查看下面的原始XML时,除了表格之外,它实际上与Excel工作表没有什么区别,而工作表却大不相同
更新:
我已经离开这个项目很长一段时间了,最近又回到了它。我已经放弃了POI自动完成这项工作,转而尝试通过DOM操作来实现它
我离得很近,我不能放弃。这一切都归结为最终工作表中的名称空间问题。此代码:
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>
小计(103,我的表格[人])
如果我使用createElement(“f”),我会得到:
小计(103,我的表格[人])
如果我在归档文件中手动编辑工作表并删除名称空间标记或限定符,它就可以工作了!如果不保存工作簿,然后继续打开它并用文件IO修复问题,我看不出如何解决NS问题。有人对此有任何提示吗?如果我为名称空间使用正确的完整URI,工作簿会保存,只要我不尝试使用POI计算公式,一切都会正常。我在上使用工作簿setForceFormulaRecalculation,它在打开Excel时工作。我相信这仍然是POI中的一个bug,但我需要一个快速修复,这对我来说就足够了。注意:我意识到这是一篇非常古老的帖子,但只是为了防止将来有人会因为我刚刚遇到同样的问题而寻找解决方案 您的思路是正确的,但我看不出您将公式应用于实际总计行中的单元格的位置。如果未设置此选项,则在打开文件时,总计行将显示,但为空 创建表格时
cttable.setTotalsRowShown(true);
cttable.setTotalsRowCount(1);
cttable.addNewAutoFilter();
创建列时
column.setTotalsRowFunction(STTotalsRowFunctionImpl.COUNT);
填充所有表数据后
Row totalsRow = sheet.createRow(tableLastRow);
Cell totalsCell = totalsRow.createCell(lastColumnPosition);
totalsCell.setCellFormula("SUBTOTAL(103,MYTABLE[Human])");
您必须为特定于代码的值填充tableLastRow和lastColumnPosition。这对我来说适用于Apache POI 3.17和Excel 2016
Row totalsRow = sheet.createRow(tableLastRow);
Cell totalsCell = totalsRow.createCell(lastColumnPosition);
totalsCell.setCellFormula("SUBTOTAL(103,MYTABLE[Human])");