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

129

我使用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分配给它的相同默认日期格式。

7个回答

218

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

30
谢谢,这对我有用。给其他需要这样做的人一个建议。有一个名为“BuiltinFormats”的POI类列出了Excel知道的所有标准格式(不仅是日期格式)。我将选择其中之一作为我的参数,以在上面的代码片段中使用getFormat()方法。 - Jim Tough
1
重要的部分在链接的注释中:我们将第二个单元格样式设置为日期(和时间)。从工作簿创建新的单元格样式非常重要,否则您可能会修改内置样式并影响不仅此单元格而且其他单元格。 - CGK
@Rashiki 这个答案是6年前发布的。我猜Apache POI的API在这段时间内已经发生了变化。对于你的问题,我的回答是“没有任何缺点(如果它按预期工作)”。 - ninja
我没有看到 mm/dd/yyyy 的任何格式。当我使用其他任何格式时,Excel 显示错误 文件错误,某些数字格式可能已丢失,它在 Excel 中显示 日期 类型。我不知道该如何解决这个问题。 - Akash
3
看起来很好并且能够正常运行,但是它没有将单元格类型设置为“日期”,而是“自定义”。 - Dmitriy Popov
显示剩余3条评论

30

要将默认的Excel日期类型设置为默认(默认为操作系统级别的本地化/即xlsx在被德国或英国人打开时会看起来不同/,并带有一个星号,如果您在Excel的单元格格式选择器中选择它),您应该:

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

我使用xlsx做到了,而且它很好用。


3
完全同意fiffy的评论。我只有一个问题:什么是最佳方法?依靠数据格式短值(14)还是字符串值("m/d/yy")?哪个才是真正描述Excel中标准日期格式的常量值?DataFormat.getFormat()方法可以接受字符串和短值作为参数。 - Miklos Krivan
Miklos,我不知道字符串值解决方案是如何工作的。如果有人能够反馈在不同语言的Excel中是否也显示了“基于语言的不同默认日期格式”,我将不胜感激。 - BlondCode

14

这个例子是用于操作 .xlsx 文件类型的。这个例子来自一个 .jsp 页面,用于创建一个 .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);

5
除了 @BlondeCode 的答案之外,以下是您可以通过 creationHelper.createDataFormat().getFormat((short) index) 获得的所有可用格式列表:
0 = "常规" 1 = "0" 2 = "0.00" 3 = "#,##0" 4 = "#,##0.00" 5 = ""$"#,##0_);("$"#,##0)" 6 = ""$"#,##0_);红色" 7 = ""$"#,##0.00_);("$"#,##0.00)" 8 = ""$"#,##0.00_);红色" 9 = "0%" 10 = "0.00%" 11 = "0.00E+00" 12 = "# ?/?" 13 = "# ??/??" 14 = "m/d/yyyy" 15 = "yyyy-mm-dd" 16 = "mmm-yy" 17 = "dd-mmm-yy" 18 = "h:mm AM/PM" 19 = "h:mm:ss AM/PM" 20 = "h:mm" 21 = "h:mm:ss" 22 = "m/d/yyyy h:mm" 23-36 = 保留 37 = "#,##0_);(#,##0)" 38 = "#,##0_);红色" 39 = "#,##0.00_);(#,##0.00)" 40 = "#,##0.00_);红色" 41 = "(* #,##0);(* (#,##0);(* “-”);(@)" 42 = "("$"* #,##0_);("$"* (#,##0);("$"* “-”);(@)" 43 = "(* #,##0.00_);(* (#,##0.00);(* “-”??);(@)" 44 = "("$"* #,##0.00_);("$"* (#,##0.00);("$"* “-”??);(@_)" 45 = "mm:ss" 46 = "[h]:mm:ss" 47 = "mm:ss.0" 48 = "##0.0E+0" 49 = "@"
从索引164开始,是您的自定义格式。

类型“0-通用”对我很有帮助,否则数字在Excel中显示为字符串,并出现“绿色左上角三角形”。 - marcor92
类型“0 - 一般”对我有用,否则数字在Excel中显示为字符串,并出现了“绿色左上角三角形”。 - marcor92

3

要知道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);

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接