清华大学赵志磊--基于thinkPHP6框架的Excel表格导入和导出

1、Excel表格导出

先上大图:(可放大查看,当作壁纸再好不过,超高清壁纸)

正题:

首先、thinkPHP6框架内在admin应用下,自定义文件夹,存放公共类,里面封装公共方法。

命名空间写好,记得引入Db查询构造器的类等

 命令:安装扩展命令:composer require phpoffice/phpspreadsheet

接着:导出代码

/**
 * Excel表格导出
 * Excel扩展名为xlsx和xls两种,默认为false
 */
public static function exportExcel($table = '' , $database = '' , $type = false , $fileName = '新建Excel表格')
{
    /**
     * author:柔情柴少
     * time:2021/12/17
     * title:封装Excel导出header头
     * 优点:不用自己定义,被柴少写活,只需要传入参数,也就是表名和数据库名
     */
    $res =Db::query("SELECT column_comment FROM INFORMATION_SCHEMA.Columns WHERE table_name='$table' AND table_schema='$database'");
    $column_length = count($res);
    $arr = [];
    for ($i='A';$i<=chr(ord('A')+$column_length-1);$i++){
        array_push($arr,$i.'1');
    }
    $newArr = [];
    foreach ($res as $k=>$v){
        array_push($newArr,implode(array_values($v)));
    }
    $header = [];
    for ($i=0;$i<$column_length;$i++){
        $header["$arr[$i]"] = $newArr[$i];
    }

    /**
     * @data 从数据库查询的数据
     * @method/Db查询构造器或者从模型查询(依赖注入、静态、实例化对象)
     * Db查询构造器查询完成,转化成二维关联数组
     */
    $data = Db::table($table)->select()->toArray();
    foreach ($data as $k=>$v){
        $array = array_values($v);
        $data[$k] = $array;
    }

    /**
     * 实例化类
     */
    $preadsheet = new Spreadsheet();
    /**
     * 创建sheet纸张
     */
    $sheet = $preadsheet->getActiveSheet();
    /**
     * 循环header表头数据
     */
    foreach ($header as $k => $v) {
        $sheet->setCellValue($k, $v);
    }
    /**
     * 生成数据
     */
    $sheet->fromArray($data, null, "A2");
    /**
     * 样式设置
     */
    $sheet->getDefaultColumnDimension()->setWidth(12);
    /**
     * 下载与后缀
     */
    if ($type) {
        header("Content-Type:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        $type = "Xlsx";
        $suffix = "xlsx";
    } else {
        header("Content-Type:application/vnd.ms-excel");
        $type = "Xls";
        $suffix = "xls";
    }
    /**
     * 清除缓存区
     */
    ob_end_clean();
    /**
     * 激活浏览器窗口
     */
    header("Content-Disposition:attachment;filename=$fileName.$suffix");
    /**
     * 缓存控制
     */
    header("Cache-Control:max-age=0");
    /**
     * 调用方法执行下载
     */
    $writer = IOFactory::createWriter($preadsheet, $type);
    /**
     * 数据流
     */
    $writer->save("php://output");
}

调用参数:

$database = 'week1';
$table='goods';
$type = false;
$fileName = '商品表';
$res = $excel::exportExcel($table,$database,$type,$fileName);

自己定义路由,跳到某个方法内,在方法内,写上述代码,即可调用公共函数exportExcel将数据库内某个表的内容完美导出:注意------表内字段,最好有comment(注释)不然导出的Excel表格没有表头。

赵教授封装的Excel导出方法,极大地简化了工作量,只需要传入四个参数;

$database 你当前操作的数据库名

$table 你要导出的表名

$type 决定Excel表格是xlsx还是xls后缀,一般默认为false

$fileName 为导出的Excel表格的名字(可以再加工一下,直接让$table代替$fileName)

导出完毕!!!

2、Excel表格导入

再上大图: 

导入公共方法:

 

/**
 * @param string $filename
 * @return array|string
 * @throws \PhpOffice\PhpSpreadsheet\Exception
 * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
 */
public static function importExcel($filename = "",$table = "",$database = "")
{
    /**
     * 注意,导入时,需要自行建表,和Excel表格格式相同
     * 可以再深度封装,加入迁移建表,但考虑到字段无法自动识别进行创建,暂时封装到这里
     */
    $file[] = $filename;

    try {
        /**
         * 验证文件大小为2M
         * 后缀为Excel表格的后缀
         */
        validate(['file' => 'fileSize:2097152|fileExt:xls,xlsx'])
            ->check($file);
        /**
         * 将文件保存到本地
         */
        $savename = \think\facade\Filesystem::disk('public')->putFile('file', $file[0]);
        /**
         * 获取文件后缀
         */
        $fileExtendName = substr(strrchr($savename, '.'), 1);
        /**
         * xls和xlsx两种格式
         */
        if ($fileExtendName == 'xlsx') {
            $objReader = IOFactory::createReader('Xlsx');
        } else {
            $objReader = IOFactory::createReader('Xls');
        }
        /**
         * 设置文件为只读
         */
        $objReader->setReadDataOnly(TRUE);
        /**
         * 读取文件,thinkPHP默认上传文件,在runtime目录下,可根据实际情况进行更改,在config目录下,filesystem.php中更改
         */
        $objPHPExcel = $objReader->load(public_path() . 'storage/' . $savename);
        /**
         * excel中的第一张纸
         */
        $sheet = $objPHPExcel->getSheet(0);
        /**
         * 获取总行数
         */
        $highestRow = $sheet->getHighestRow();
        /**
         * 获取总列数
         */
        $highestColumn = $sheet->getHighestColumn();
        Coordinate::columnIndexFromString($highestColumn);
        $lines = $highestRow - 1;
        if ($lines <= 0) {
            return "数据为空数组";
        }
        /**
         * 直接取出Excel中的数据
         */
        $data = $objPHPExcel->getActiveSheet()->toArray();
        /**
         * 删除第一行元素,Excel表格的表头
         * 第一行,也可以留着,插入对应字段后,当注释,具体请百度,本尊不再详细讲解
         */
        array_shift($data);
        /**
         * 删除文件
         */
        unlink(public_path() . 'storage/' . $savename);
        /**
         * 输入表名,查找对应字段
         */
        $columns =Db::query("select column_name from information_schema.columns where table_name='$table' and table_schema='$database'");
        /**
         * 将查询的字段放入对应索引数组
         */
        $array = [];
        foreach ($columns as $k=>$v){
            array_push($array,implode(array_values($v)));
        }
        /**
         * 循环数据,也就是二维关联数组,生成对应的键,方便插入
         * 注意:表中字段,一定要和Excel表格的列数一样,不然会报错,也就是对应的字段数据,没有键
         */
        $count_column = count($array);
        $newArray = [];
        $finalArray = [];
        foreach($data as $k=>$v){
            for ($i=1;$i<$count_column;$i++){
                $newArray[$array[$i]] = $v[$i];
            }
            $finalArray[] = $newArray;
        }
        foreach ($finalArray as $k=>$v){
            Db::table($table)->insert($v);
        }
        /**
         * 循环添加,将数据插入数据库
         * 注意:由于使用了Db查询构造器插入
         * 表内字段,出了主键不能为空且自增以外
         * 其他字段最好不要在不能为空的方框内打对号
         * 不然Excel导入数据有空值的情况下,会报错
         * 若是用模型插入,并且,字段有默认值的情况下,不会出现这种错误
         * 也就是说,Db查询构造器,字段有默认值,不能为空,当你Excel表格存在空值,依旧报错
         */
    } catch (ValidateException $e) {
        return $e->getMessage();
    }
}

调用代码:

public function import(Excel $excel){
    $file = \request()->file('file');
    $table = 'good';
    $database = 'week1';
    $res = $excel::importExcel($file,$table,$database);
}

Excel类的引入,可以使用依赖注入

$file 文件域上传的Excel文件

$table 为表名

$database 为当前要插入数据的表所在的数据库名字

只需要三个参数

但是:注意!!!

表需要提前建好,最好依据Excel表格建表,对应好列column

因为导入方法,插入数据时,调用了Db查询构造器,所以建表时,字段后的小方格,不要打对号。

即便有默认值也不行,除了自增的主键可以不为空

防止-------你的Excel表格存在单元格空数据,报错

如果是模型插入则不存在这个问题,只要有默认值,即便插入对应字段数据为空,也能插入。

但,赵教授封装的方法,却是用Db查询构造器插入的数据,用模型还得调用模型,会增加不必要的麻烦!

例如:

varchar类型数据,不为空,默认为字符串,模型插入时,这个字段对应数据为空,能插进去,Db查询构造器就会报错。

谨记!!!

Excel表格的导入和导出讲解完,最后上大图,同学们最爱看!

大图:

本学期的课程接近尾声,thinkPHP6框架分为5层架构,控制器层--业务逻辑层--lib基础库--模型层--视图层

在这里插入图片描述

 祝愿同学们,在清华大学计算机系web语言编程的课程学习上,学有所成,愉快成长!

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柔情柴少

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值