Как установить значение ячейки в значение Дата и применить формат даты Excel по умолчанию?

102

Некоторое время я использую Apache POI для программного чтения существующих файлов Excel 2003. Теперь у меня есть новое требование - создавать целые файлы .xls в памяти (все еще используя Apache POI), а затем записывать их в файл в конце. Единственная проблема, стоящая на моем пути, - это обработка ячеек с датами.

Рассмотрим следующий код:

Date myDate = new Date();
HSSFCell myCell;
// code that assigns a cell from an HSSFSheet to 'myCell' would go here...
myCell.setCellValue(myDate);

Когда я записываю книгу, содержащую эту ячейку, в файл и открываю его в Excel, ячейка отображается в виде числа. Да, я понимаю, что Excel хранит свои «даты» как количество дней с 1 января 1900 года, и это то, что представляет собой число в ячейке.

ВОПРОС: Какие вызовы API я могу использовать в POI, чтобы сообщить ему, что я хочу, чтобы к моей ячейке даты применялся формат даты по умолчанию?

В идеале я хочу, чтобы ячейка электронной таблицы отображалась с тем же форматом даты по умолчанию, который Excel назначил бы ей, если бы пользователь вручную открыл электронную таблицу в Excel и ввел значение ячейки, которое Excel распознало как дату.

Джим Таф
источник

Ответы:

174

http://poi.apache.org/spreadsheet/quick-guide.html#CreateDateCells

CellStyle cellStyle = wb.createCellStyle();
CreationHelper createHelper = wb.getCreationHelper();
cellStyle.setDataFormat(
    createHelper.createDataFormat().getFormat("m/d/yy h:mm"));
