1. 程式人生 > >ThinkPHP匯入檔案並上傳與檔案下載

ThinkPHP匯入檔案並上傳與檔案下載

在做網站專案時必不可少就是匯入檔案將資料傳進資料表中,並將插入資料寫入日誌檔案並下載。下面是我的程式碼與心得。

第一步:給表單中的input新增一個name屬性為file,action設定為當前控制器下的upload方法,特別注意:一定要在表單中寫入enctype="multipart/form-data

<form role="form" method="post" action="__URL__/upload" enctype="multipart/form-data">
	<div class="modal-body">
		<div class="form-group">
			<input type="file" id="inputfile" name="file">
		</div>
	</div>
	<div class="modal-footer">
		<button type="button" class="btn btn-default" data-dismiss="modal">關閉</button>
		<button type="submit" class="btn btn-primary">匯入</button>
	</div>
</form>

第二步:在當前控制器下新建upload方法,先判斷是否為post方式提交,如果不是則退出;設定上傳檔案的屬性如大小、字尾、根目錄等,呼叫Think模組的Upload方法,上傳檔案,失敗則提示。最後呼叫import方法,並將檔案路徑作為引數傳遞過去。

public function upload(){
	if(IS_GET){
		$this->display();
		exit;
	}
	$upload = new \Think\Upload();//例項化上傳類
	$upload->maxSize = 0 ;//設定附件上傳大小
	$upload->exts = array('csv');//設定附件上傳型別
	$upload->rootPath = './Public/Upload/'; //設定附件上傳根目錄
	$upload->savePath = '';//設定附件上傳(子)目錄
	// 上傳檔案
	$info = $upload->upload();
	if(!$info) {//上傳錯誤提示錯誤資訊
		$this->error($upload->getError());
	}else{//上傳成功
		// $this->success('上傳成功!' . $info['file']['savepath'] . $info['file']['savename']);
		$file = './Public/upload/' . $info['file']['savepath'] . $info['file']['savename'];//檔案的完整路徑
		$this->import($file);//呼叫import方法
	}
}

第三步:先檢測檔案編碼是否為utf8格式(檢測編碼格式的函式將在下文展示),因為學號為主鍵不能重複,所以要檢測匯入檔案中的學號是否已經存在,要將資料表中的學號提出來放到一個數組中,再將檔案裡的學號插入到陣列中,無論是否存在都將資訊寫入到日誌檔案中,並下載。

public function import($file){
    //檢測檔案編碼
    $encoding=detect_encoding($file);
    //如果不是utf8格式,則轉化為utf8
    if($encoding !='UTF-8'){
    	$contents=file_get_contents($file);
    	$contents=mb_convert_encoding($contents, 'utf-8',$encoding);
    	file_put_contents($file, $contents);
    }
    $fp=fopen($file,'r');
		if($fp){
			$fields=array('no','name','sex');
			$model=M('student');
			$arrno=$model->getField('no',true);
			// dump($arrno);
			// exit;
			$arr=array();
            $file = 'log.txt';
			$file = fopen($file, 'w');
			while(($row=fgetcsv($fp,1000,","))!==false){
				$row=array_combine($fields, $row);
				if(in_array($row['no'],$arrno)){
				  $content = $row['no'] . "已存在" . PHP_EOL;
				}else{
                   $arrno[] = $row['no'];
                   $name = $row['name'];
                   $py = SpGetPinyin($name);
					   $row['py'] = $py;
					   $password = '123456';
					   $row['password'] = md5($password);
					   $create_time = intval(time());
					   $row['create_time'] = $create_time;
                   $arr[] = $row;
                   $content = $row['no'] . "匯入成功" .PHP_EOL;
				}
                fwrite($file, $content);
				// dump($row);
				if(count($arr) == 1000){
					$model->addAll($arr);
					unset($arr);
				}
			}
			fclose($file);
			if(count($arr)>0){
				$model->addAll($arr);
			}
			// $this->success('新增成功');
			$this->download();
		}
}
第五步:先定義要下載的檔名稱和存放目錄,使用file_exists()函式檢測檔案是否存在,使用header設定各種屬性用來顯示都愛瀏覽器中即可完成
// 檔案下載
protected function download(){
	$file_name = "log.txt";     //下載檔名    
	$file_dir = ROOT . "/";   //下載檔案存放目錄  
	echo $file_dir . $file_name;
	//檢查檔案是否存在    
	if (! file_exists ( $file_dir . $file_name )) {    
	    echo "檔案找不到";    
	    exit ();    
	} else {    
	    //開啟檔案    
	    $file = fopen ( $file_dir . $file_name, "r" );    
	    //輸入檔案標籤     
	    Header ( "Content-type: application/octet-stream" );    
	    Header ( "Accept-Ranges: bytes" );    
	    Header ( "Accept-Length: " . filesize ( $file_dir . $file_name ) );    
	    Header ( "Content-Disposition: attachment; filename=" . $file_name );    
	    //輸出檔案內容     
	    //讀取檔案內容並直接輸出到瀏覽器    
	    echo fread ( $file, filesize ( $file_dir . $file_name ) );    
	    fclose ( $file );    
	    exit ();    
	}     
}

效果: