我正在使用Apache和Java操作.xls文件。
我正在尝试创建一个新的单元格,它的内容是公式的结果,就好像用户复制/粘贴了公式一样(我称之为“相对”方式,与“绝对”方式相反)。
为了让我更清楚,这里有一个简单的例子:
如果我将公式复制到excel下的A4单元格,它将变为"=A2+B2"
:excel正在动态调整公式的内容。
不幸的是,我无法通过编程获得相同的结果。我找到的唯一解决方案就是对公式进行标记化,然后自己来做这些繁琐的工作,但我真的很怀疑这是否应该这样做。我在指南或API中找不到我想要的东西。
有没有更简单的方法来解决这个问题?如果是这样的话,你能给我指个方向吗?
诚挚的问候,
Nils
发布于 2014-03-12 22:03:12
在我看来,user2622016是正确的,除了他的解决方案只管理单元格引用,而不是区域引用(例如,它不适用于=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);
}
我仍然不知道我是否对所有的单元格公式都是正确的,但它对我来说是有效的,快速可靠。
发布于 2009-10-28 20:15:08
我也认为没有一种简单的方法可以做到这一点。
即使是POI网站上的HSSF and XSSD examples,例如TimesheetDemo,也会手动构建公式。例如在110行附近
String ref = (char)('A' + j) + "3:" + (char)('A' + j) + "12";
cell.setCellFormula("SUM(" + ref + ")");
发布于 2013-07-30 21:46:54
我查看了FormulaEvaluator类,发现了一些可以为我们做这项工作的POI内部类。
FormulaParser,它将字符串解析为"parse things“数组:
String formula = cell.getCellFormula();
XSSFEvaluationWorkbook workbookWrapper =
XSSFEvaluationWorkbook.create((XSSFWorkbook) workbook);
/* parse formula */
Ptg[] ptgs = FormulaParser.parse(formula, workbookWrapper,
FormulaType.CELL, 0 /*sheet index*/ );
ptgs现在是我们用反向波兰语表示的公式。现在遍历所有元素,并根据需要逐个修改引用:
/* re-calculate cell references */
for( Ptg ptg : ptgs )
if( ptg instanceof RefPtgBase ) //base class for cell reference "things"
{
RefPtgBase ref = (RefPtgBase)ptg;
if( ref.isColRelative() )
ref.setColumn( ref.getColumn() + 0 );
if( ref.isRowRelative() )
ref.setRow( ref.getRow() + 1 );
}
现在就可以将"parse thing“返回给String了:
formula = FormulaRenderer.toFormulaString(workbookWrapper, ptgs);
cell.setCellFormula( formula );
https://stackoverflow.com/questions/1636759
复制相似问题