Wie setze ich den Zellenwert auf Datum und wende das Standard-Excel-Datumsformat an?

101

Ich verwende Apache POI seit einiger Zeit, um vorhandene Excel 2003-Dateien programmgesteuert zu lesen. Jetzt habe ich eine neue Anforderung, ganze XLS-Dateien im Speicher zu erstellen (immer noch mit Apache POI) und sie am Ende in eine Datei zu schreiben. Das einzige Problem, das mir im Weg steht, ist der Umgang mit Zellen mit Datumsangaben.

Betrachten Sie den folgenden Code:

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

Wenn ich die Arbeitsmappe mit dieser Zelle in eine Datei schreibe und sie mit Excel öffne, wird die Zelle als Zahl angezeigt. Ja, mir ist klar, dass Excel seine "Daten" als Anzahl der Tage seit dem 1. Januar 1900 speichert und genau diese Zahl in der Zelle darstellt.

FRAGE: Welche API-Aufrufe kann ich in POI verwenden, um anzugeben, dass ein Standard-Datumsformat auf meine Datumszelle angewendet werden soll?

Idealerweise soll die Tabellenkalkulationszelle mit demselben Standard-Datumsformat angezeigt werden, das Excel zugewiesen hätte, wenn ein Benutzer die Tabelle manuell in Excel geöffnet und einen Zellenwert eingegeben hätte, den Excel als Datum erkannt hat.

Jim Tough
quelle

Antworten:

172

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
quelle
21
Danke Ninja, das funktioniert bei mir. Ein Kommentar für andere, die dies tun müssen. Es gibt eine POI-Klasse mit dem Namen BuiltinFormats, die alle Standardformate (nicht nur Datumsformate) auflistet, die Excel kennt. Ich halte mich an eine davon, die ich als Parameter für die getFormat()im obigen Snippet gezeigte Methode verwenden möchte.
Jim Tough
Der wichtige Teil ist in den Kommentaren des Links: Wir gestalten die zweite Zelle als Datum (und Uhrzeit). Es ist wichtig, einen neuen Zellenstil aus der Arbeitsmappe zu erstellen, da Sie sonst den integrierten Stil ändern und nicht nur diese Zelle, sondern auch andere Zellen beeinflussen können.
CGK
Danke, @ninja. Wissen Sie, warum getCreationHelper()benötigt wird? Ich arbeite gerade mit Mule zusammen, um eine Excel-Ausgabedatei zu generieren. Tatsächlich konnte ich die createDataFormat()ohne den Erstellungshelfer verwenden und in meinem Test eine Excel-Datei generieren. Gibt es einen Nachteil, wenn man es nicht benutzt? Vielen Dank!
Rashiki
@Rashiki Diese Antwort wurde vor 6 Jahren veröffentlicht. Ich vermute, dass sich die API des Apache-POI in dieser Zeit geändert hat. Meine Antwort auf Ihre Frage lautet "Nein, es gibt keinen Nachteil (wenn es wie erwartet funktioniert)"
Ninja
Ich sehe kein Format für mm/dd/yyyy. Wenn ich ein anderes Format verwende, zeigt das Excel einen Fehler an File error, some number formats may have been lost, es zeigt den DateTyp in Excel an. Ich habe keine Ahnung, wie dies behoben werden kann.
Akash
24

Um den Standard-Excel-Typ Datum festzulegen (standardmäßig das Gebietsschema auf Betriebssystemebene / -> dh xlsx sieht anders aus, wenn es von einer deutschen oder britischen Person geöffnet wird / und mit einem Sternchen gekennzeichnet wird, wenn Sie es in der Zellenformatauswahl von Excel auswählen), sollten Sie:

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

Ich habe es mit xlsx gemacht und es hat gut funktioniert.

BlondCode
quelle
2
Absolut einverstanden mit Fiffys Kommentar. Ich habe nur eine Frage. Was ist der beste Ansatz. Verlassen Sie sich auf den dataFormat-Kurzwert (14) oder den Zeichenfolgenwert ("m / t / jj"). Welches ist wirklich der konstante Wert, der das Standard-Datumsformat in Excel beschreibt? DataFormat.getFormat () hat sowohl einen String als auch einen kurzen Wert als Parameter.
Miklos Krivan
Miklos, ich weiß nicht, wie die String-Wert-Lösung funktioniert. Ich würde mich freuen, wenn jemand eine Rückmeldung geben könnte, ob dies auch das "sprachbasierte unterschiedliche Standard-Datumsformat" in Excels mit unterschiedlichen Sprachen anzeigt.
BlondCode
13

Dieses Beispiel dient zum Arbeiten mit XLSX-Dateitypen. Dieses Beispiel stammt von einer .jsp-Seite, die zum Erstellen einer .xslx-Tabelle verwendet wird.

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);
Herr Port St Joe
quelle
1

Ich schreibe meine Antwort hier, weil sie für andere Leser hilfreich sein kann, die möglicherweise eine etwas andere Anforderung haben als der Fragesteller hier.

Ich bereite eine XLSX-Vorlage vor. Alle Zellen, die mit Datumsangaben gefüllt werden, sind bereits als Datumszellen formatiert (mit Excel).

Ich öffne die XLSX-Vorlage mit Apache POI und schreibe dann einfach das Datum in die Zelle, und es funktioniert.

Im folgenden Beispiel ist Zelle A1 bereits in Excel mit dem Format formatiert [$-409]mmm yyyy, und der Java-Code wird nur zum Auffüllen der Zelle verwendet.

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

Beim Öffnen von Excel wird das Datum korrekt formatiert.

gordon613
quelle
0

Mit diesem Codebeispiel kann das Datumsformat geändert werden. Hier möchte ich von JJJJ-MM-TT zu TT-MM-JJJJ wechseln. Hier posist die Position der Spalte.

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
quelle
0

So kennen Sie die von Excel verwendete Formatzeichenfolge, ohne sie erraten zu müssen: Erstellen Sie eine Excel-Datei, schreiben Sie ein Datum in Zelle A1 und formatieren Sie es nach Ihren Wünschen. Führen Sie dann die folgenden Zeilen aus:

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

Kopieren Sie dann die resultierende Zeichenfolge, fügen Sie sie ein, entfernen Sie die Backslashes (z. B. d/m/yy\ h\.mm;@wird d/m/yy h.mm;@) und verwenden Sie sie im Code 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);
Luke
quelle