实际上就是填写一个表单,然后存储到数据库中,然后管理员可以下载此数据库的内容,也就是说要生成excel。同时也要支持上传excel,用于存储账号密码。
composer require “maatwebsite/excel:~2.1.0”
在config/app.php中加入
Maatwebsite\Excel\ExcelServiceProvider::class,
'Excel' => Maatwebsite\Excel\Facades\Excel::class,
php artisan vendor:publish –provider=”Maatwebsite\Excel\ExcelServiceProvider”
所有的报名信息放在同一张表,通过比赛id和schoolid来做限制,不过到后面有可能数据表里面的内容会很大,可以考虑分表。
报名表需要填写的字段
分为单人比赛和多人比赛
单人比赛:
学号、电话、邮箱、学院、专业、报名id、比赛id
多人比赛:
学号、电话、邮箱、学院、专业、队名、报名id(三个人有相同的报名id)、比赛id
1、创建数据库迁移
php artisan make:migration create_peoplebaomings_table –create=peoplebaomings
public function up()
{
Schema::create('peoplebaomings', function (Blueprint $table) {
$table->increments('id');
$table->integer('baomingid');
$table->bigInteger('schoolid');
$table->bigInteger('phone');
$table->string('email');
$table->string('xueyuan');
$table->string('zhuanye');
$table->string('duiming');
$table->timestamps();
});
}
php artisan migrate
如果发现刚刚迁移的数据库差字段,可以回滚之后重新迁移,也可以追加字段,第一种比较简单,这里说说第二种方式
php artisan make:migration add_gameid_to_peoplebaomings
class AddGameidToPeoplebaomings extends Migration
{
public function up()
{
Schema::table('peoplebaomings',function(Blueprint $table){
$table->integer('gameid');
});
}
public function down()
{
Schema::table('peoplebaomings',function(Blueprint $table){
$table->integer('gameid');
});
}
}
然后执行 php artisan migrate 即可
2、创建模型
php artisan make:model Api\Models\Peoplebaoming
class Peoplebaoming extends Model
{
use Notifiable;
protected $table = "peoplebaomings";
protected $fillable = [
'baomingid','schoolid','phone','email','xueyuan','zhuanye','duiming','gameid',
];
protected $hidden = [
'schoolid','gameid',
];
}
准备工作就绪
3、定制路由
//用户报名比赛
//单人报名
$api->post('danrenbaominggame','UsersController@baoming')
->name('api.danrenbaominggame.baoming');
4、编写逻辑
public function baoming(Request $request){
$this->validate($request,[
'schoolid'=>'required|max:10',
'phone'=>'required|max:11',
'email'=>'required',
'gameid'=>'required',
]);
$game = Game::where('id',$request->gameid)->first();
if($game->gamestatus==0){
$gameidnumber = Gameidnumber::where('gameid',$request->gameid)->first();//
Peoplebaoming::create([
'baomingid' => $gameidnumber->number,
'schoolid' => $request->schoolid,
'phone' => $request->phone,
'email' => $request->email,
'xueyuan' => $request->xueyuan,
'zhuanye' => $request->zhuanye,
'gameid' => $request->gameid,
]);
$gameidnumber->number = $gameidnumber->number+1;
$gameidnumber->save();
$game->number = $gameidnumber->number;
$game->save();
return $this->response->array([
'info' => '报名成功',
'status_code' => 200,
])->setStatusCode(200);
}else{
$this->response->array([
'info' => '该竞赛暂时无法报名',
'status_code'=>400,
])->setStatusCode(200);
}
}
5、测试
{
"info": "报名成功",
"status_code": 200
}
1、定制路由
//管理员下载报名表
$api->post('downloadbaoming','GamesController@downloadbmb')
->name('api.downloadbaoming.downloadbmb');
2、逻辑
$peoplebaomings=Peoplebaoming::where('gameid',$gameid)->get();
//使用这个方法从数据库中取出数据,然后需要转换成excel并支持下载
$arraypeoplebaomings = $peoplebaomings->toArray();
//使用这个方法将模型转化为数组
Excel::create('报名信息',function($excel) use ($arraypeoplebaomings){
$excel->sheet('详细信息', function($sheet) use ($arraypeoplebaomings){
$sheet->rows($arraypeoplebaomings);
});
})->export('xls');
//生成excel
整个获取报名表的逻辑为
public function downloadbmb(Request $request){
$this->validate($request,[
'key' => 'required',
'gameid' => 'required',
]);
$key = $request->key;
if($request->session()->has($key)){
$gameid = $request->gameid;
$peoplebaomings=Peoplebaoming::where('gameid',$gameid)->get();
$arraypeoplebaomings = $peoplebaomings->toArray();
Excel::create('报名信息',function($excel) use ($arraypeoplebaomings){
$excel->sheet('详细信息', function($sheet) use ($arraypeoplebaomings){
$sheet->rows($arraypeoplebaomings);
});
})->export('xls');
}else{
return $this->response->array([
'info' => '请登录后重试',
'status_code' => 400,
])->setStatusCode(200);
}
}
3、测试
使用postman测试下载的功能,在点击send的时候,有个选项是 send and download 。执行即可
注意:在模型文件中(App/Models/中定义的 hidden 字段,在生成的excel中是不存在的)
测试结果
1 0 2015211795 13452581923 1721347156@qq.com cs 2018-07-28 03:11:44 2018-07-28 03:11:44 1
2 1 2015211795 13452581923 1721347156@qq.com cs cs 2018-07-28 03:12:35 2018-07-28 03:12:35 1
3 2 2015211795 13452581923 1721347156@qq.com cs cs 2018-07-28 03:13:37 2018-07-28 03:13:37 1
4 3 2015212018 13452581923 3328118489@qq.com cs cs 2018-07-28 03:18:56 2018-07-28 03:18:56 1
分两步走,第一步,上传excel文件;第二步,解析excel文件存储到数据库中。
1、接收前端发来的excel文件,并进行存储
a、设置路由
//管理员上传账号密码的excel
$api->post('uploadpass','GamesController@uploadpass')
->name('api.uploadpass.uploadpass');
b、逻辑
config/excel.php中,修改
‘to_ascii’ => false,
use Storage;
...
$file = $request->file('userpass');
if ($file->isValid()){
$realPath = $file->getRealPath();
$gameid = $request->gameid;
$filename = $gameid.'.xls';
Storage::disk('uploads')->put($filename, file_get_contents($realPath));
}
//获取并存储到本地
然后需要从磁盘中拿出数据
$filename1 = Storage::disk('uploads')->get($filename);
//这是从excel表中拿出所有数据,而不是拿出路径
//现在我需要做的是拿出路径,可以用下面的硬编码的方法
$filename1 = 'storage\app\uploads\\'.$filename;
报错如下:
message”: “iconv(): Detected an illegal character in input string”,
这个是编码的问题,修改编码就可以了。
整个逻辑的代码
public function uploadpass(Request $request){
$this->validate($request,[
'key' => 'required',
'gameid' => 'required',
]);
$key = $request->key;
if($request->session()->has($key)){
$file = $request->file('userpass');
if ($file->isValid()){
$realPath = $file->getRealPath();
$gameid = $request->gameid;
$filename = $gameid.'.xls';
Storage::disk('uploads')->put($filename, file_get_contents($realPath));
$filename1 = 'storage\app\uploads\\'.$filename;
Excel::load($filename1, function($reader) {
$data = $reader->get();
dd($data);
});
}else{
return $this->response->array([
'info' => '文件上传失败',
'status_code' => 400,
])->setStatusCode(200);
}
}else{
return $this->response->array([
'info' => '请登录后重试',
'status_code' => 400,
])->setStatusCode(200);
}
}
我上传的数据
Copy these accounts to distribute
team_name login_id password
test01 94EC507759
your_own_nick test02 9CD1601100
your_own_nick test03 12CD24D826
your_own_nick test04 A9ACFE5D55
your_own_nick test05 FB594C4E2F
your_own_nick test06 A1BF89C1F8
your_own_nick test07 02B1305232
your_own_nick test08 7238FAD701
your_own_nick test09 0032403057
your_own_nick test10 02DFE47356
返回的结果非常奇怪,是一个html文件,关键信息如下
RowCollection {
heading: []
title: "
Sheet1"
items:
array:12 [
0 =>
CellCollection {
title:
null
items:
array:3 [
0 => "
Copy these accounts to distribute"
1 =>
null
2 =>
null
]
}
1 =>
CellCollection {
title:
null
items:
array:3 [
0 => "
team_name"
1 => "
login_id"
2 => "
password"
]
}
2 =>
CellCollection {
title:
null
items:
array:3 [
0 =>
null
1 => "
test01"
2 => "
94EC507759"
]
}
3 =>
CellCollection {
title:
null
items:
array:3 [
0 => "
your_own_nick"
1 => "
test02"
2 => "
9CD1601100"
]
}
4 =>
CellCollection {
title:
null
items:
array:3 [
0 => "
your_own_nick"
1 => "
test03"
2 => "
12CD24D826"
]
}
5 =>
CellCollection {
title:
null
items:
array:3 [
0 => "
your_own_nick"
1 => "
test04"
2 => "
A9ACFE5D55"
]
}
6 =>
CellCollection {
title:
null
items:
array:3 [
0 => "
your_own_nick"
1 => "
test05"
2 => "
FB594C4E2F"
]
}
7 =>
CellCollection {
title:
null
items:
array:3 [
0 => "
your_own_nick"
1 => "
test06"
2 => "
A1BF89C1F8"
]
}
8 =>
CellCollection {
title:
null
items:
array:3 [
0 => "
your_own_nick"
1 => "
test07"
2 => "
02B1305232"
]
}
9 =>
CellCollection {
title:
null
items:
array:3 [
0 => "
your_own_nick"
1 => "
test08"
2 => "
7238FAD701"
]
}
10 =>
CellCollection {
title:
null
items:
array:3 [
0 => "
your_own_nick"
1 => "
test09"
2 => "
0032403057"
]
}
11 =>
CellCollection {
title:
null
items:
array:3 [
0 => "
your_own_nick"
1 => "
test10"
2 => "
02DFE47356"
]
}
]
}
关键信息中包含了所有上传的东西,现在得取出来放到数据库中去
最后完成的代码
public function uploadpass(Request $request){
$this->validate($request,[
'key' => 'required',
'gameid' => 'required',
]);
$key = $request->key;
if($request->session()->has($key)){
$file = $request->file('userpass');
if ($file->isValid()){
$realPath = $file->getRealPath();
$gameid = $request->gameid;
$filename = $gameid.'.xls';
$content = Storage::disk('uploads')->get($filename);
if($content!=null){
$cunzai = 1;
}else{
$cunzai = 0;
}
Storage::disk('uploads')->put($filename, file_get_contents($realPath));
$filename1 = 'storage\app\uploads\\'.$filename;
$tablename = 'game_'.$gameid.'_pass';
Excel::load($filename1, function($reader) use ($tablename,$cunzai){
$reader = $reader->getSheet(0);
//获取表中的数据
$data = $reader->toArray();
$result = $this->create_table($tablename,$data,$cunzai);
});
return $this->response->array([
'info' => '上传成功',
'status_code' => 200,
])->setStatusCode(200);
}else{
return $this->response->array([
'info' => '文件上传失败',
'status_code' => 400,
])->setStatusCode(200);
}
}else{
return $this->response->array([
'info' => '请登录后重试',
'status_code' => 400,
])->setStatusCode(200);
}
}
//create_table代码
public function create_table($table_name,$arr_field,$chu_zai)
{
$tmp = $table_name;
$va = $arr_field;
if($chu_zai==1) Schema::drop($tmp);//加了一个判断用于避免重复生成数据表
Schema::create("$tmp", function(Blueprint $table) use ($tmp,$va)
{
$fields = $va[0]; //列字段
//$fileds_count = 0; //列数
$table->increments('id');//主键
foreach($fields as $key => $value){
if($key == 0){
$table->string($fields[$key])->nullable();//->unique(); 唯一
}else{
$table->string($fields[$key])->nullable();
}
//$fileds_count = $fileds_count + 1;
}
});
$value_str= array();
$id = 1;
foreach($va as $key => $value){
if($key != 0){
$content = implode(",",$value);
$content2 = explode(",",$content);
foreach ( $content2 as $key => $val ) {
$value_str[] = "'$val'";
}
$news = implode(",",$value_str);
$news = "$id,".$news;
DB::insert("insert into $tmp values ($news)");
//$value_str = '';
$value_str= array();
$id = $id + 1;
}
}
return 1;
}
c、测试
{
"info": "上传成功",
"status_code": 200
}
至此,用户报名、管理员下载报名信息、管理员上传账号密码的部分就写完了
下一讲 实现管理员批量给参赛者发邮件、单独发邮件