PHPExcel:如何为单元格设置日期格式

7

我需要将日期保存到Excel文件中,日期必须以“dd/mm/yyyy”格式输出(或用户的本地日期格式),并且必须被视为日期,以便可以正确排序它们所在的列。

以下是代码:

<?php
include_once("../PHPExcel/Classes/PHPExcel.php");
date_default_timezone_set('Europe/London');
$objPHPExcel = new PHPExcel();
$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip;
PHPExcel_Settings::setCacheStorageMethod($cacheMethod);

$objPHPExcel = new PHPExcel();
$sheet = $objPHPExcel->getActiveSheet();
PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);

//I didn't find dd/mm/yyyy format, so I used yyyy-mm-dd
$sheet->setCellValueByColumnAndRow(0, 1, "2014-10-16");
$sheet->getStyleByColumnAndRow(0, 1)
    ->getNumberFormat()->setFormatCode(
        PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2
);

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save("test.xlsx");

它创建了一个文件,但是我看到的不是我的本地日期格式,而是"2014-10-16",单元格格式为"All formats" -> "yyyy-mm-dd"。我想将其解析并输出为我的本地日期格式。

我查看了PHPExcel/Classes/PHPExcel/Style/NumberFormat.php的源代码,并找到了许多日期格式:

const FORMAT_DATE_YYYYMMDD2 = 'yyyy-mm-dd';
const FORMAT_DATE_YYYYMMDD = 'yy-mm-dd';
const FORMAT_DATE_DDMMYYYY = 'dd/mm/yy';
const FORMAT_DATE_DMYSLASH = 'd/m/y';
const FORMAT_DATE_DMYMINUS = 'd-m-y';
...

但我不确定该使用什么。我应该如何实现期望的目标?

2个回答

8
$sheet->setCellValueByColumnAndRow(0, 1, "2014-10-16");

在单元格中设置一个字符串值,而不是日期。即使您将其解释为日期,计算机程序也不会自动将其解释为日期。
查看PHPExcel 文档示例中的日期示例,您将看到需要将单元格值设置为MS Excel序列化时间戳(自1900年1月1日以来的天数的浮点值)。您可以使用PHPExcel函数,如PHPExcel_Shared_Date :: PHPToExcel(),将人类日期/PHP DateTime对象/Unix时间戳转换为MS Excel序列化时间戳。
$sheet->setCellValueByColumnAndRow(0, 1, PHPExcel_Shared_Date::PHPToExcel( '2014-10-16' ));

如果你将值存储为时间戳,那么你可以在该单元格上应用任何日期格式掩码来获得所需的格式。


1
在 xdebug 中,PHPExcel_Shared_Date::PHPToExcel( ) 总是显示数字,我不明白它为什么被编码为数字了?我在我的电子表格中看到一些单元格格式为日期,并显示日期,但有些格式不是日期,却显示了该函数的输出数字。为什么会这样呢? - Darius.V
这对我没用。它返回了一个“false”的值。但是它仍然达到了目标。我按照这里另一个答案中提到的方式添加了"$date = new DateTime('2014-10-16');",并且在你的示例中使用了$date代替了你的字符串,然后它就完美地工作了! - undefined

8

这段代码生成了4个日期格式的单元格。

<?php
include_once("../PHPExcel/Classes/PHPExcel.php");
date_default_timezone_set('Europe/London');
$objPHPExcel = new PHPExcel();
$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip;
PHPExcel_Settings::setCacheStorageMethod($cacheMethod);

$objPHPExcel = new PHPExcel();
$sheet = $objPHPExcel->getActiveSheet();
PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);

$format = 'dd/mm/yyyy';
for ($i = 1; $i < 5; ++$i)
{
    $date = new DateTime('2016-12-0'.$i);
    $sheet->setCellValueByColumnAndRow(0, $i, 
                                       PHPExcel_Shared_Date::PHPToExcel( $date ));

    $sheet->getStyleByColumnAndRow(0, $i)
        ->getNumberFormat()->setFormatCode($format);
}

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save("test.xlsx");

在调用 PHPExcel_Shared_Date::PHPToExcel() 之前,您不需要将 DateTime 对象转换为 Unix 时间戳。相反,您可以将 DateTime 对象传递给 PHPExcel_Shared_Date::PHPToExcel(),而不是时间戳。 - Mark Baker
@MarkBaker 我更新了答案。当我尝试将字符串'2016-12-01'传递给PHPExcel_Shared_Date::PHPToExcel时,像你展示的那样,它没有起作用。 - user4035
那么你发现了一个在PHPExcel中只有你遇到过的重大bug。 PHPExcel_Shared_Date :: PHPToExcel()将接受Unix时间戳、DateTime对象或格式为PHP内置strtotime()函数可以识别的字符串,并且'2016-12-01'是一个完全有效的字符串...我刚刚用这个值进行了测试,它的表现完全符合预期。 - Mark Baker
@MarkBaker 也许是因为我用的是过时版本的库:我的库是2012年的? - user4035
“1.8.1”是最新的生产版本,发布于2015年4月30日;尽管开发分支也非常稳定。 - Mark Baker
在执行以下代码后,这段代码就能正常工作: $sheet->setCellValueByColumnAndRow(0, 1, "2014-10-16");第三个参数应该是一个字符串类型的日期。 - Azghanvi

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