Como defino o valor da célula para Data e aplico o formato de data padrão do Excel?

101

Eu uso o Apache POI há algum tempo para ler arquivos existentes do Excel 2003 de forma programática. Agora eu tenho um novo requisito para criar arquivos .xls inteiros na memória (ainda usando Apache POI) e, em seguida, gravá-los em um arquivo no final. O único problema no meu caminho é o manuseio de células com datas.

Considere o seguinte código:

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

Quando escrevo a pasta de trabalho que contém essa célula em um arquivo e o abro com o Excel, a célula é exibida como um número. Sim, eu sei que o Excel armazena suas 'datas' como o número de dias desde 1º de janeiro de 1900 e é isso que o número na célula representa.

PERGUNTA: Quais chamadas de API posso usar no POI para informar que desejo um formato de data padrão aplicado à minha célula de data?

O ideal é que a célula da planilha seja exibida com o mesmo formato de data padrão que o Excel teria atribuído se um usuário tivesse aberto manualmente a planilha no Excel e digitado um valor de célula que o Excel reconheceu como uma data.

Jim Tough
fonte

Respostas:

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
fonte
21
Obrigado ninja, isso funciona para mim. Um comentário para outras pessoas que precisam fazer isso. Existe uma classe de POI chamada BuiltinFormatsque lista todos os formatos padrão (não apenas formatos de data) que o Excel conhece. Estou usando um desses para usar como meu parâmetro para o getFormat()método mostrado no trecho acima.
Jim Tough
A parte importante está nos comentários do link: estilizamos a segunda célula como uma data (e hora). É importante criar um novo estilo de célula a partir da pasta de trabalho, caso contrário, você pode acabar modificando o estilo integrado e afetando não apenas esta célula, mas outras células.
CGK
Obrigado, @ninja. Você sabe por que getCreationHelper()é necessário? Estou trabalhando com o Mule agora para gerar um arquivo de saída do Excel e, na verdade, consegui usar o createDataFormat()sem o auxiliar de criação e gerei um arquivo do Excel no meu teste. Existe uma desvantagem em não usá-lo? Obrigado!
Rashiki
@Rashiki Esta resposta foi postada 6 anos atrás. Eu acho que a API do Apache POI mudou durante esse tempo. Minha resposta à sua pergunta é 'Não, não há nenhuma desvantagem (se funcionar como o esperado)'
ninja
Não vejo nenhum formato para mm/dd/yyyy. Quando eu uso qualquer outro formato, o excel exibe um erro File error, some number formats may have been lost, ele exibe o Datetipo no excel. Não tenho ideia de como isso pode ser consertado.
Akash
24

Para definir o tipo de data do Excel padrão (padronizado para o local do nível do sistema operacional / -> ou seja, xlsx parecerá diferente quando aberto por um alemão ou britânico / e marcado com um asterisco se você escolher no seletor de formato de célula do Excel), você deve:

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

Eu fiz isso com xlsx e funcionou bem.

BlondCode
fonte
2
Concordo absolutamente com o comentário de Fiffy. Eu só tenho uma pergunta. Qual é a melhor abordagem. Confie no valor curto dataFormat (14) ou no valor da string ("m / d / yy"). Qual é realmente o valor constante que descreve o formato de data padrão no Excel? DataFormat.getFormat () tem ambos com string e com valor curto como parâmetro.
Miklos Krivan
Miklos, não sei como funciona a solução do valor da cadeia. Eu ficaria feliz se alguém pudesse comentar se também está mostrando o "formato de data padrão diferente com base no idioma" no Excels com idiomas diferentes.
BlondCode
13

Este exemplo é para trabalhar com tipos de arquivo .xlsx. Este exemplo vem de uma página .jsp usada para criar uma planilha .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);
Sr. Port St Joe
fonte
1

Estou escrevendo minha resposta aqui porque pode ser útil para outros leitores, que podem ter um requisito ligeiramente diferente do que o questionador aqui.

Eu preparo um modelo .xlsx; todas as células que serão preenchidas com datas, já estão formatadas como células de data (usando o Excel).

Abro o modelo .xlsx usando o Apache POI e, em seguida, apenas escrevo a data na célula e funciona.

No exemplo a seguir, a célula A1 já está formatada no Excel com o formato [$-409]mmm yyyye o código Java é usado apenas para preencher a célula.

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

Quando o Excel é aberto, a data é formatada corretamente.

gordon613
fonte
0

Este exemplo de código pode ser usado para alterar o formato da data. Aqui eu quero mudar de aaaa-MM-dd para dd-MM-aaaa. Aqui posestá a posição da coluna.

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

Para saber a string de formato usada pelo Excel sem precisar adivinhá-la: crie um arquivo excel, escreva uma data na célula A1 e formate-a como desejar. Em seguida, execute as seguintes linhas:

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

Em seguida, copie e cole a string resultante, remova as barras invertidas (por exemplo, d/m/yy\ h\.mm;@se torna d/m/yy h.mm;@) e use-a no código 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);
Lucas
fonte