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

问题描述 投票:17回答:6

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

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

为了使自己更清楚,这是一个简单的示例:

  • 单元格A1包含“ 1”,B1包含“ 2”,A2包含“ 3”,B2包含“ 4”。
  • 单元格A3包含以下公式“ = A1 + B1”。

如果我将公式复制到excel下的A4单元格,它将变为"=A2+B2":excel正在动态调整公式的内容。

很遗憾,我无法以编程方式获得相同的结果。我发现的唯一解决方案是对公式进行标记化,然后自己完成肮脏的工作,但是我真的怀疑这样做是否应该这样做。我无法在指南或API中找到所需的内容。

有没有更简单的方法来解决此问题?如果是这样,可以请您指出正确的方向吗?

最诚挚的问候,

指甲

java excel apache-poi poi-hssf
6个回答
9
投票

我也认为没有简单的方法可以做到这一点。

即使是POI站点上的HSSF and XSSD examples,例如TimesheetDemo手动进行公式构建。例如110行附近

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

7
投票

在我看来,user2622016是正确的,除了他的解决方案仅管理cell引用,而不是area引用(例如,它不适用于=SUM(A1:B8))。 >

这是我解决此问题的方式:

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);
}

我仍然不知道我是否对所有单元格公式都正确,但是它对我有用,快速而可靠。


5
投票

我查看了[[FormulaEvaluator


3
投票
相对复制公式的另一种方法,用poi 3.12测试过

2
投票
我不认为有。 POI必须解析公式(考虑到A1 vs. $ A $ 1 vs. $ A1等),我不认为它具有这种能力。过去,当我这样做时,我总是不得不自己解决这个问题。抱歉-不是您希望的答案!

-2
投票
您可以尝试一些第三方excel库,其中大多数可以处理相对/绝对范围公式。
© www.soinside.com 2019 - 2024. All rights reserved.