在评估引用另一个工作簿的公式时收到 "Book not linked"
Receiving "Book not linked" when evaluating formular which references another workbook
我有两本工作簿:
- map.xlsx
- req.xlsx
map.xlsx有一个sheet映射,req.xlsx有一个sheetABC请求.
我想在 map.xlsx 中插入并计算一个引用 req.xlsx 的公式。根据POI Documentation我使用下面的代码。
FormulaEvaluator mapWbEvaluator = mapWb.getCreationHelper().createFormulaEvaluator();
FormulaEvaluator reqWbEvaluator = reqWb.getCreationHelper().createFormulaEvaluator();
Map<String, FormulaEvaluator> evalMap = new HashMap<>();
evalMap.put("map.xlsx", mapWbEvaluator);
evalMap.put("req.xlsx", reqWbEvaluator);
mapWbEvaluator.setupReferencedWorkbooks(evalMap);
Sheet mapSheet = mapWb.getSheet("Mapping");
CellReference tgtRef = new CellReference("A25");
Cell tgtCell = mapSheet.getRow(tgtRef.getRow()).getCell(tgtRef.getCol());
tgtCell.setCellFormula("IF('[req.xlsx]ABC Request'!R28,1,2)");
CellValue cellVal = mapWbEvaluator.evaluate(tgtCell);
执行最后一行时,我收到以下异常:
Exception in thread "main" java.lang.RuntimeException: Book not linked
for filename req.xlsx at
org.apache.poi.xssf.usermodel.BaseXSSFEvaluationWorkbook.resolveBookIndex(BaseXSSFEvaluationWorkbook.java:135)
知道出了什么问题吗?我错过了什么吗?
FormulaEvaluator.setupReferencedWorkbooks
只告诉评估者 linked 工作簿在哪里。它不 link 他们。它们必须已经 link 编辑在主工作簿中(主计算器 mapWbEvaluator
来自的工作簿)。
另外 tgtCell.setCellFormula("IF('[req.xlsx]ABC Request'!R28,1,2)");
不会 link 工作簿。它只将该公式设置到单元格中。但是 req.xlsx
必须使用外部 links table 在 map.xlsx
中编辑 link。在那个外部 links table 中,link 得到一个索引,例如 1
,然后内部存储的公式将是 IF('[1]ABC Request'!R28,1,2)
。 1
指向外部 links table,然后 links 指向 req.xlsx
。
Apache poi
不提供创建或更改外部 links table。有 ExternalLinksTable,但只有在创建 apache poi
XSSFWorkbook
时才会被读取。没有什么可以为工作簿创建一个新的外部links table。并且 ExternalLinksTable
不提供添加新外部 links 的方法。
在 中,我展示了一个使用低级方法创建外部 links table 到 link 两个 *.xlsx
工作簿的示例.在这种情况下,从 linked 工作簿中获取图表数据。但是从 linked 工作簿中获取单元格数据的问题是一样的。
因此,要么您会为该代码而烦恼并了解在两个工作簿之间创建外部 link 需要做什么,或者您将等到 apache poi
提供高级功能类.
我有两本工作簿:
- map.xlsx
- req.xlsx
map.xlsx有一个sheet映射,req.xlsx有一个sheetABC请求.
我想在 map.xlsx 中插入并计算一个引用 req.xlsx 的公式。根据POI Documentation我使用下面的代码。
FormulaEvaluator mapWbEvaluator = mapWb.getCreationHelper().createFormulaEvaluator();
FormulaEvaluator reqWbEvaluator = reqWb.getCreationHelper().createFormulaEvaluator();
Map<String, FormulaEvaluator> evalMap = new HashMap<>();
evalMap.put("map.xlsx", mapWbEvaluator);
evalMap.put("req.xlsx", reqWbEvaluator);
mapWbEvaluator.setupReferencedWorkbooks(evalMap);
Sheet mapSheet = mapWb.getSheet("Mapping");
CellReference tgtRef = new CellReference("A25");
Cell tgtCell = mapSheet.getRow(tgtRef.getRow()).getCell(tgtRef.getCol());
tgtCell.setCellFormula("IF('[req.xlsx]ABC Request'!R28,1,2)");
CellValue cellVal = mapWbEvaluator.evaluate(tgtCell);
执行最后一行时,我收到以下异常:
Exception in thread "main" java.lang.RuntimeException: Book not linked for filename req.xlsx at org.apache.poi.xssf.usermodel.BaseXSSFEvaluationWorkbook.resolveBookIndex(BaseXSSFEvaluationWorkbook.java:135)
知道出了什么问题吗?我错过了什么吗?
FormulaEvaluator.setupReferencedWorkbooks
只告诉评估者 linked 工作簿在哪里。它不 link 他们。它们必须已经 link 编辑在主工作簿中(主计算器 mapWbEvaluator
来自的工作簿)。
另外 tgtCell.setCellFormula("IF('[req.xlsx]ABC Request'!R28,1,2)");
不会 link 工作簿。它只将该公式设置到单元格中。但是 req.xlsx
必须使用外部 links table 在 map.xlsx
中编辑 link。在那个外部 links table 中,link 得到一个索引,例如 1
,然后内部存储的公式将是 IF('[1]ABC Request'!R28,1,2)
。 1
指向外部 links table,然后 links 指向 req.xlsx
。
Apache poi
不提供创建或更改外部 links table。有 ExternalLinksTable,但只有在创建 apache poi
XSSFWorkbook
时才会被读取。没有什么可以为工作簿创建一个新的外部links table。并且 ExternalLinksTable
不提供添加新外部 links 的方法。
在 *.xlsx
工作簿的示例.在这种情况下,从 linked 工作簿中获取图表数据。但是从 linked 工作簿中获取单元格数据的问题是一样的。
因此,要么您会为该代码而烦恼并了解在两个工作簿之间创建外部 link 需要做什么,或者您将等到 apache poi
提供高级功能类.