Comment définir la valeur de la cellule sur Date et appliquer le format de date Excel par défaut?

101

J'utilise Apache POI depuis un certain temps pour lire des fichiers Excel 2003 existants par programmation. Maintenant, j'ai une nouvelle exigence pour créer des fichiers .xls entiers en mémoire (toujours en utilisant Apache POI), puis les écrire dans un fichier à la fin. Le seul problème qui me gêne est la manipulation des cellules avec des dates.

Considérez le code suivant:

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

Lorsque j'écris le classeur contenant cette cellule dans un fichier et que je l'ouvre avec Excel, la cellule s'affiche sous forme de nombre. Oui, je me rends compte qu'Excel stocke ses «dates» sous forme de nombre de jours depuis le 1er janvier 1900 et c'est ce que représente le nombre dans la cellule.

QUESTION: Quels appels d'API puis-je utiliser dans POI pour lui indiquer que je souhaite qu'un format de date par défaut soit appliqué à ma cellule de date?

Idéalement, je souhaite que la cellule de la feuille de calcul soit affichée avec le même format de date par défaut qu'Excel l'aurait attribué si un utilisateur avait ouvert manuellement la feuille de calcul dans Excel et tapé une valeur de cellule qu'Excel reconnaissait comme étant une date.

Jim Tough
la source

Réponses:

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
la source
21
Merci ninja, cela fonctionne pour moi. Un commentaire pour les autres qui ont besoin de le faire. Il existe une classe POI nommée BuiltinFormatsqui répertorie tous les formats standard (pas seulement les formats de date) connus d'Excel. Je m'en tiens à l'un de ceux à utiliser comme paramètre de la getFormat()méthode indiquée dans l'extrait de code ci-dessus.
Jim Tough
La partie importante est dans les commentaires du lien: nous stylisons la deuxième cellule comme une date (et une heure). Il est important de créer un nouveau style de cellule à partir du classeur, sinon vous pouvez finir par modifier le style intégré et affecter non seulement cette cellule, mais d'autres cellules.
CGK
Merci, @ninja. Savez-vous pourquoi getCreationHelper()est nécessaire? Je travaille actuellement avec Mule pour générer un fichier de sortie Excel et j'ai pu utiliser le createDataFormat()sans l'aide de création et généré un fichier Excel dans mon test. Y a-t-il un inconvénient à ne pas l'utiliser? Merci!
Rashiki
@Rashiki Cette réponse a été publiée il y a 6 ans. Je suppose que l'API du POI Apache a changé pendant ce temps. Ma réponse à votre question est `` Non, il n'y a pas d'inconvénient (si cela fonctionne comme prévu) ''
ninja
Je ne vois aucun format pour mm/dd/yyyy. Lorsque j'utilise un autre format, Excel affiche une erreur File error, some number formats may have been lost, il affiche le Datetype dans Excel. Je n'ai aucune idée de comment cela peut être résolu.
akash
24

Pour définir le type Excel par défaut Date (défini par défaut sur les paramètres régionaux du système d'exploitation / -> c'est-à-dire que xlsx aura un aspect différent lorsqu'il est ouvert par une personne allemande ou britannique / et signalé par un astérisque si vous le choisissez dans le sélecteur de format de cellule d'Excel), vous devez:

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

Je l'ai fait avec xlsx et cela a bien fonctionné.

BlondCode
la source
2
Absolument d'accord sur le commentaire de Fiffy. J'ai une seule question. Quelle est la meilleure approche. Fiez-vous à la valeur courte dataFormat (14) ou à la valeur de chaîne ("m / j / yy"). Quelle est vraiment la valeur constante qui décrit le format de date standard dans Excel? DataFormat.getFormat () a à la fois une chaîne et une valeur courte comme paramètre.
Miklos Krivan
Miklos, je ne sais pas comment fonctionne la solution de valeur de chaîne. Je serais heureux si quelqu'un pouvait dire si cela montre également le "format de date par défaut différent basé sur la langue" dans Excels avec différentes langues également.
BlondCode
13

Cet exemple concerne l'utilisation des types de fichiers .xlsx. Cet exemple provient d'une page .jsp utilisée pour créer une feuille de calcul .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);
M. Port St Joe
la source
1

J'écris ma réponse ici parce qu'elle peut être utile à d'autres lecteurs, qui pourraient avoir une exigence légèrement différente de celle du questionneur ici.

Je prépare un modèle .xlsx; toutes les cellules qui seront remplies avec des dates, sont déjà formatées comme cellules de date (en utilisant Excel).

J'ouvre le modèle .xlsx en utilisant Apache POI, puis j'écris simplement la date dans la cellule, et cela fonctionne.

Dans l'exemple ci-dessous, la cellule A1 est déjà formatée à partir d'Excel avec le format [$-409]mmm yyyyet le code Java est utilisé uniquement pour remplir la cellule.

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

À l'ouverture d'Excel, la date est formatée correctement.

gordon613
la source
0

Cet exemple de code peut être utilisé pour modifier le format de date. Ici, je veux passer de aaaa-MM-jj à jj-MM-aaaa. Voici la posposition de la colonne.

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
la source
0

Pour connaître la chaîne de format utilisée par Excel sans avoir à la deviner: créez un fichier Excel, écrivez une date dans la cellule A1 et formatez-la comme vous le souhaitez. Exécutez ensuite les lignes suivantes:

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

Ensuite, copiez-collez la chaîne résultante, supprimez les contre-obliques (par exemple d/m/yy\ h\.mm;@devient d/m/yy h.mm;@) et utilisez-la dans le 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
la source