Jak ustawić wartość komórki na datę i zastosować domyślny format daty programu Excel?

101

Od jakiegoś czasu używam Apache POI do programowego odczytywania istniejących plików Excel 2003. Teraz mam nowe wymaganie, aby tworzyć całe pliki .xls w pamięci (nadal używam Apache POI), a następnie zapisywać je do pliku na końcu. Jedynym problemem stojącym na mojej drodze jest obsługa komórek z datami.

Rozważ następujący kod:

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

Kiedy piszę skoroszyt zawierający tę komórkę do pliku i otwieram go w programie Excel, komórka jest wyświetlana jako liczba. Tak, zdaję sobie sprawę, że Excel przechowuje swoje „daty” jako liczbę dni od 1 stycznia 1900 r. I to właśnie reprezentuje liczba w komórce.

PYTANIE: Jakich wywołań API mogę użyć w POI, aby powiedzieć, że chcę zastosować domyślny format daty w mojej komórce daty?

Idealnie byłoby, gdyby komórka arkusza kalkulacyjnego była wyświetlana z tym samym domyślnym formatem daty, jaki przypisałby jej program Excel, gdyby użytkownik ręcznie otworzył arkusz kalkulacyjny w programie Excel i wpisał wartość komórki, którą program Excel rozpoznał jako datę.

Jim Tough
źródło

Odpowiedzi:

173

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);
ninja
źródło
21
Dzięki ninja, to działa dla mnie. Jeden komentarz dla innych, którzy muszą to zrobić. Istnieje klasa POI o nazwie, BuiltinFormatsktóra zawiera listę wszystkich standardowych formatów (nie tylko formatów dat) znanych w programie Excel. Trzymam się jednego z nich, aby użyć go jako mojego parametru do getFormat()metody pokazanej w powyższym fragmencie.
Jim Tough
Ważna część znajduje się w komentarzach do linku: stylizujemy drugą komórkę jako datę (i godzinę). Ważne jest, aby utworzyć nowy styl komórki ze skoroszytu, w przeciwnym razie możesz zmodyfikować styl wbudowany i wpłynąć nie tylko na tę komórkę, ale także na inne komórki.
CGK,
Dzięki, @ninja. Czy wiesz, dlaczego getCreationHelper()jest potrzebny? Pracuję teraz z Mule, aby wygenerować plik wyjściowy Excel i faktycznie mogłem użyć programu createDataFormat()bez pomocnika tworzenia i wygenerowałem plik Excel w moim teście. Czy jest wada, aby go nie używać? Dzięki!
Rashiki
@Rashiki Ta odpowiedź została opublikowana 6 lat temu. Myślę, że API Apache POI zmieniło się w tym czasie. Moja odpowiedź na twoje pytanie brzmi:
ninja
Nie widzę żadnego formatu dla mm/dd/yyyy. Kiedy używam innego formatu, program Excel wyświetla błąd File error, some number formats may have been lost, wyświetla Datetyp w programie Excel. Nie mam pojęcia, jak można to naprawić.
akash
24

Aby ustawić domyślny typ Excela Data (domyślnie ustawienie regionalne poziomu systemu operacyjnego / -> tj. Xlsx będzie wyglądać inaczej, gdy zostanie otwarty przez osobę z Niemiec lub Wielkiej Brytanii / i oznaczony gwiazdką, jeśli wybierzesz go w selektorze formatu komórek programu Excel), należy:

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

Zrobiłem to z xlsx i działało dobrze.

BlondCode
źródło
2
Całkowicie zgodził się z komentarzem Fiffy. Mam tylko jedno pytanie. Jakie jest najlepsze podejście. Polegaj na krótkiej wartości dataFormat (14) lub wartości ciągu („m / d / rr”). Jaka jest naprawdę stała wartość opisująca standardowy format daty w programie Excel? DataFormat.getFormat () zawiera zarówno ciąg znaków, jak i krótką wartość jako parametr.
Miklos Krivan
Miklos, nie wiem, jak działa rozwiązanie wartości ciągu. Byłbym zadowolony, gdyby ktoś mógł skomentować, czy to również pokazuje „inny domyślny format daty oparty na języku” w programie Excel z różnymi językami.
BlondCode
13

Ten przykład dotyczy pracy z typami plików .xlsx. Ten przykład pochodzi ze strony .jsp używanej do tworzenia arkusza kalkulacyjnego .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);
Pan Port St Joe
źródło
1

Piszę tutaj swoją odpowiedź, ponieważ może być pomocna dla innych czytelników, którzy mogą mieć nieco inne wymagania niż pytający tutaj.

Przygotowuję szablon .xlsx; wszystkie komórki, które zostaną wypełnione datami, są już sformatowane jako komórki daty (w programie Excel).

Otwieram szablon .xlsx za pomocą Apache POI, a następnie po prostu wpisuję datę do komórki i działa.

W poniższym przykładzie komórka A1 jest już sformatowana w programie Excel za pomocą tego formatu [$-409]mmm yyyy, a kod Java jest używany tylko do wypełnienia komórki.

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);

Po otwarciu programu Excel data jest poprawnie sformatowana.

gordon613
źródło
0

Ten przykładowy kod może służyć do zmiany formatu daty. Tutaj chcę zmienić z rrrr-MM-dd na dd-MM-rrrr. Oto pospozycja kolumny.

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();
}}
Gaurav Khare
źródło
0

Aby poznać ciąg formatu używany przez program Excel bez zgadywania: utwórz plik Excela, napisz datę w komórce A1 i sformatuj ją tak, jak chcesz. Następnie uruchom następujące wiersze:

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);

Następnie skopiuj i wklej wynikowy ciąg, usuń ukośniki odwrotne (na przykład d/m/yy\ h\.mm;@staje się d/m/yy h.mm;@) i użyj go w kodzie 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);
Łukasz
źródło