<?php
//...
class YourExcelImport implements OnEachRow, WithValidation, WithHeadingRow
{
// ...
/**
* Tweak the data slightly before sending it to the validator
* @param $data
* @param $index
* @return mixed
*/
public function prepareForValidation($data, $index)
{
//Fix that Excel's numeric date (counting in days since 1900-01-01)
$data['your_date_column'] = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($data['your_date_column'])->format('Y-m-d');
//...
}
/**
* List the validation rules
* @return array
*/
public function rules(): array
{
return [
'your_date_column'=>'required|date_format:Y-m-d',
//..
];
}
}
?>
/**
* @param Cell $cell
* @param $value
*
* @return boolean;
*/
public function bindValue(Cell $cell, $value)
{
$formatedCellValue = $this->formatDateTimeCell($value, $datetime_output_format = "d-m-Y H:i:s", $date_output_format = "d-m-Y", $time_output_format = "H:i:s" );
if($formatedCellValue != false){
$cell->setValueExplicit($formatedCellValue, DataType::TYPE_STRING);
return true;
}
// else return default behavior
return parent::bindValue($cell, $value);
}
/**
*
* Convert excel-timestamp to Php-timestamp and again to excel-timestamp to compare both compare
* By Leonardo J. Jauregui ( @Nanod10 | siskit dot com )
*
* @param $value (cell value)
* @param String $datetime_output_format
* @param String $date_output_format
* @param String $time_output_format
*
* @return $formatedCellValue
*/
private function formatDateTimeCell( $value, $datetime_output_format = "Y-m-d H:i:s", $date_output_format = "Y-m-d", $time_output_format = "H:i:s" )
{
// is only time flag
$is_only_time = false;
// Divide Excel-timestamp to know if is Only Date, Only Time or both of them
$excel_datetime_exploded = explode(".", $value);
// if has dot, maybe date has time or is only time
if(strstr($value,".")){
// Excel-timestamp to Php-DateTimeObject
$dateTimeObject = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value);
// if Excel-timestamp > 0 then has Date and Time
if(intval($excel_datetime_exploded[0]) > 0){
// Date and Time
$output_format = $datetime_output_format;
$is_only_time = false;
}else{
// Only time
$output_format = $time_output_format;
$is_only_time = true;
}
}else{
// Only Date
// Excel-timestamp to Php-DateTimeObject
$dateTimeObject = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value);
$output_format = $date_output_format;
$is_only_time = false;
}
// Php-DateTimeObject to Php-timestamp
$phpTimestamp = $dateTimeObject->getTimestamp();
// Php-timestamp to Excel-timestamp
$excelTimestamp = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel( $phpTimestamp );
// if is only Time
if($is_only_time){
// 01-01-1970 = 25569
// Substract to match PhpToExcel conversion
$excelTimestamp = $excelTimestamp - 25569;
}
/*
// uncoment to debug manualy and see if working
$debug_arr = [
"value"=>$value,
"value_float"=>floatval($value),
"dateTimeObject"=>$dateTimeObject,
"phpTimestamp"=>$phpTimestamp,
"excelTimestamp"=>$excelTimestamp,
"default_date_format"=>$dateTimeObject->format('Y-m-d H:i:s'),
"custom_date_format"=>$dateTimeObject->format($output_format)
];
if($cell->getColumn()=="Q"){
if($cell->getRow()=="2"){
if(floatval($value)===$excelTimestamp){
dd($debug_arr);
}
}
}
*/
// if the values match
if( floatval($value) === $excelTimestamp ){
// is a fucking date! ;)
$formatedCellValue = $dateTimeObject->format($output_format);
return $formatedCellValue;
}else{
// return normal value
return false;
}
}
8条答案
按热度按时间bjg7j2ky1#
数字来自excel本身,日期以数值形式存储在excel中。http://www.cpearson.com/excel/datetime.htm
对于Laravel framework 5.6和maatwebsite/excel包3.1版,要将日期从excel数字转换为正常的日期格式,可以使用函数
PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($dateFromExcel)
,它接受整数(excel日期)并返回DateTime对象。更多信息请访问https://github.com/Maatwebsite/Laravel-Excel/issues/1832
从这个答案:https://stackoverflow.com/a/55139981/9133724
daupos2t2#
解决了!这是我用来解决我的问题的代码:
9q78igpj3#
我尝试了上述解决方案,但总是遇到非数值错误
我设法用
第一个月
\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($date)->format('d/m/Y')
0aydgbwb4#
基于
Skyrem Brilliant
的@skyrem-brilliant答案,我是这样解决的:这就完成了任务,验证通过。
jslywgbw5#
这个"未知数字"是一个excel时间戳,这样它就可以在内部存储日期和时间数据。
例如:
如果可以Map单元格,并且知道哪一列将始终具有日期/时间/日期-时间,则可以使用Map的单元格或手动转换它,请参见:https://stackoverflow.com/a/59049044
否则,如果您的需要涉及动态解析日期时间字段,我已经编写了一个方法,负责自动动态检测值是否为日期时间(不管您是否知道该列中是否有日期时间),或者我尝试了各种数据类型,它工作正常
qxsslcnc6#
只需使用此功能即可存储日期。
ehxuflar7#
在这种情况下,你可以参考我的代码。它工作得很好。
〈?php
xtfmy6hx8#
我已经创建了一个函数来检查文件扩展名。它根据文件扩展名解析日期
1.控制器代码
1.在
FileImportRequest
类中。1.在
FileImport
类中。