【问题标题】:Apache POI Excel Table-TotalsRowApache POI Excel 表-TotalsRow
【发布时间】:2015-10-05 12:53:30
【问题描述】:

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

我相信一定有一些魔法,比如公式评估器或类似的东西,但我还没有在 javadocs 或示例代码中偶然发现它。我正在使用this location 的代码并进行以下修改。在设置列标题的循环内部:

     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>

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

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

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

【问题讨论】:

    标签: java xml excel formatting apache-poi


    【解决方案1】:

    如果我为命名空间使用正确的完整 URI,则工作簿将保存并且一切都很好,只要我不尝试使用 POI 评估公式。我使用工作簿 setForceFormulaRecalculation,它在打开 Excel 时工作。我相信这仍然是 POI 中的一个错误,但我需要快速修复,这对我来说是可行的。

    【讨论】:

      【解决方案2】:

      注意:我意识到这是一篇非常古老的帖子,但以防万一将来有人可能会在我遇到同样的问题时寻找解决方案...

      您在正确的轨道上,但我看不到您在实际总行中将公式应用于单元格的位置。如果您不设置此项,则打开文件时总行将显示但为空。

      创建表格时

      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。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多