一、安装
composer require phpoffice/phpspreadsheet
官网:phpoffice/phpspreadsheet - Packagist
二、代码
>设置文本格式
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Shared\Date;
/**
* @name 导入表格处理
* @method Model
* @author 峰神
* @date 2024-1-3
* @ruturn array
*/
class Import extends BaseServices
{
/**
* @name 导入表格处理
* @author 峰神
* @date 2024-1-3
* @param array $postArr 选填 提交表单的数组
* @param 对象 $files 必填 上传文件
* @ruturn array
*/
public function importUploads(array $postData,$files){
$msg='成功';$code=200;$data=[];
try {
if(empty($files)){
throw new \Exception("上传文件为空");
}
if(empty($postData)){
throw new \Exception("提交参数为空");
}
$action=!empty($postData['action'])?$postData['action']:'';
$oss_c_n=!empty($postData['oss_c_n'])?$postData['oss_c_n']:'';
if($oss_c_n=='Live'){//导入直播章节
// $fieldArr=['A'=>'title','B'=>'ctitle','C'=>'starttime','D'=>'duration','E'=>'endtime'];
$sheetArr = self::readData('file',[],'excel',$postData,['C']);
$data = (new \app\appcenter\model\LiveChapter())->batchImportData($sheetArr,$postData);
dump($data);die;
// $data = $this->LiveImportChapter($files,$postData);
}
} catch (\Exception $e) {
// 这是进行异常捕获
$code=-200;$msg=$e->getMessage();
}
return ['code' => $code,'msg' => $msg,'data'=>$data];
}
/**
* 读取表格数据
*
* @param string $name 必填 文件域名称
* @param array $field 选填 表格各列对应的数据库字段
* @param string $scene 选填 验证场景
* @param array $postData 选填 表单数组
* @param array $timeFieldArr 选填 时间日期字段(带日期字段值都需要格式化,例子:表格中C列是日期,值是2024/1/3 0:00,如果不处理,取得是45305.708333333这种的)
*/
public static function readData(string $name, array $field=[], string $scene = 'excel',array $postData=[],array $timeFieldArr=[])
{
try {
$file = request()->file($name);
if (!$file) throw new \Exception('没有文件上传');
// Excel文件验证
validate(\app\tableappcenter\validate\ImportValidate::class)->scene($scene)->check([$scene => $file]);
// Excel 类型 Xls Excel2005 Xlsx Excel2007
$type = ucfirst($file->getOriginalExtension());
// 创建读操作对象
$reader = IOFactory::createReader($type);
// 忽略任何格式的信息
$reader->setReadDataOnly(true);
// 打开文件、载入excel表格
$spreadsheet = $reader->load($file->getRealPath());
// 获取活动工作薄
$sheet = $spreadsheet->getActiveSheet();
// 返回表格数据
return self::getCellData($sheet, $field,$postData,$timeFieldArr);
} catch (\Exception $e) {
// 有异常发生
return ['code' => $e->getCode(), 'errMsg' => $e->getMessage()];
}
}
/**
* 获取单元格数据
*
* @param object $sheet 获取活动工作薄
* @param array $field 表格各列对应的数据库字段
* @param array $postData 选填 表单数组
* @param array $timeFieldArr 选填 时间日期字段(带日期字段值都需要格式化,例子:表格中C列是日期,值是2024/1/3 0:00,如果不处理,取得是45305.708333333这种的)
*/
private static function getCellData(object $sheet, array $field=[],array $postData=[], array $timeFieldArr=[])
{
# 获取最高列 返回字母 如: C
$highestColumn = $sheet->getHighestColumn();
# 获取最大行 返回数字 如: 4
$highestRow = $sheet->getHighestRow();
# 列数 改为数字显示
$highestColumnIndex = Coordinate::columnIndexFromString($highestColumn);
$data = [];
// 从第二行开始读取数据
for ($row = 2; $row <= $highestRow; $row++) {
$build = [];
// 从第一列读取数据
for ($col = 1; $col <= $highestColumnIndex; $col++) {
// 'A' 对应的ASCII码十进制为 64
// 将ASCII值转为字符
$chr = chr(64 + $col);
// 列转为数据库字段名
$key = $field[$chr] ?? $chr;
$Value = $sheet->getCellByColumnAndRow($col, $row)->getValue();
if(!empty($timeFieldArr)){//格式化时间-
if(in_array($key,$timeFieldArr) && $Value){
// $Value = $sheet->getCellByColumnAndRow($col, $row)->getValue();
$Value = gmdate('Y-m-d H:i:s',\PhpOffice\PhpSpreadsheet\Shared\Date::excelToTimestamp(($Value)));
}
}
// 构建当前行数据
$build[$key] = $Value;
}
$data[] = $build; //当前行数据
}
return $data;
}
}
注意:
$sheetArr = self::readData('file',[],'excel',$postData,['C']);//file相当request()->file('file')中file'
['C']=指 表格中放日期的列;日期需要经过处理后才可以的,不然取得的值是:45305.708333333,而且还会增加多8小时
处理方法:gmdate('Y-m-d H:i:s',\PhpOffice\PhpSpreadsheet\Shared\Date::excelToTimestamp(($Value)));
参考:
TP6.0 使用 phpoffice/phpspreadsheet 导入数据 - 霸波儿奔925 - 博客园 (cnblogs.com)
PhpOffice\PhpSpreadsheet 获取时间快了8小时_php xlxs 读取时间长-CSDN博客