Получить значение ячейки, как она была представлена в Excel
9829 просмотра
3 ответа
В настоящее время я работаю над проектом, который читает файл Excel с использованием Apache POI.
Моя задача проста, мне просто нужно получить значение ячейки, которое отображалось в файле Excel. Мне известно о выполнении оператора switch на основе типа ячейки ячейки. Но если данные что-то вроде
9,000.00
POI дает мне, 9000.0
когда я делаю getNumericCellValue()
. Когда я вынуждаю ячейку быть строковым типом и делаю getStringCellValue()
это, то выдает меня 9000
. Что мне нужно, так это данные о том, как они были представлены в Excel.
Я нашел пост, в котором говорится, что нужно использовать DataFormat
класс, но, насколько я понимаю, он требует, чтобы ваш код знал о формате, который имеет ячейка. В моем случае я не знаю формат, который может иметь ячейка.
Итак, как я могу получить значение ячейки, как это было представлено в Excel?
Автор: Bnrdo Источник Размещён: 12.11.2019 09:56Ответы (3)
21 плюса
В Excel некоторые ячейки хранятся в виде строк, но чаще всего в виде чисел, к которым применяются специальные правила форматирования. Вам нужно будет запустить эти правила форматирования для числовых ячеек, чтобы получить строки, которые выглядят так же, как в Excel.
К счастью, в Apache POI есть класс для этого - DataFormatter
Все, что вам нужно сделать, это что-то вроде:
Workbook wb = WorkbookFactory.create(new File("myfile.xls"));
DataFormatter df = new DataFormatter();
Sheet s = wb.getSheetAt(0);
Row r1 = s.getRow(0);
Cell cA1 = r1.getCell(0);
String asItLooksInExcel = df.formatCellValue(cA1);
Неважно, какой тип ячейки, DataFormatter отформатирует его как можно лучше, используя правила, применяемые в Excel.
Автор: Gagravarr Размещён: 16.10.2013 11:121 плюс
На самом деле, невозможно получить точно отформатированное значение ячейки с локалью, определенной при написании ячейки. это связано с наблюдателем локали и тем фактом, что внутренний префикс locale excel никогда не используется повторно при последующем форматировании;
Анализ для POI 3.17 (может измениться, если посмотреть, как компонент выполнен внутри)
например: dateConverted формат стиля ячейки (из CellStyle.getDataFormatString ()) для Locale.US в формате dd MMM гггг чч: мм: сс is:
"[$ -0409] дд ммм гггг чч: мм: сс; @ "где местный префикс внутреннего префикса = [$ -0409]
Он получен из частной статической карты DateFormatConverter.localPrefixes.
Вот некоторый код, чтобы обойти эту проблему:
/**
* Missing method in POI to enable the visualisation asIs of an cell with a
* different locale in a xls document.
*
* @param style
* the cell style localized.
* @return the Locale found using internal locationPrefixes.
*/
private final Locale extractLocaleFromDateCellStyle(final CellStyle style) {
final String reOpenedFormat = style.getDataFormatString();
LOGGER.info("Data Format of CellStyle : " + reOpenedFormat);
Locale locale = getLocaleFromPrefixes(extractPrefixeFromPattern(reOpenedFormat));
LOGGER.info("Found locale : " + locale);
return locale;
}
/**
* Extracts the internal prefix that represent the local of the style.
*
* @param pattern
* the DataFormatString of the cell style.
* @return the prefix found.
*/
private final String extractPrefixeFromPattern(final String pattern) {
Pattern regex = Pattern.compile(REGEX_PREFIX_PATTERN);
Matcher match = regex.matcher(pattern);
if (match.find()) {
LOGGER.info("Found prefix: " + match.group(1));
// return only the prefix
return match.group(1);
}
return null;
}
/**
* Reverse obtain the locale from the internal prefix from
* DateFormatConverter.localePrefixes
private static field.
*
* Uses reflection API.
*
* @param prefixes
* the prefixes
* @return the local corresponding tho the prefixes.
*/
public static Locale getLocaleFromPrefixes(final String prefixes) {
try {
@SuppressWarnings("unchecked")
Map map = getStaticPrivateInternalMapLocalePrefix();
String localPrefix = null;
// find the language_Country value matching the internal excel
// prefix.
for (Map.Entry entry : map.entrySet()) {
LOGGER.info("value : " + entry.getValue() + ", key :"
+ entry.getKey());
if (entry.getValue().equals(prefixes)
&& !StringUtils.isBlank(entry.getKey())) {
localPrefix = entry.getKey();
break;
}
}
// Generate a Locale with language, uppercase(country) info.
LOGGER.info(localPrefix);
if (localPrefix.indexOf('_') > 0) {
String[] languageCountry = localPrefix.split("_");
return new Locale(languageCountry[0],
StringUtils.defaultString(languageCountry[1]
.toUpperCase()));
}
// nothing found.
return null;
// factorized the multiples exceptions.
} catch (Exception e) {
throw new UnsupportedOperationException(e);
}
}
/**
* gets the internal code map for locale used by Excel.
*
* @return the internal map.
* @throws NoSuchFieldException
* if the private field name changes.
* @throws IllegalAccessException
* if the accessible is restricted.
*/
private static Map getStaticPrivateInternalMapLocalePrefix()
throws NoSuchFieldException, IllegalAccessException {
// REFLECTION
Class> clazz = DateFormatConverter.class;
Field fieldlocalPrefixes = (Field) clazz
.getDeclaredField(DATE_CONVERTER_PRIVATE_PREFIXES_MAP);
// change from private to public.
fieldlocalPrefixes.setAccessible(true);
@SuppressWarnings("unchecked")
Map map = (Map) fieldlocalPrefixes
.get(clazz);
LOGGER.info("MAP localPrefixes : " + map);
return map;
}
Таким образом, следующий простой код должен сделать свое дело. Обратите внимание, что код не полностью протестирован с нулевыми значениями и зависит от версии POI, которую вы используете, пока они там не изменились. LOCALE OBSERVER MADNESS :)
....
final CellStyle cellStyle = reopenedCell.getCellStyle();
Locale locale = extractLocaleFromDateCellStyle(cellStyle);
LOGGER.info("FOUND LOCAL : " + locale);
// use the same local from the cell style during writing.
DataFormatter df = new DataFormatter(locale);
String reOpenValue = df.formatCellValue(reopenedCell);
С уважением.
Автор: Patrice Rochemont Размещён: 20.08.2018 11:130 плюса
Используйте CellType, вы можете проверить все
if (cellValue.getCellType() == Cell.CELL_TYPE_NUMERIC)
// cellValue является числовым
if (cellValue.getCellType() == Cell.CELL_TYPE_STRING)
// cellValue является строкой
дата также указывается как числовое значение, в то время проверяйте, является ли данная ячейка датой или нет с помощью dateUtil.
if (DateUtil.isCellDateFormatted(cellData))
после того, как вы можете конвертировать значение ячейки в дату
Автор: newuser Размещён: 16.10.2013 10:55Вопросы из категории :
- java В чем разница между int и Integer в Java и C #?
- java Как я могу определить IP моего маршрутизатора / шлюза в Java?
- java Каков наилучший способ проверки XML-файла по сравнению с XSD-файлом?
- java Как округлить результат целочисленного деления?
- java Преобразование списка <Integer> в список <String>
- java Почему я не могу объявить статические методы в интерфейсе?
- java Библиотека Java SWIFT
- java Выключение компьютера
- java Как я могу воспроизвести звук на Java?
- java Когда выбирать отмеченные и непроверенные исключения
- apache-poi Отрицательные стили сотовой стоимости в Apache POI
- apache-poi Apache POI xls столбец Удалить
- apache-poi Как получить цвет фона (Java Apache POI HSSF) для данной ячейки?
- apache-poi Поиск последней строки в таблице Excel
- apache-poi Как читать ячейки Excel, имеющие нулевые значения тоже в Java ...?
- apache-poi Как прочитать ячейку Excel, имеющую Date с Apache POI?
- apache-poi Создание отчетов Excel путем программирования из шаблонов
- apache-poi Неверная подпись заголовка; IOException с Apache POI в документе Excel
- apache-poi Как получить значение Cell A1 (Cell Address), используя apache poi 3.6
- apache-poi Как получить значение пустой ячейки Excel в Apache POI?