gpt4 book ai didi

java - Apache POI 复制时更新公式引用

转载 作者:行者123 更新时间:2023-12-02 01:20:50 25 4
gpt4 key购买 nike

在 Apache POI 中复制公式时是否可以更新公式引用?

假设在 Excel 中,第 1 行中有公式 =A1/B1。如果您复制粘贴它,例如在第 5 行,公式将变为 =A5/B5。

在 Apache POI 中,如果运行以下行

r5.getCell(2).setCellType(CellType.FORMULA);
r5.getCell(2).setCellFormula(r1.getCell(2).getCellFormula());

公式仍然是=A1/B1

最佳答案

您的代码不是复制/粘贴某些内容,而是从一个单元格获取公式字符串,并将该公式字符串精确设置到另一个单元格。这不会改变公式字符串。到底应该怎样做呢?

因此需要从一个单元格中获取公式字符串,然后将此公式字符串调整到目标单元格。

既然apache poi能够计算公式,它也必须能够解析公式。解析类位于包 org.apache.poi.ss.formula 中和 org.apache.poi.ss.formula.ptg .

因此我们可以使用这些类将公式字符串调整为目标单元格。

示例:

以下 Excel 工作簿:

enter image description here

和以下代码:

import java.io.FileInputStream;

import org.apache.poi.ss.formula.*;
import org.apache.poi.ss.formula.ptg.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;

import org.apache.poi.ss.util.CellAddress;

public class ExcelCopyFormula {

private static String copyFormula(XSSFSheet sheet, String formula, int coldiff, int rowdiff) {

XSSFEvaluationWorkbook workbookWrapper =
XSSFEvaluationWorkbook.create((XSSFWorkbook) sheet.getWorkbook());
Ptg[] ptgs = FormulaParser.parse(formula, workbookWrapper, FormulaType.CELL
, sheet.getWorkbook().getSheetIndex(sheet));

for (int i = 0; i < ptgs.length; i++) {
if (ptgs[i] instanceof RefPtgBase) { // base class for cell references
RefPtgBase ref = (RefPtgBase) ptgs[i];
if (ref.isColRelative())
ref.setColumn(ref.getColumn() + coldiff);
if (ref.isRowRelative())
ref.setRow(ref.getRow() + rowdiff);
}
else if (ptgs[i] instanceof AreaPtgBase) { // base class for range references
AreaPtgBase ref = (AreaPtgBase) ptgs[i];
if (ref.isFirstColRelative())
ref.setFirstColumn(ref.getFirstColumn() + coldiff);
if (ref.isLastColRelative())
ref.setLastColumn(ref.getLastColumn() + coldiff);
if (ref.isFirstRowRelative())
ref.setFirstRow(ref.getFirstRow() + rowdiff);
if (ref.isLastRowRelative())
ref.setLastRow(ref.getLastRow() + rowdiff);
}
}

formula = FormulaRenderer.toFormulaString(workbookWrapper, ptgs);
return formula;
}

public static void main(String[] args) throws Exception {

XSSFWorkbook workbook = (XSSFWorkbook)WorkbookFactory.create(new FileInputStream("test.xlsx"));
XSSFSheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
//if (cell.getCellTypeEnum() == CellType.FORMULA) { // up to apache poi version 3
if (cell.getCellType() == CellType.FORMULA) { // since apache poi version 4
CellAddress source = cell.getAddress();
String formula = cell.getCellFormula();
System.out.print(source + "=" + formula);
int rowdiff = 3;
int coldiff = -2;
CellAddress target = new CellAddress(source.getRow() + rowdiff, source.getColumn() + coldiff);
String newformula = copyFormula(sheet, formula, coldiff, rowdiff);
System.out.println("->" + target + "=" + newformula);
}
}
}

workbook.close();
}
}

导致以下输出:

E3=C3/D3->C6=A6/B6
E4=$C4/D$4->C7=$C7/B$4
E5=SUM(C3:D5)->C8=SUM(A6:B8)
E6=SUM(C$3:$D6)->C9=SUM(A$3:$D9)
E7=C3+SUM(C3:D7)->C10=A6+SUM(A6:B10)
E8=C$3+SUM($C3:D$8)->C11=A$3+SUM($C6:B$8)
<小时/>

更新了 String copyFormula(Sheet Sheet, String Formula, int Coldiff, int rowdiff) 方法,该方法适用于 SS,适用于 HSSF以及XSSF:

 private static String copyFormula(Sheet sheet, String formula, int coldiff, int rowdiff) {

Workbook workbook = sheet.getWorkbook();
EvaluationWorkbook evaluationWorkbook = null;
if (workbook instanceof HSSFWorkbook) {
evaluationWorkbook = HSSFEvaluationWorkbook.create((HSSFWorkbook) workbook);
} else if (workbook instanceof XSSFWorkbook) {
evaluationWorkbook = XSSFEvaluationWorkbook.create((XSSFWorkbook) workbook);
}

Ptg[] ptgs = FormulaParser.parse(formula, (FormulaParsingWorkbook)evaluationWorkbook,
FormulaType.CELL, sheet.getWorkbook().getSheetIndex(sheet));

for (int i = 0; i < ptgs.length; i++) {
if (ptgs[i] instanceof RefPtgBase) { // base class for cell references
RefPtgBase ref = (RefPtgBase) ptgs[i];
if (ref.isColRelative())
ref.setColumn(ref.getColumn() + coldiff);
if (ref.isRowRelative())
ref.setRow(ref.getRow() + rowdiff);
}
else if (ptgs[i] instanceof AreaPtgBase) { // base class for range references
AreaPtgBase ref = (AreaPtgBase) ptgs[i];
if (ref.isFirstColRelative())
ref.setFirstColumn(ref.getFirstColumn() + coldiff);
if (ref.isLastColRelative())
ref.setLastColumn(ref.getLastColumn() + coldiff);
if (ref.isFirstRowRelative())
ref.setFirstRow(ref.getFirstRow() + rowdiff);
if (ref.isLastRowRelative())
ref.setLastRow(ref.getLastRow() + rowdiff);
}
}

formula = FormulaRenderer.toFormulaString((FormulaRenderingWorkbook)evaluationWorkbook, ptgs);
return formula;
}

关于java - Apache POI 复制时更新公式引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47594254/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com