-
背景
前段時間因爲業務需求,涉及到了多種文件的上傳操作;
其中,包含 圖片、Excel文件、視頻文件
比如:我需要進行excel
表格文件的上傳,然後讀取其中的數據寫入數據庫
那麼,至少要限制一下上傳文件的類型
在此,進行整理一番,歡迎指摘 … -
環境
- 前端框架:Layui 2.5.4
- 使用框架:ThinkPHP 5.1.2
- 文件類型:image、excel、video
- 前端配置
前提自然是先要對
layui
前端框架的正確引用,個人使用的版本是:2.5.4
<link href="__LAYUI__/css/layui.css" rel="stylesheet">
<!--採用模塊化方式-->
<script type="text/javascript" src="__LAYUI__/layui.js"></script>
<!-- jQuery (necessary JavaScript plugins) -->
<script type='text/javascript' src="__LAYUI__/jquery-3.2.1.min.js"></script>
☛. 圖片文件的上傳操作
- 首先,是
html
頁面的標籤佈局設計
<div class="layui-upload layui-input-inline">
<button type="button" name="img_upload" class="layui-btn btn_upload_img">
<i class="layui-icon"></i>上傳圖片
</button>
<img class="layui-upload-img img-upload-preview-medium img-upload-view"
src="">
<input type="hidden" name="cover_url" class="menu-icon" value="">
</div>
- 其次是對應的
js
代碼的設計
layui.use(['layer','upload'], function () {
var upload = layui.upload;
//指定允許上傳的文件類型
upload.render({
elem: '.btn_upload_img'
, type: 'images'
, exts: 'jpg|png|gif|jpeg' //設置一些後綴,用於演示前端驗證和後端的驗證
, url: '/api/upload/img_file' //TODO 此爲服務端上傳接口
, data: {'_token': tag_token}
, before: function (obj) {
//預讀本地文件示例,不支持ie8
obj.preview(function (index, file, result) {
$('.img-upload-view').attr('src', result); //圖片鏈接(base64)
});
}
, done: function (res) {
layer.msg(res.message);
//如果上傳成功
if (res.status == 1) {
$('.menu-icon').val(res.data.url);
}
}
, error: function () {
//演示失敗狀態,並實現重傳
return layer.msg('上傳失敗,請重新上傳');
}
});
});
- 服務端對應的上傳接口代碼參考如下:
/**
* 單一圖片的上傳操作
* @param Request $request
*/
public function img_file(Request $request)
{
$status = 0;
$data = [];
if ($request->Method()== 'POST') {
$file = $request->file('file');
// 移動到框架應用根目錄/upload/ 目錄下
$info = $file->move('upload');
if ($info){
//把反斜槓(\)替換成斜槓(/) 因爲在windows下上傳路是反斜槓徑
$getSaveName = str_replace("\\", "/", $info->getSaveName());
$fileUrl = '/upload/' . $getSaveName;
$data['url'] = $fileUrl;
$message = '上傳成功';
}else{
$message = "上傳失敗 ".$file->getError();
}
} else {
$message = "參數錯誤";
}
return showMsg($status, $message,$data);
}
- 參考截圖:
☛. Excel文件的上傳操作
- 首先,便是頁面標籤的佈局
<button type="button"
class="layui-btn" id="uploadExcel">
<i class="layui-icon"></i>上傳物流訂單
</button>
- 然後,需要對
js
的代碼進行配置
layui.use(['layer','upload'], function () {
var upload = layui.upload;
//指定允許上傳的文件類型
upload.render({
elem: '#uploadExcel'
,url: '/api/upload/file_excel' //此處爲所上傳的請求路徑
,accept: 'file' //普通文件
,exts: 'xls|excel|xlsx' //只允許上傳壓縮文件
,done: function(res){
console.log(res)
layer.msg(res.message);
}
});
});
- 接下來,便是對所獲取的
excel
文件的解析處理,以我的ThinkPHP5.1.2
處理代碼爲例
/**
* 進行excel文件的上傳讀取操作
* @param Request $request
*/
public function file_excel(Request $request){
$status = 0;
if ($request->Method() == 'POST') {
$file = $request->file('file');
// 移動到框架應用根目錄/upload/ 目錄下
$info = $file->move('upload');
if ($info) {
//把反斜槓(\)替換成斜槓(/) 因爲在windows下上傳路是反斜槓徑
$getSaveName = str_replace("\\", "/", $info->getSaveName());
$fileUrl = './upload/' . $getSaveName;
//TODO 此時進行數據的解析,個人業務邏輯,此處應該修改爲你自己的邏輯
$orderModel = new XorderGoods();
$status = 1;
$message = $orderModel->ajaxDealExcelOrder($fileUrl);
} else {
$message = "上傳失敗 " . $file->getError();
}
} else {
$message = "參數錯誤";
}
return showMsg($status, $message);
}
- 後續的數據處理,請參考:【
ThinkPHP5.1 excel表的導入導出操作 (PHPExcel)
】
☛. 視頻文件的上傳操作
爲了應對大文件的上傳,補充設計了,進度條展示效果
- 首先,是
html
頁面的標籤佈局設計,參考如下:
<div class="layui-form-item">
<label class="layui-form-label">視頻:</label>
<div class="layui-upload layui-input-block">
<button type="button" name="video_upload" class="layui-btn btn_upload_video">
<i class="layui-icon"></i>上傳視頻
</button>
<br><br>
<div class="layui-progress layui-progress-big" lay-showpercent="true" lay-filter="progressBar">
<div id="progressBar" pb_loading_tag="1" class="layui-progress-bar layui-bg-red" lay-percent="0%"></div>
</div>
<br>
<video class="video-upload-view" src="" controls="controls" style="display: none"></video>
<input type="hidden" name="save_url" class="save_url" value="">
</div>
</div>
- 然後是對應的
js
代碼編寫
layui.use(['layer','upload','element'], function () {
var upload = layui.upload;
var element = layui.element;
var loading_count = 0;
upload.render({
elem: '.btn_upload_video'
,exts: 'mp4|flv' //設置一些後綴,用於演示前端驗證和後端的驗證
,url: '/api/upload/video_file' //改成您自己的上傳接口
,accept: 'video' //視頻
, before: function (obj) {
loading_count = 0;
$("#progressBar").attr('pb_loading_tag',1);
element.progress('progressBar', '0%');
//預讀本地文件示例,不支持ie8
obj.preview(function (index, file, result) {
$('.video-upload-view').attr('src', result); //圖片鏈接(base64)
$('.video-upload-view').show();
});
},
progress: function() {
//模擬loading
var timer = setInterval(function(){
var loading = $("#progressBar").attr('pb_loading_tag');
if(loading == 1){
loading_count = loading_count + Math.random()*10|1;
if(loading_count>98){
loading_count = 98;
}
}else {
loading_count = 100;
clearInterval(timer);
}
//這裏是虛擬的哦,其實就是爲了能提示一下沒上傳完就可以了,哈哈...
element.progress('progressBar', loading_count+'%');
}, 300+Math.random()*1000);
}
,done: function(res){
//如果上傳成功
if (res.status == 1) {
$('.save_url').val(res.data.url);
$("#progressBar").attr('pb_loading_tag',0);
}
layer.msg(res.message);
}
});
});
- 服務端的接口,可完全借用前面提到的 圖片上傳代碼
如果文件比較大,需要更改一下php.ini 和 nginx.conf
配置文件的一些東西(可百度哦)
有能力的,可以搜索數據片上傳的方法,提高上傳效率!
- 實現效果截圖:
【提示
】
這裏的進度條上傳是虛擬的哦,其實就是爲了能提示一下沒上傳完就可以了,哈哈…
附錄:
- 1 .
showMsg
公共方法
/**
* 公用的方法 返回json數據,進行信息的提示
* @param $status 狀態
* @param string $message 提示信息
* @param array $data 返回數據
*/
function showMsg($status,$message = '',$data = array()){
$result = array(
'status' => $status,
'message' =>$message,
'data' =>$data
);
exit(json_encode($result));
}
- 2 . 如果操作,上傳的文件會默認保存到了
/public/upload
目錄下
一般而言,後期會考慮將各種文件統一使用 FTP 上傳到資源服務器;
屆時可以對鄙人所提供的上傳接口進行優化升級即可 …