cell = row.createCell(1);
cell.setCellValue(new Date());
cell.setCellStyle(cellStyle);
ниндзя
источник
21
Спасибо ниндзя, у меня это работает. Один комментарий для тех, кому это нужно. Существует класс POI с именем, в BuiltinFormatsкотором перечислены все стандартные форматы (а не только форматы даты), известные Excel. Я использую один из них в качестве параметра getFormat()метода, показанного в приведенном выше фрагменте.
Джим Таф
Важная часть находится в комментариях к ссылке: мы стилизуем вторую ячейку как дату (и время). Важно создать новый стиль ячейки из книги, иначе вы можете изменить встроенный стиль и повлиять не только на эту ячейку, но и на другие ячейки.
CGK
Спасибо, @ninja. Вы знаете, зачем getCreationHelper()это нужно? Я работаю с Mule прямо сейчас, чтобы создать выходной файл Excel, и я действительно смог использовать его createDataFormat()без помощника по созданию и сгенерировал файл Excel в моем тесте. Есть ли недостаток в том, чтобы не использовать его? Спасибо!
Rashiki
@Rashiki Этот ответ был опубликован 6 лет назад. Я предполагаю, что API Apache POI изменился за это время. Мой ответ на ваш вопрос: «Нет, недостатков нет (если он работает
ниндзя
Я не вижу формата для mm/dd/yyyy. Когда я использую любой другой формат, Excel отображает ошибку File error, some number formats may have been lost, он отображает Dateтип в excel. Я понятия не имею, как это можно исправить.
Акаш
24

Чтобы установить тип Excel по умолчанию Дата (по умолчанию локаль уровня ОС / -> т.е. xlsx будет выглядеть по-другому при открытии немецким или британским лицом / и помечен звездочкой, если вы выберете его в средстве выбора формата ячеек Excel), вам следует:

    CellStyle cellStyle = xssfWorkbook.createCellStyle();
    cellStyle.setDataFormat((short)14);
    cell.setCellStyle(cellStyle);

Я сделал это с помощью xlsx, и он работал нормально.

BlondCode
источник
2
Абсолютно согласен с комментарием Фиффи. У меня только один вопрос. Какой лучший подход. Положитесь на короткое значение dataFormat (14) или строковое значение («m / d / yy»). Какое на самом деле постоянное значение описывает стандартный формат даты в Excel? DataFormat.getFormat () имеет как параметр со строкой, так и с коротким значением.
Миклош Криван
Миклос, я не знаю, как работает решение для строкового значения. Я был бы рад, если бы кто-нибудь мог прокомментировать, показывает ли это также «другой формат даты по умолчанию на основе языка» в Excel с разными языками.
BlondCode
13

Этот пример предназначен для работы с типами файлов .xlsx. Этот пример взят из страницы .jsp, используемой для создания электронной таблицы .xslx.

import org.apache.poi.xssf.usermodel.*; //import needed

XSSFWorkbook  wb = new XSSFWorkbook ();  // Create workbook
XSSFSheet sheet = wb.createSheet();      // Create spreadsheet in workbook
XSSFRow row = sheet.createRow(rowIndex); // Create the row in the spreadsheet


//1. Create the date cell style
XSSFCreationHelper createHelper = wb.getCreationHelper();
XSSFCellStyle cellStyle         = wb.createCellStyle();
cellStyle.setDataFormat(
createHelper.createDataFormat().getFormat("MMMM dd, yyyy")); 

//2. Apply the Date cell style to a cell

//This example sets the first cell in the row using the date cell style
cell = row.createCell(0);
cell.setCellValue(new Date());
cell.setCellStyle(cellStyle);
Г-н Порт-Сент-Джо
источник
1

Я пишу здесь свой ответ, потому что он может быть полезен другим читателям, у которых могут быть несколько иные требования, чем у спрашивающего здесь.

Готовлю шаблон .xlsx; все ячейки, которые будут заполнены датами, уже отформатированы как ячейки даты (с помощью Excel).

Я открываю шаблон .xlsx с помощью Apache POI, а затем просто записываю дату в ячейку, и все работает.

В приведенном ниже примере ячейка A1 уже отформатирована в Excel с использованием этого формата [$-409]mmm yyyy, а код Java используется только для заполнения ячейки.

FileInputStream inputStream = new FileInputStream(new File("Path to .xlsx template"));
Workbook wb = new XSSFWorkbook(inputStream);
Date date1=new Date();
Sheet xlsMainTable = (Sheet) wb.getSheetAt(0);
Row myRow= CellUtil.getRow(0, xlsMainTable);
CellUtil.getCell(myRow, 0).setCellValue(date1);

Когда открывается Excel, дата отображается правильно.

gordon613
источник
0

Этот пример кода можно использовать для изменения формата даты. Здесь я хочу изменить с yyyy-MM-dd на dd-MM-yyyy. Вот posположение столбца.

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

class Test{ 
public static void main( String[] args )
{
String input="D:\\somefolder\\somefile.xlsx";
String output="D:\\somefolder\\someoutfile.xlsx"
FileInputStream file = new FileInputStream(new File(input));
XSSFWorkbook workbook = new XSSFWorkbook(file);
XSSFSheet sheet = workbook.getSheetAt(0);
Iterator<Row> iterator = sheet.iterator();
Cell cell = null;
Row row=null;
row=iterator.next();
int pos=5; // 5th column is date.
while(iterator.hasNext())
{
    row=iterator.next();

    cell=row.getCell(pos-1);
    //CellStyle cellStyle = wb.createCellStyle();
    XSSFCellStyle cellStyle = (XSSFCellStyle)cell.getCellStyle();
    CreationHelper createHelper = wb.getCreationHelper();
    cellStyle.setDataFormat(
        createHelper.createDataFormat().getFormat("dd-MM-yyyy"));
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Date d=null;
    try {
        d= sdf.parse(cell.getStringCellValue());
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        d=null;
        e.printStackTrace();
        continue;
    }
    cell.setCellValue(d);
    cell.setCellStyle(cellStyle);
   }

file.close();
FileOutputStream outFile =new FileOutputStream(new File(output));
workbook.write(outFile);
workbook.close();
outFile.close();
}}
Гаурав Харе
источник
0

Чтобы узнать строку формата, используемую Excel, не угадывая ее: создайте файл Excel, напишите дату в ячейке A1 и отформатируйте ее по своему усмотрению. Затем запустите следующие строки:

FileInputStream fileIn = new FileInputStream("test.xlsx");
Workbook workbook = WorkbookFactory.create(fileIn);
CellStyle cellStyle = workbook.getSheetAt(0).getRow(0).getCell(0).getCellStyle();
String styleString = cellStyle.getDataFormatString();
System.out.println(styleString);

Затем скопируйте и вставьте полученную строку, удалите обратную косую черту (например, d/m/yy\ h\.mm;@становится d/m/yy h.mm;@) и используйте ее в коде http://poi.apache.org/spreadsheet/quick-guide.html#CreateDateCells :

CellStyle cellStyle = wb.createCellStyle();
CreationHelper createHelper = wb.getCreationHelper();
cellStyle.setDataFormat(createHelper.createDataFormat().getFormat("d/m/yy h.mm;@"));
cell = row.createCell(1);
cell.setCellValue(new Date());
cell.setCellStyle(cellStyle);
Люк
источник