如何将单元格值设置为“日期”并应用默认的Excel日期格式?


101

我已经使用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将其“日期”存储为自1900年1月1日以来的天数,这就是单元格中所代表的数字。

问题:我可以在POI中使用什么API调用来告诉它我希望将默认日期格式应用于日期单元格?

理想情况下,如果用户手动在Excel中打开电子表格并输入Excel认为是日期的单元格值,则我希望使用与Excel为其分配的默认日期格式相同的默认日期格式显示电子表格单元格。

Answers:


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

21
谢谢忍者,这对我有用。对需要这样做的其他人发表评论。有一个名为POI的类BuiltinFormats,列出了Excel知道的所有标准格式(而不仅仅是日期格式)。我坚持使用其中一个作为getFormat()上面代码段所示方法的参数。
Jim Tough

重要的部分在链接的注释中:我们将第二个单元格设置为日期(和时间)。在工作簿中创建新的单元格样式很重要,否则您最终可能会修改内置样式并不仅影响此单元格,而且影响其他单元格。
CGK 2013年

谢谢,@ ninja。你知道为什么getCreationHelper()需要吗?我现在正在与Mule一起生成Excel输出文件,实际上我可以在createDataFormat()没有创建帮助器的情况下使用,并在测试中生成Excel文件。不使用它有不利之处吗?谢谢!
拉希基

@Rashiki这个答案发布于6年前。我猜这期间Apache POI的API发生了变化。我对您的问题的回答是“不,没有缺点(如果它按预期工作)”
忍者

我看不到任何格式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做到了,效果很好。


2
完全同意fiffy的评论。我只有一个问题。最好的方法是什么?依靠dataFormat的短值(14)或字符串值(“ m / d / yy”)。到底哪个值描述了Excel中的标准日期格式?DataFormat.getFormat()同时具有字符串和简短值作为参数。
米克洛斯·克里文

Miklos,我不知道字符串值解决方案如何工作。如果有人可以反馈是否也在不同语言的Excel中显示“基于语言的不同默认日期格式”,我将感到非常高兴。
BlondCode

13

本示例用于处理.xlsx文件类型。本示例来自用于创建.xslx电子表格的.jsp页面。

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

我使用Apache POI打开.xlsx模板,然后只需将日期写入单元格即可。

在下面的示例中,单元格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时,日期格式正确。


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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.