Формула Java POI XSSF VLookup
Я пытаюсь поставить простую формулу VLookup в моем ".xlsx " файл с использованием Java и Apache POI.
Эта формула имеет внешнюю ссылку, и это не работает для меня.
поэтому, чтобы дать вам более подробную информацию, я использую poi и poi-ooxml версии 3.13 и excel 2007.
Я помещаю формулу в ячейку таким образом (где ячейка-это ячейка):
cell.setCellType(Cell.CELL_TYPE_FORMULA);
cell.setCellFormula("StringContainingFormula");
а затем оцените формулу, я пробовал три разных способа, но не повезло. (ББ XSSFWorkbook).
1
FormulaEvaluator mainWorkbookEvaluator = wb.getCreationHelper().createFormulaEvaluator();
Map<String,FormulaEvaluator> workbooks = new HashMap<String, FormulaEvaluator>();
workbooks.put("SpreadsheetName.xlsx", mainWorkbookEvaluator);
mainWorkbookEvaluator.setupReferencedWorkbooks(workbooks);
mainWorkbookEvaluator.evaluateAll();
2
XSSFEvaluationWorkbook.create(wb);
Workbook nwb = wb;
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
for (Sheet sheet : nwb) {
for (Row r : sheet) {
for (Cell c : r) {
if (c.getCellType() == Cell.CELL_TYPE_FORMULA) {
try {
//evaluator.evaluateFormulaCell(c);
evaluator.evaluate(c);
} catch (Exception e) {
System.out.println("Error occured in 'EvaluateFormulas' : " + e);
}
}
}
}
}
3
XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
проблема в том, что он пишет в файл Excel, а затем при оценке выдает ошибку:
java.ленг.IllegalArgumentException: недопустимый sheetIndex: -1
теперь, если я открою файл Excel, он дает мне предупреждение:
автоматическое обновление ссылок отключено
если я включу содержание, формула показывает результат правильно, и если я ничего не делаю, чем формула, приводящая к #N/A
.
Теперь, если я выберу ячейку с формулой в ней и нажмите "строка формул" и нажмите "Ввод", формула покажет результат.
обновление:
Итак, я отключил предупреждающее сообщение, перейдя в параметры Excel, и он начал давать мне формулу внутри ячейки.
Но, когда я попытался получить значение результата от него, используя
if (cell.getCachedFormulaResultType == Cell.CELL_TYPE_STRING) {
System.out.println("Last evaluated as "" + cell.getRichStringCellValue() + """);
}
он никогда не давал мне getCachedFormulaResultType
as CELL_TYPE_STRING
, оно всегда возвращается CELL_TYPE_NUMERIC
. Он должен возвращать строковое значение. Я экспонирую URL и другое значение (слова, разделенные "|" - "кошка|собака|птица").
Я ценю любую помощь / предложение.
3 ответов
Ну, кажется, это работает. Вы должны относиться к excel мягко; это намного счастливее, если вы открываете сначала внешнюю книгу, а затем основную книгу. Если вы этого не сделаете, это даст сообщение о небезопасных ссылках, но кроме этого, все кажется в порядке. Оценщик работает только с одиночными ячейками,поэтому вам придется выполнить цикл, если вы хотите пересчитать всю электронную таблицу. Кроме того, внешняя ссылка должна быть уже связана excel,POI
еще не реализовал эту функцию. Вот что я вложил в github:
// Open workbooks
Path pathBook1 = Paths.get("c:/users/karl/scsb/Vlookup/Book1.xlsx");
InputStream is = Files.newInputStream(pathBook1);
XSSFWorkbook book1 = new XSSFWorkbook(is);
// Add Linked Cell
// The workbook must already have been linked to Book2.xlsx by Excel
// The linkExternalWorkbook has not yet been implemented: SEE BUG #57184
Cell cell = book1.getSheetAt(0).createRow(2).createCell(0);
cell.setCellFormula("A2+[Book2.xlsx]Sheet1!A1");
// Create evaluator after the new cell has been added.
FormulaEvaluator mainEvaluator = book1.getCreationHelper().createFormulaEvaluator();
XSSFWorkbook book2 = new XSSFWorkbook("c:/users/karl/scsb/Vlookup/Book2.xlsx");
Map<String, FormulaEvaluator> workbooks = new HashMap<String, FormulaEvaluator>();
workbooks.put("Book1.xlsx", mainEvaluator);
workbooks.put("Book2.xlsx", book2.getCreationHelper().createFormulaEvaluator());
mainEvaluator.setupReferencedWorkbooks(workbooks);
// mainEvaluator.evaluateAll(); // doesn't work.
// XSSFFormulaEvaluator.evaluateAllFormulaCells(book1); // doesn't work.
mainEvaluator.evaluateFormulaCell(cell);
System.out.println(cell.getNumericCellValue());
book2.close();
// Close and write workbook 1
is.close();
OutputStream os = Files.newOutputStream(pathBook1);
book1.write(os);
os.close();
book1.close();
в последнее время у меня такая же проблема. Проблема заключалась в том, что с текущим POI нельзя написать документ, добавить формулу в конкретное поле и выполнить оценку формулы на все еще не существующем документе. Трюк, который я использовал для его решения, был:
- запишите все данные и формулы в рабочую книгу
- добавить
workbook.setForceFormulaRecalculation(true);
перед закрытием этого документа - напишите и закройте документ
- откройте тот же документ снова и только
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator(); evaluator.evaluateAll();
- пишите и еще раз закрыть!--6-->
Итак, поскольку у меня нет другого варианта, мне пришлось скопировать ссылочные данные в основную книгу (я знаю, что это не очень хорошая идея, если данные огромны), чтобы все работало.
Вот что я сделал:--2-->
- скопировать данные из внешней книги.
- создайте новый рабочий лист в главной книге(в которой вам нужно написать формулу) и вставьте ссылочные данные.
- теперь напишите формулу и на этот раз вместо использования внешней книги вновь созданный рабочий лист (с вставленными данными).
Примечание: вам нужно сначала написать все данные (включая формулы), прежде чем отправиться на оценку формул. - затем откройте книгу для чтения, если вы уже закрыли и оцените все формулы, подобные этому (wb-XSSFWorkbook):
XSSFFormulaEvaluator.evaluateAllFormulaCells (wb);