POI/Excel:以“相对”方式应用公式

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (43)

我使用Apache的POI来使用Java操作Excel(.xls)文件。

我试图创建一个新的单元格,其内容是公式的结果,就好像用户复制/粘贴了公式(我称之为“相对”方式,与“绝对”相反)。

为了让我更清楚,这里有一个简单的例子:单元格A1包含“1”,B1包含“2”,A2包含“3”,B2包含“4”。单元格A3包含以下公式“=A1+B1”。如果我将公式复制到EXCEL下的A4单元格中,则会变成“=A2+B2”:EXCEL动态地调整公式的内容。

不幸的是,我无法通过编程获得相同的结果。我找到的唯一解决办法是标记公式,但我真的怀疑这是否应该是那样做的。我无法在指南或API中找到我正在寻找的内容。

有没有更容易解决这个问题的方法?如果是这样的话,你能指出正确的方向吗?

提问于
用户回答回答于

private void copyFormula(Sheet sheet, Cell org, Cell dest) {
    if (org == null || dest == null || sheet == null 
            || org.getCellType() != Cell.CELL_TYPE_FORMULA)
        return;
    if (org.isPartOfArrayFormulaGroup())
        return;
    String formula = org.getCellFormula();
    int shiftRows = dest.getRowIndex() - org.getRowIndex();
    int shiftCols = dest.getColumnIndex() - org.getColumnIndex();
    XSSFEvaluationWorkbook workbookWrapper = 
            XSSFEvaluationWorkbook.create((XSSFWorkbook) sheet.getWorkbook());
    Ptg[] ptgs = FormulaParser.parse(formula, workbookWrapper, FormulaType.CELL
            , sheet.getWorkbook().getSheetIndex(sheet));
    for (Ptg ptg : ptgs) {
        if (ptg instanceof RefPtgBase) // base class for cell references
        {
            RefPtgBase ref = (RefPtgBase) ptg;
            if (ref.isColRelative())
                ref.setColumn(ref.getColumn() + shiftCols);
            if (ref.isRowRelative())
                ref.setRow(ref.getRow() + shiftRows);
        } else if (ptg instanceof AreaPtg) // base class for range references
        {
            AreaPtg ref = (AreaPtg) ptg;
            if (ref.isFirstColRelative())
                ref.setFirstColumn(ref.getFirstColumn() + shiftCols);
            if (ref.isLastColRelative())
                ref.setLastColumn(ref.getLastColumn() + shiftCols);
            if (ref.isFirstRowRelative())
                ref.setFirstRow(ref.getFirstRow() + shiftRows);
            if (ref.isLastRowRelative())
                ref.setLastRow(ref.getLastRow() + shiftRows);
        }
    }
    formula = FormulaRenderer.toFormulaString(workbookWrapper, ptgs);
    dest.setCellFormula(formula);
}

我仍然不知道我是否对所有的公式都正确,但它对我有效,快速和可靠。

用户回答回答于

我也认为这样做并不容易。

甚至HSSF和XSSD示例在POI站点上。时间表演示手动进行公式构造。例如,在第110行附近。

String ref = (char)('A' + j) + "3:" + (char)('A' + j) + "12";
cell.setCellFormula("SUM(" + ref + ")");

扫码关注云+社区