thinkphp 操作导入excel表 且保存错误数据到新的excel表

11 篇文章 1 订阅
4 篇文章 0 订阅

准备工作:下载PHPExcel文件存放在自己的文件下(我放在了extend目录下)

1.前端:先实现可以上传文件(和平时上传文件一样)

因为我的页面还有其他功能的实现,所以自己写了个方法来收回传的上传成功文件的路径(本人用的是前端layui框架,自带上传)

后台:处理数据的方法。

        $upload = input('upload');
        $action = input('action');
        if($upload and $upload == 'upload'){
            //获取文件对象
            $file = $this->request->file('file');
            //验证并上传
            $info = $file->validate(['size'=>'10485760','ext'=>'xls,xlsx'])
                ->move('uploads');
            //判断是否成功
            if($info){
                $url = $info->getSaveName();
                $this->success('上传成功','',['url'=>$url]);    //返回上传文件成功的文件名
            }else{
                $this->error($file->getError());
            }
        }

2.提交数据后,处理数据的方法,并且处理导出新的错误数据excel表:

<?php
namespace app\admin\model;
use think\Model;
use think\Db;
use think\db\Where;
require'../extend/PHPExcel/PHPExcel.php'; // 引入PHPExcel核心文件
class CommentimportModel extends Model
{

	public function import($data,$m){
		// 启动事务
		Db::startTrans();
		try {
		$url = $data['url'];
		$pid = $data['pid'];
		$url = 'uploads/'.$url;
		$mid = $this->list_all($data,true);
		if ($mid['data']==-200) {
			throw new \Exception('课程不存在');
		}
		//公共部分---
		$PHPExcel = new \PHPExcel();
		$PHPReader = new \PHPExcel_Reader_Excel2007();
		if (!$PHPReader->canRead($url)) {
			$PHPReader = new \PHPExcel_Reader_Excel5();
			if (!$PHPReader->canRead($url)) {
				throw new \Exception('叁数错误');
			}
		}
		//获取系统设置的难易度标签
		$con = Db::name('comment_confing')->where('mid',$mid['data']['category1id'])->where('deleted',0)->field('description,controller,mid')->find();
		if (!$con) {
			throw new \Exception('没有对应评论栏目设置');
		}
		$label_arr = explode(',',$con['description']);
		$product = Db::name($mid['data']['table'])->where('id',$pid)->field('title,comment_number')->find();
		$E = $PHPReader->load($url);
		$cur = $E->getSheet(0);  // 读取第一个表
		$end = $cur->getHighestColumn(); // 获得最大的列数
		$line_count = $cur->getHighestRow(); // 获得最大总行数
		
		//判断模板格式是否正确
		$A2 = $cur->getCell("A2")->getValue();
		$B2 = $cur->getCell("B2")->getValue();
		$C2 = $cur->getCell("C2")->getValue();	
		if( strcmp($A2,"内容")!=0 or strcmp($B2,"难易程度")!=0 or strcmp($C2,"评分")!=0 ){
			throw new \Exception('导入模板格式不正确');
		}
		if($line_count<3){
			throw new \Exception('导入模板不能为空');
		}
		if($line_count>502){
			throw new \Exception('一次至多只能导入500条数据');
		}
		$data2 = [];  //记录成功数据
		$data3 = [];  //记录错误信息
		$error_count = 0; //记录错误数据量
		$data['line_count'] = $line_count-2;
		$data['time'] = date('Y-m-d h:i:s');
		$import_id = Db::name('comment_import')->insertGetId($data);
		for ($i=3; $i <=$line_count ; $i++) { 
			$data1 = []; //记录信息
			$error = 0;
			$data1['content'] = $cur->getCell("A" . $i)->getValue();
			if (is_object($data1['content'])) {  			 
			   $data1['content'] = $data1['content']->__toString();
			}
			if($data1['content']==''){
				$error = 1;
				$data1['error'] = '第'.$i.'行内容不能为空';
			}
			$data1['label']   = $cur->getCell("B" . $i)->getValue();
			if (is_object($data1['label'])) {  			 
			   $data1['label'] = $data1['label']->__toString();
			}
			if(!in_array($data1['label'],$label_arr)){
				$error = 1;
				$data1['error'] = $data1['error'].'第'.$i.'难易程度参数错误';
				// throw new \Exception('第'.$i.'难易程度参数错误');
			}
			$data1['rate']    = $cur->getCell("C" . $i)->getValue();
			if (is_object($data1['rate'])) {  			 
			   $data1['rate'] = $data1['rate']->__toString();
			}
			if ( $data1['rate']<1 or $data1['rate']>5) {
				$error = 1;
				$data1['error'] = $data1['error'].'第'.$i.'评分不可以超过(1-5分)';
			}
			if ($error) {
				$error_count++;
				$data3[] =$data1;
			}else{
				$data1['pid'] = $pid;  //课程id
				$end =time();  //获取当前时间时间戳
	    		$begin =strtotime(" -2 month");  //获取两月前时间戳
	   			$timestamp = date('Y-m-d h:i:s',rand($begin, $end));  //随机生成时间戳
				$data1['time'] = $timestamp;	
				$data1['title'] = $product['title'];	
				$data1['controller']=$con['controller'];
				$data1['mid']=$con['mid'];
				$data1['import_id']=$import_id;
				$data2[] = $data1;				
			}
		}
		if ($data2) {
			$insert = Db::name('Comment')->insertAll($data2);
		}
		if ($insert>0) {
			$comment_number = $product['comment_number']+$insert;
			$info2=Db::name('product')->where('id',$data['pid'])->update('comment_number',$comment_number);  //更改评论数量
		}		
		if ($data3) {
			$data['error_count'] = count($data3);
			$data['error_data'] = $this->export($data3);
		}
		$data['success_count'] = $insert;
		$data['error_count']   = $line_count-$insert-2;
		$info1=Db::name('comment_import')->where('id',$import_id)->update($data);
		Db::commit();
		}catch (\Exception $e) {
			// 回滚事务
			Db::rollback();
			//提示出错
			return $e->getMessage();
		}
		return true;
	}
	/**
	 * 处理错误数据的方法
	 * @param $data  [array]  错误数据
	 * @return 返回保存好的文件名
	 */
	public function export($data){
		if (!$data) {
			return '';
		}
		//公共部分---
		$objPHPExcel = new \PHPExcel();
		//error_reporting(E_ALL);
		ini_set('display_errors', TRUE);
		ini_set('display_startup_errors', TRUE);
		date_default_timezone_set('Europe/London');
		$objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
									 ->setLastModifiedBy("Maarten Balliauw")
									 ->setTitle("Office 2007 XLSX Test Document")
									 ->setSubject("Office 2007 XLSX Test Document")
									 ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
									 ->setKeywords("office 2007 openxml php")
									 ->setCategory("Test result file");
		// Add some data
		$objPHPExcel->getActiveSheet()->mergeCells('A1:D1');
		$objPHPExcel->getActiveSheet()->getRowDimension(1)->setRowHeight(30);
		//垂直水平居中
		$objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
		$objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
		$objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true);
		$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(25);
		$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(25);
		$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(25);
		$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(25);
		$objPHPExcel->setActiveSheetIndex(0)
					->setCellValue('A1', '导入失败的评论')
					->setCellValue('A2', '内容')
					->setCellValue('B2', '难易程度')
					->setCellValue('C2', '评分')
					->setCellValue('D2', '错误说明');

        //填写数据  
        foreach ($data as $k => $v) {
        	$objPHPExcel->getActiveSheet()->setCellValue('A'.($k+3),$v['content']);
        	$objPHPExcel->getActiveSheet()->setCellValue('B'.($k+3),$v['label']);
        	$objPHPExcel->getActiveSheet()->setCellValue('C'.($k+3),$v['rate']);
        	$objPHPExcel->getActiveSheet()->setCellValue('D'.($k+3),$v['error']);
        } 	
		$objPHPExcel->getActiveSheet()->setTitle('导入失败的评论');
		$objPHPExcel->setActiveSheetIndex(0);
		
		//定义保存路径
		$user_path="./uploads/";
        $filename = 'file/'.date('YmdHis',time()).'commenterror.xlsx';
        $filename = iconv("utf-8","gb2312",$filename);
		$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
		$objWriter->save($user_path.$filename);
		// dump($user_path.$filename);
		return $filename;	
	}

    /**
     * 返回产品类别
     * return 数组
     */
    public function list_all($post,$type=false){
		$where = new Where;
		$where['deleted']=0;
		$page = $post['page']?$post['page']:1;
		$limit = $post['limit']?$post['limit']:1;
		if($post['keyword']){
			$where['title'] = ['like', "%".$post['keyword']."%"];
		}
		$category_arr = $post['cate_id']; //处理分类ID	
		if(!$category_arr){
			return['code'=>0,'msg'=>'失败','count'=>0,'data'=>''];
		}
		$first= explode('/',$category_arr);
		$model = Db::name('menu')->where('id',$first[0])->field('model')->find();
		$model = $model['model'];
		if ($model ==1 || $model==12 || $model==13 ) {
			$table = 'product';
		}elseif ($model == 11) {
			$table = 'combination';
		}elseif ($model == 7) {
			$table = 'teachers';
		}elseif ($model == 2) {
			$table = 'news';
		}else{
			return['code'=>0,'msg'=>'失败','count'=>'','data'=>''];
		}
		if ($type) {
			$where['id']=$post['pid'];
			$list=Db::name($table)->field('category1id')->where($where)->find();
			// dump($list);dump($post);die;
			if ($list) {
				$list['table'] = $table;
			}else{
				$list = -200;
			}
		}else{
			$list=Db::name($table)->field('id,title,type_mold')->where($where)->where('FIND_IN_SET(:category_id,category)',['category_id' => $category_arr])->order(['sort','id'=>'desc'])->page($page,$limit)->select();
			$count = Db::name($table)->field('id,title,type_mold')->where($where)->where('FIND_IN_SET(:category_id,category)',['category_id' => $category_arr])->count();			
		}

		// dump($crs);die;
		$json['code']=0;
    	$json['msg']='成功';
		$json['count']=$count;
    	$json['data']=$list;
    	return $json;
    }
}

具体实现代码:具体实现代码功能链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Student Li

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

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

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

打赏作者

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

抵扣说明:

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

余额充值