Apache POI: немецкий формат ячеек в ячейке с конкатенированной строкой

У меня есть файл Excel- (xlsx-) с двумя ячейками:

  • A1 - это числовое значение "5,3".
  • B1 - это формула = "Число:" & A1

Когда я открываю этот Excel-файл в немецком LibreOffice или Excel, они оба показывают мне содержимое ячейки с разделителем-запятой:

  • A1: 5,3
  • B1: Число: 5,3

Когда я читаю содержимое с помощью Apache POI (версия 3.17; new DataFormatter(Locale.GERMAN).formatCellValue(cell, formulaEvaluator)), числовая ячейка A1 правильно отформатирована как «5,3», но объединенная ячейка B1 неожиданно форматируется точкой в ​​качестве разделителя.

Вот мой пример кода:

import java.io.File;
import java.util.Locale;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

public class MiniPoiTest {

  public static void main(String[] args) throws Exception {
    // doesn't change anything
    // LocaleUtil.setUserLocale(Locale.GERMAN);

    // read workbook
    File xlsxFile = new File("string-concat.xlsx");
    Workbook workbook = WorkbookFactory.create(xlsxFile);
    FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
    formulaEvaluator.clearAllCachedResultValues();
    Sheet sheet = workbook.getSheetAt(0);

    // read two cells
    Row row = sheet.getRow(0);
    Cell numericCell = row.getCell(0);
    Cell concatenatedCell = row.getCell(1);

    // print numeric cell
    String numericCellValue = new DataFormatter(Locale.GERMAN).formatCellValue(numericCell,
            formulaEvaluator);
    System.out.println("Value in " + numericCell.getAddress().formatAsString()
            + " (numeric cell): '" + numericCellValue + "'");

    // print concatenated cell
    String concatenatedCellValue = new DataFormatter(Locale.GERMAN)
            .formatCellValue(concatenatedCell, formulaEvaluator);
    System.out.println("Value in " + concatenatedCell.getAddress().formatAsString()
            + " (concatenated cell): '" + concatenatedCellValue + "'");
    System.out.println("Formula in " + concatenatedCell.getAddress().formatAsString()
            + " (concatenated cell): '" + concatenatedCell.getCellFormula() + "'");
  }

}

Результат при выполнении примера кода:

Value in A1 (numeric cell): '5,3'
Value in B1 (concatenated cell): 'Number: 5.3'
Formula in B1 (concatenated cell): '"Number: "&A1'

Есть ли какой-нибудь трюк, чтобы объединенное содержимое B1 также было отформатировано с немецким числовым разделителем ("Number: 5,3")?

Что происходит если вы скажете Apache POI использовать немецкий язык для всего перед проведением оценки?

Gagravarr 05.09.2018 10:09

Вызов LocaleUtil.setUserLocale(Locale.GERMAN) ничего не меняет. Это тот же результат: «Число: 5,3».

S. Doe 05.09.2018 11:45

Проблема в том, что DataFormatter может использовать разные локали, а FormulaEvaluator - нет. И DataFormatter не будет менять точку на запятую, когда получит строку от FormulaEvaluator. FormulaEvaluator преобразует числа в строки с помощью NumberToTextConverter. Это всегда будет использовать точку в качестве десятичного разделителя, потому что это жестко запрограммировано там. Так что здесь нет решения, пока apache poi не сделает FormulaEvaluator также способным использовать другие локали.

Axel Richter 05.09.2018 17:43

@Axel Richter: Спасибо за подробный ответ. Тогда я попробую заменить символы-разделители на формулы Excel.

S. Doe 05.09.2018 22:53
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
4
497
0

Другие вопросы по теме