##从前台获取文件:
//用来显示选择的文件
//隐藏的存文件的目录
前台获取文件为3个input框:
第一个type=“text”,用来显示获取到文件的路径;
第二个type="button"点击按钮;
第三个type="file"隐藏的获取文件的表单。
流程:
当button 触发click事件,则调用$(’#i-file’).click();触发file,当file类型的input获取到值(文件路径),则change事件将路径值显示在location。
jQuery的 .val() - 设置或返回表单字段的值。
##后台接收文件:
获取:
通过调用request对象的file()方法获取。
if(request()->isPost()){
$file = request()->file('examfile');
if (!$file)
{
return $this->error('未选择任何文件','JoinController/joinMultiple');
}
}
移动(上传):
内置的上传只是上传到本地服务器,上传到远程或者第三方平台的话需要自己扩展。
// 移动到框架应用根目录/public/uploads/ 目录下
$file_url = ROOT_PATH . 'public' . DS . 'upload'; //. DS . 'excel'
$config = [
'size' => 2097152,
'ext' => 'xlsx,xls'
];
$info = $file->validate($config)->move($file_url); //2MB
其中validata()是一个格式验证,传入参数为最大字节size和限定的后缀ext;
/**
* 设置上传文件的验证规则
* @param array $rule 验证规则
* @return $this
*/
public function validate($rule = [])
{
$this->validate = $rule;
return $this;
}
move 方法成功的话返回的是一个 \think\File 对象,你可以对上传后的文件进行后续操作,
move方法如果只传入一个路径则默认会在目录下生成时间目录,且文件名为自动生成的。
例如:20180926\bbc624371e90924a8483b5421acc2e43.xlsx
时间目录20180926下的这个文件
如果不想生成时间目录,且用原始文件名,则通过传入其他参数。
原始文件名采用:move($file_url,'')
/**
* 移动文件
* @param string $path 保存路径
* @param string|bool $savename 保存的文件名 默认自动生成
* @param boolean $replace 同名文件是否覆盖
* @return false|SplFileInfo false-失败 否则返回SplFileInfo实例
*/
public function move($path, $savename = true, $replace = true)
后续操作:
对move()方法获取到的返回值$info可以执行:
好的可以获取文件地址通过:
$url=$info->getSaveName();
注意:在文档中查到
getSaveName 方法返回的是图片的服务器文件地址,并不能直接用于图片的URL地址,尤其在 windows平台上必须做转换才能正常显示图片。
所以正确的获取路径的方法为:
$url=$info->getSaveName();
$file_url .= "\\" . $url;
getSaveName()
得到的其实就是文件名加后缀名,要得到的file_url为可用的URL地址。则
$file_url .= "\\" . $url
其中 **.=**为连接符 ,双斜杠为转义字符,本意为单斜杆。
则将**$file_url**传入到真正的文件文件处理的方法中,这里是import()方法。
上述过程完整代码:
public function upload()
{
if(request()->isPost()){
$file = request()->file('examfile');
if (!$file)
{
return $this->error('未选择任何文件','JoinController/joinMultiple');
}
// 移动到框架应用根目录/public/uploads/ 目录下
$file_url = ROOT_PATH . 'public' . DS . 'upload'; //. DS . 'excel'
$config = [
'size' => 2097152,
'ext' => 'xlsx,xls'
];
$info = $file->validate($config)->move($file_url); //2MB
if ($info) {
$url=$info->getSaveName();
$file_url .= "\\" . $url;
try{
chmod($file_url, 0777);
}catch(\Exception $e){}
$result = $this->import($file_url,$info->getExtension());
try{
//使用文件对象的时候没有完全关闭句柄,导致无法删除该文件。
//解决方法只需要在上传逻辑完成之后清空释放一下变量 会在public/upload下多一些空文件夹
unset($info);
unlink($file_url);
}catch(\Exception $e){}
if (!$result) //为""
{
return $this->success('导入成功','JoinController/joinMultiple');
}else
{
return $this->error($result,'JoinController/joinMultiple');
}
} else {
// 上传失败获取错误信息
return $this->error($file->getError(),'JoinController/joinMultiple');
}
}else
{
return $this->error("非法请求",'JoinController/joinMultiple');
}
}
##处理文件:
我处理的为Excel文件,经过上述步骤将一个Excel的URL地址,和其扩展名传入了处理函数import()。
一.PHPExcel的安装和引用:
注意在处理之前必须采用使用composer安装PHPExcel。
教程
Git地址
use一下全套服务:
use PHPExcel;
use PHPExcel_IOFactory;
use PHPExcel_Cell;
或者:
//引入PHPExcel
header("content-type:text/html; charset=utf-8");
vendor("phpoffice.phpexcel.Classes.PHPExcel");
就完成了引用!
二.开始处理:
1.通过实例化的PHPExcel_IOFactory对象调用createReader()方法获得Reader对象;
$PHPReader = PHPExcel_IOFactory::createReader('Excel5'); //use excel2007 for 2007 format
2.Reader对象的load方法调用URL地址获取到存放文件内容的PHPExcel;
$PHPExcel = $PHPReader->load($filename);
3.通过PHPExcel的getActiveSheet方法获取sheet当前工作sheet
sheet可以存在多个,通过索引getActiveSheet(0)
$sheet = $PHPExcel->getActiveSheet(0);//获得sheet
$highestRow = $sheet->getHighestRow(); // 取得共有数据数
4.将sheet转化为数组进行处理,则Excel中的内容就变成了一个二维数组,方便处理了。
$data=$sheet->toArray();
上述过程完整代码:
/** 对xlsx文件解析处理,写入数据库
* @param $filename 文件路径
* @param $ext 文件后缀
* @return string 处理结果
*/
private function import($filename,$ext){
//引入PHPExcel
header("content-type:text/html; charset=utf-8");
vendor("phpoffice.phpexcel.Classes.PHPExcel");
//文件导入
if ($ext == 'xls')
$PHPReader = PHPExcel_IOFactory::createReader('Excel5'); //use excel2007 for 2007 format
else
$PHPReader = PHPExcel_IOFactory::createReader('Excel2007');
//载入excel文件
try{
$PHPExcel = $PHPReader->load($filename);
}catch(\Exception $e)
{
return '您使用的文件可能为改变文件扩展名之后的Excel文件';
}
$sheet = $PHPExcel->getActiveSheet(0);//获得sheet
$highestRow = $sheet->getHighestRow(); // 取得共有数据数
$data=$sheet->toArray();
$res=$this->checkExcel($data); //结果 检查上传的Excel是否合格
if ($res) //不为"" ,即不通过
{
return $res;
}
$hyjyzlb = new Hyjyzlb();
$yearId = $hyjyzlb->getId(); //Hyjyzlb表的id
if (!$yearId) //无合适数据
{
return "该时间不能报名";
}
$arr['YEAR_ID'] = $yearId; //报名年份
$arr['DEPTID'] = Session::get('DEPTID','think');// 院系ID
$join = new Join();
$unit = new Unit();
for($i=1;$i<$highestRow;$i++){
if(!$data[$i][0]||!$data[$i][1]||!$data[$i][2])//学号,姓名性别不全的跳过
{
continue;
}
$arr['XH'] = $data[$i][0];//学号
$arr['XM'] = $data[$i][1]; //姓名
if ($data[$i][2]=='男') //0:男 1:女
{
$arr['GENDER'] = 0;
}
else if ($data[$i][2]=='女'){
$arr['GENDER'] = 1;
}else
{
continue;
}
for ($j=3;$j$data[0][$j],
'GENDER' =>$arr['GENDER']
];
$unitInfo = $unit->select($where);
if (!$unitInfo) //数据库没有相关项目
{
continue;
}else
{
$arr['UNIT_ID'] = $unitInfo->ID;
}
$where=[
'XH'=>$data[$i][0],
'YEAR_ID'=>$yearId,
'UNIT_ID'=>$unitInfo->ID, //运动项目id
];
$joinInfo = $join->select($where);
if (!$joinInfo) //数据库没有相关报名
{
$maxs = $join->getMaxNumber($yearId);
$arr['NUMBER'] = sprintf("%04d\n", intval($maxs)+1); //比赛号码
$join->insertOneJoin($arr);
}
}
}
}
return $res;
}
注意:
**checkExcel()**为检查表头是否和标准Excel表相同;
**insertOneJoin()**往数据库插数据。
##最后
终于完了,有点长,写的头皮发麻。