准备工作:下载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;
}
}
具体实现代码:具体实现代码功能链接