tp8/6 插件PhpOffice\PhpSpreadsheet导入表格

2024-01-03 18:45:03

一、安装

composer require phpoffice/phpspreadsheet

官网:phpoffice/phpspreadsheet - Packagist

二、代码

<?php
namespace app\services\upload\model;
use app\services\BaseServices;
use \PhpOffice\PhpSpreadsheet\Spreadsheet;
use \PhpOffice\PhpSpreadsheet\IOFactory;
use \PHPExcel_Style_NumberFormat;    //设置列的格式==>>设置文本格式
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博客

文章来源:https://blog.csdn.net/haibo0668/article/details/135369946
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。