我正在使用Apache的POI来通过Java操作Excel(.xls)文件。
我正在尝试创建一个新单元格,其内容是公式的结果,就好像用户已复制/粘贴了该公式(我称之为“相对”方式,与“绝对”相反)。
为了使自己更清楚,这是一个简单的示例:
如果我将公式复制到excel下的A4单元格,它将变为"=A2+B2"
:excel正在动态调整公式的内容。
很遗憾,我无法以编程方式获得相同的结果。我发现的唯一解决方案是对公式进行标记化,然后自己完成肮脏的工作,但是我真的怀疑这样做是否应该这样做。我无法在指南或API中找到所需的内容。
有没有更简单的方法来解决此问题?如果是这样,可以请您指出正确的方向吗?
最诚挚的问候,
指甲
我也认为没有简单的方法可以做到这一点。
即使是POI站点上的HSSF and XSSD examples,例如TimesheetDemo手动进行公式构建。例如110行附近
String ref = (char)('A' + j) + "3:" + (char)('A' + j) + "12";
cell.setCellFormula("SUM(" + ref + ")");
在我看来,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); }
我仍然不知道我是否对所有单元格公式都正确,但是它对我有用,快速而可靠。
我查看了[[FormulaEvaluator