Java Excel单元格中带有外部引用的FormulaEvaluator.evaluateAll()使用Apache POI返回RuntimeException
在过去的几天里,这让我发疯Java Excel单元格中带有外部引用的FormulaEvaluator.evaluateAll()使用Apache POI返回RuntimeException,java,excel,apache-poi,Java,Excel,Apache Poi,在过去的几天里,这让我发疯 请考虑两个Excel文件: 及 以下是用于计算a.xlsx中单元格的代码,包括对b.xlsx的外部引用 import java.io.FileInputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.apache.poi.ss.usermodel.FormulaEvaluator; import org.apache.poi.x
请考虑两个Excel文件: 及
以下是用于计算a.xlsx中单元格的代码,包括对b.xlsx的外部引用import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class Test {
public static void main(String[] args) {
try {
FileInputStream file1 = new FileInputStream("C:\\Users\\Abid\\Desktop\\a.xlsx");
FileInputStream file2 = new FileInputStream("C:\\Users\\Abid\\Desktop\\b.xlsx");
XSSFWorkbook workbook1 = new XSSFWorkbook(file1);
XSSFWorkbook workbook2 = new XSSFWorkbook(file2);
FormulaEvaluator evaluator1 = workbook1.getCreationHelper().createFormulaEvaluator();
FormulaEvaluator evaluator2 = workbook2.getCreationHelper().createFormulaEvaluator();
Map<String, FormulaEvaluator> workbooks = new HashMap<String, FormulaEvaluator>();
workbooks.put("a.xlsx", evaluator1);
workbooks.put("b.xlsx", evaluator2);
evaluator1.setupReferencedWorkbooks(workbooks);
evaluator1.evaluateAll();
file1.close();
file2.close();
workbook1.close();
workbook2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
它在使用
HSSF
(*.xls)时不会出现问题
但是ApachePOI是一团糟。因此只需调用hssformulaevaluator.evaluateAllFormulaCells(_book)代码>。但是将创建一个新的公式化评估器
,它不在环境中涉及
相反,它应该调用并移交FormulaEvaluator
,该已包含在环境中。但是这个方法是私有的
幸运的是,它没有那么大和独立。因此,我们可以在代码中使用此方法:
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.ss.usermodel.*;
public class TestEvaluateExtRef {
private static void evaluateAllFormulaCells(Workbook wb, FormulaEvaluator evaluator) {
for(int i=0; i<wb.getNumberOfSheets(); i++) {
Sheet sheet = wb.getSheetAt(i);
for(Row r : sheet) {
for (Cell c : r) {
if (c.getCellType() == Cell.CELL_TYPE_FORMULA) {
evaluator.evaluateFormulaCell(c);
}
}
}
}
}
public static void main(String[] args) {
try {
Workbook workbook1 = WorkbookFactory.create(new FileInputStream("a.xlsx"));
Workbook workbook2 = WorkbookFactory.create(new FileInputStream("b.xlsx"));
FormulaEvaluator evaluator1 = workbook1.getCreationHelper().createFormulaEvaluator();
FormulaEvaluator evaluator2 = workbook2.getCreationHelper().createFormulaEvaluator();
Map<String, FormulaEvaluator> workbooks = new HashMap<String, FormulaEvaluator>();
workbooks.put("a.xlsx", evaluator1);
workbooks.put("b.xlsx", evaluator2);
workbook2.getSheetAt(0).getRow(0).getCell(0).setCellValue(new java.util.Random().nextDouble());
evaluator1.setupReferencedWorkbooks(workbooks);
//evaluator1.evaluateAll();
evaluateAllFormulaCells(workbook1, evaluator1);
System.out.println(workbook1.getSheetAt(0).getRow(0).getCell(0));
System.out.println(workbook1.getSheetAt(0).getRow(0).getCell(0).getNumericCellValue());
workbook1.close();
workbook2.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
import java.io.FileInputStream;
导入java.io.IOException;
导入java.util.HashMap;
导入java.util.Map;
导入org.apache.poi.ss.usermodel.*;
公共类TestEvaluateExtRef{
专用静态void evaluateAllFormulaCells(工作簿wb,FormulaEvaluator evaluator){
对于(int i=0;i您需要使用Apache POI 3.15 beta 3或更高版本,或者在2016-08-04上/之后使用svn的夜间构建/构建/git的构建。因为,这是一个XSSF特定的bug,随后已被修复
使用带有修复程序的构建/发行版,在XSSFFormulaEvaluator
上调用evaluateAll()
现在将使用任何已设置的引用工作簿,就像HSSF一直以来所做的那样。我不熟悉apache poi,但我在错误输出中看到了这一点无法解析外部工作簿名称“b.xlsx”。尚未设置工作簿环境。"我确实设置了工作簿环境。是的,我明白了。祝你好运。你使用的是什么版本的Apache POI?如果不是最新版本,升级时会发生什么?我使用的是最新的稳定版本Apache POI 3.14。在这方面HSSF和XSSF之间应该没有区别。如果你能够编写一个小的junit测试来显示问题,并且可以将其上传到POI bugzilla,我很乐意看一看!@Gagravarr:我的解释和我的示例代码非常清楚问题所在。使用evaluator1.evaluator1();
失败。使用evaluateAllFormulaCells(工作簿1,evaluator1)
它可以工作。拥有a.xls
和b.xls
它也可以与evaluator1.evaluateAll()一起工作;
。
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.ss.usermodel.*;
public class TestEvaluateExtRef {
private static void evaluateAllFormulaCells(Workbook wb, FormulaEvaluator evaluator) {
for(int i=0; i<wb.getNumberOfSheets(); i++) {
Sheet sheet = wb.getSheetAt(i);
for(Row r : sheet) {
for (Cell c : r) {
if (c.getCellType() == Cell.CELL_TYPE_FORMULA) {
evaluator.evaluateFormulaCell(c);
}
}
}
}
}
public static void main(String[] args) {
try {
Workbook workbook1 = WorkbookFactory.create(new FileInputStream("a.xlsx"));
Workbook workbook2 = WorkbookFactory.create(new FileInputStream("b.xlsx"));
FormulaEvaluator evaluator1 = workbook1.getCreationHelper().createFormulaEvaluator();
FormulaEvaluator evaluator2 = workbook2.getCreationHelper().createFormulaEvaluator();
Map<String, FormulaEvaluator> workbooks = new HashMap<String, FormulaEvaluator>();
workbooks.put("a.xlsx", evaluator1);
workbooks.put("b.xlsx", evaluator2);
workbook2.getSheetAt(0).getRow(0).getCell(0).setCellValue(new java.util.Random().nextDouble());
evaluator1.setupReferencedWorkbooks(workbooks);
//evaluator1.evaluateAll();
evaluateAllFormulaCells(workbook1, evaluator1);
System.out.println(workbook1.getSheetAt(0).getRow(0).getCell(0));
System.out.println(workbook1.getSheetAt(0).getRow(0).getCell(0).getNumericCellValue());
workbook1.close();
workbook2.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}