基于ThinkPHP6框架的Excel表格导入和导出


应该把它封装成公共类自定义文件夹,存放公共类,里面封装公共方法。(library \ Excel)
在这里插入图片描述

1、准备工作

1.1、下载拓展

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

1.2、引入构造器

use think\facade\Db;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;

2、导入导出代码

2.1、导入

/**
  * @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();
     }
 }

2.2、导出

 /**
  * Excel表格导出
  * Excel扩展名为xlsx和xls两种,默认为false
  */
 public static function exportExcel($table = '' , $database = '' , $type = false , $fileName = '新建Excel表格')
 {
 	/**
     * title:封装Excel导出header头
     * 优点:只需要传入参数,也就是表名和数据库名,解决超过26位无限循环问题
     */
     $res =Db::query("SELECT column_comment FROM INFORMATION_SCHEMA.Columns WHERE table_name='$table' AND table_schema='$database'");
     $column_length = count($res);
     $arr = [];
     // 设置excel表的表头
     $start = 'A';
     for ($i = 0;$i < $column_length;$i++){
         array_push($arr,$start.'1');
         $start ++;
     }
     // 读取数据
     $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");
 }

2.3、执行使用

导入-前端代码

<!--导入前端代码-->
<form action="http://cparty.io.com:802/api/Activity/import" method="post" enctype="multipart/form-data">
    <!-- 文件选择按钮 -->
    <input type="file" name="file">
    <!-- 表单提交按钮 -->
    <button type="submit">提交</button>
</form>

导入

// 导入
public function import(Excel $excel){
    $file = \request()->file('file');
    $table = 'fa_user';
    $database = 'yfcmf_tp6';
    $res = $excel::importExcel($file,$table,$database);
}

导出

//导出
public function export(){
    $excel = new Excel();
    // 数据库名
    $database = 'yfcmf_tp6';
    // 表名
    $table='fa_user';
    $type = false;
    // 重命名
    $fileName = '用户表';
    $res = $excel::exportExcel($table,$database,$type,$fileName);
}

原文链接:https://blog.csdn.net/wuqingchaishao/article/details/122022166

3、报错

导入报 Disk [public] not found.
解决办法:在配置文件中(路径:/config/filesystem.php)加入public磁盘配置路径

'public' => [
    // 磁盘类型
    'type'       => 'local',
    // 磁盘路径
    'root'       => app()->getRootPath() . 'public/storage',//public/storage目录下.然后还要什么目录。具体看代码操作
    // 磁盘路径对应的外部URL路径
    'url'        => '/storage',
    // 可见性
    'visibility' => 'public',
],

![在这里插入图片描述](https://img-blog.csdnimg.cn/711f8a0678e24d3fa7a4c81791c736fd.png

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值