該上傳下載附件的功能是基於bootstrap fileinput組件實現的。
其源碼以及API地址如下:
bootstrap-fileinput源碼:https://github.com/kartik-v/bootstrap-fileinput
bootstrap-fileinput在線API:http://plugins.krajee.com/file-input
bootstrap-fileinput Demo展示:http://plugins.krajee.com/file-basic-usage-demo
先看一下實現的效果圖:此處與默認的上傳樣式有區別,是因為使用了【explorer】樣式的主題。
下面記錄一下具體實現步驟:
1、下載源碼,將相應js、css分別放入static目錄下,如下:主要是fileinput.min.js、fileinput.min.js、以及用於顯示中文的zh.js、主題相關theme.min.js、theme.min.css
2、在include.html中引入相應js、css
<link th:href="@{/css/bootstrap-fileinput/fileinput.min.css}" rel="stylesheet"/> <link th:href="@{/css/bootstrap-fileinput/themes/explorer/theme.min.css}" rel="stylesheet"/>
<script th:src="@{/js/plugins/bootstrap-fileinput/fileinput.min.js}"></script> <script th:src="@{/js/plugins/bootstrap-fileinput/themes/explorer/theme.min.js}"></script> <script th:src="@{/js/plugins/bootstrap-fileinput/locales/zh.js}"></script>
3、先考慮后端的實現,此處需要在數據庫中新建一張sys_attachment表,用於保存上傳圖片的相關信息,包括圖片名稱、圖片路徑等,生成語句如下:
DROP TABLE IF EXISTS `sys_attachment`; CREATE TABLE `sys_attachment` ( `id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT 'id', `business_type` varchar(40) DEFAULT NULL COMMENT '業務類型', `business_id` varchar(40) DEFAULT NULL COMMENT '業務Id', `file_path` varchar(100) DEFAULT NULL COMMENT '文件路徑', `file_name_real` varchar(100) DEFAULT NULL COMMENT '真實的文件名', `file_name_show` varchar(100) DEFAULT NULL COMMENT '顯示用的文件名', `file_size` bigint(10) DEFAULT NULL COMMENT '文件大小', `del_flag` int(10) DEFAULT NULL COMMENT '刪除標記', `create_time` datetime DEFAULT NULL COMMENT '創建時間', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=81 DEFAULT CHARSET=utf8 COMMENT='附件表';
4、后台創建sys_attachment對應的實體、mapper、service、controller文件。此處主要展示AttachmentController層代碼:
@Controller @RequestMapping("/system/attachment") public class AttachmentController extends BaseController { private String prefix = "system/attachment"; @Autowired private IAttachmentService attachmentService; @RequiresPermissions("module:attachment:view") @GetMapping() public String attachment() { return prefix + "/attachment"; } @PostMapping("/load") @ResponseBody public String load(Attachment attachment) { List<Attachment> alist = attachmentService.selectAttachmentList(attachment); JSONObject jsonObject = new JSONObject(); jsonObject.put("success", true); jsonObject.put("alist", alist); return jsonObject.toString(); } @PostMapping("/delete") @ResponseBody public AjaxResult delete(String ids) { try { return toAjax(attachmentService.deleteAttachmentByIds(ids)); } catch (Exception e) { return error(e.getMessage()); } } @PostMapping("/save") @ResponseBody public AjaxResult save(Attachment attachment) { return toAjax(attachmentService.insertAttachment(attachment)); } }
5、將附件上傳的方法,加入至 CommonController.java中
@RequestMapping("common/upload") @ResponseBody public String fileUpload(@RequestParam MultipartFile file) { JSONObject json = new JSONObject(); if(file!=null){ try { //上傳文件,返回文件名 String fileName = FileUploadUtils.upload(Global.getDownloadPath(), file); //拼裝文件名、文件路徑信息,返回json json.put("success", true); json.put("filePath", Global.getDownloadPath() + fileName); json.put("fileNameReal", fileName); json.put("fileNameShow", file.getOriginalFilename()); json.put("fileSize", file.getSize()); return json.toString(); } catch (IOException e) { json.put("success", false); json.put("msg", "上傳失敗!"); return json.toString(); } }else { json.put("success", false); json.put("msg", "請選擇附件!"); return json.toString(); } }
6、在ry-ui.js中封裝【初始化上傳附件】、【初始化編輯附件】、【執行上傳附件】、【執行下載附件】的相關js代碼。
其中相應的配置大部分都有注釋解釋了,如果需要更詳細的了解具體的參數配置詳情,可以參考:https://www.cnblogs.com/parker-yu/p/7207071.html,或查看官方API說明。
代碼內容比較多,可能還有可以優化的地方,后續可能會優化。
//文件的操作 file :{ //初始化新增附件 initAddFiles : function (ctrlName,fileType){ var control = $('#' + ctrlName); // 具體參數自行查詢 control.fileinput({ theme: "explorer", //主題 language: 'zh', //設置語言 uploadUrl: '/common/upload', //上傳的地址 enctype: 'multipart/form-data', uploadAsync: true, showUpload: false, //是否顯示上傳按鈕 showPreview: true,//是否展前預覽 dropZoneEnabled: false,//是否顯示拖拽區域 allowedFileExtensions : fileType == 'file' ? ['doc','docx','xls','xlsx','pdf','txt','ppt','zip'] : ['jpg','gif','png'],//接收的文件后綴 maxFileCount: 10, msgFilesTooMany: "選擇上傳的文件數量 超過允許的最大數值!", previewFileIcon: '<i class="fa fa-file"></i>', layoutTemplates :{ actionUpload:'',//去除上傳預覽縮略圖中的上傳圖片; actionZoom:'', //去除上傳預覽縮略圖中的查看詳情預覽的縮略圖標。 }, allowedPreviewTypes: ['image'], previewFileIconSettings: { 'doc': '<i class="fa fa-file-word-o text-primary"></i>', 'xls': '<i class="fa fa-file-excel-o text-success"></i>', 'ppt': '<i class="fa fa-file-powerpoint-o text-danger"></i>', 'pdf': '<i class="fa fa-file-pdf-o text-danger"></i>', 'zip': '<i class="fa fa-file-archive-o text-muted"></i>', 'txt': '<i class="fa fa-file-text-o text-info"></i>', }, previewFileExtSettings: { // configure the logic for determining icon file extensions 'doc': function(ext) {return ext.match(/(doc|docx)$/i);}, 'xls': function(ext) {return ext.match(/(xls|xlsx)$/i);}, 'ppt': function(ext) {return ext.match(/(ppt|pptx)$/i);}, 'zip': function(ext) {return ext.match(/(zip|rar|tar|gzip|gz|7z)$/i);}, 'txt': function(ext) {return ext.match(/(txt|ini|csv|java|php|js|css)$/i);} } }); }, //初始化編輯附件 initEditFiles : function(ctrlName,fileType,businessType,businessId){ $.ajax({ type : "post", url : "/system/attachment/load", dataType : "json", data:{ "businessType" :businessType, "businessId" : businessId }, success : function(data) { //layer.msg('操作成功!'); $.file.loadEditFiles(ctrlName,fileType,data); }, error: function(XMLHttpRequest, textStatus, errorThrown) { layer.msg('操作失敗!'); } }); }, //獲取已上傳需要編輯的附件 loadEditFiles: function (ctrlName,fileType,djson){ var control = $('#' + ctrlName); //后台返回json字符串轉換為json對象 var reData = eval(djson).alist; // 預覽圖片json數據組 var preList = new Array(); for ( var i = 0; i < reData.length; i++) { var array_element = reData[i]; // 此處指針對.txt判斷,其余自行添加 if(array_element.fileNameReal.indexOf("txt") > 0){ // 非圖片類型的展示 preList[i]= "<div class='file-preview-other-frame'><div class='file-preview-other'><span class='file-icon-4x'><i class='fa fa-file-text-o text-info'></i></span></div></div>" }else if(array_element.fileNameReal.indexOf("doc") > 0){ preList[i]= "<div class='file-preview-other-frame'><div class='file-preview-other'><span class='file-icon-4x'><i class='fa fa-file-word-o text-primary'></i></span></div></div>" }else if(array_element.fileNameReal.indexOf("xls") > 0){ preList[i]= "<div class='file-preview-other-frame'><div class='file-preview-other'><span class='file-icon-4x'><i class='fa fa-file-excel-o text-success'></i></span></div></div>" }else if(array_element.fileNameReal.indexOf("ppt") > 0){ preList[i]= "<div class='file-preview-other-frame'><div class='file-preview-other'><span class='file-icon-4x'><i class='fa fa-file-powerpoint-o text-danger'></i></span></div></div>" }else if(array_element.fileNameReal.indexOf("zip") > 0){ preList[i]= "<div class='file-preview-other-frame'><div class='file-preview-other'><span class='file-icon-4x'><i class='fa fa-file-archive-o text-muted'></i></span></div></div>" }else if(array_element.fileNameReal.indexOf("pdf") > 0){ preList[i]= "<div class='file-preview-other-frame'><div class='file-preview-other'><span class='file-icon-4x'><i class='fa fa-file-pdf-o text-danger'></i></span></div></div>" }else{ // 圖片類型 preList[i]= "<img src=\" "+ctx+"profile/download/"+array_element.fileNameReal+"\" class=\"file-preview-image\" height=\"80\" width=\"80\">"; } } var previewJson = preList; // 與上面 預覽圖片json數據組 對應的config數據 var preConfigList = new Array(); for ( var i = 0; i < reData.length; i++) { var array_element = reData[i]; var tjson = { caption: array_element.fileNameShow, // 展示的文件名 size : array_element.fileSize, width: '120px', url: '/system/attachment/delete', // 刪除url key: array_element.fileNameReal, // 刪除是Ajax向后台傳遞的參數 extra: {ids: array_element.id} }; preConfigList[i] = tjson; } // 具體參數自行查詢 control.fileinput({ theme: "explorer", language: 'zh', //設置語言 uploadUrl: '/common/upload', //上傳的地址 enctype: 'multipart/form-data', uploadAsync: true, showUpload: false, //是否顯示上傳按鈕 showPreview: true,//是否展前預覽 dropZoneEnabled: false,//是否顯示拖拽區域 showRemove:false, //是否顯示移除按鈕 allowedFileExtensions : fileType == 'file' ? ['doc','docx','xls','xlsx','pdf','txt','ppt','zip'] : ['jpg','gif','png'],//接收的文件后綴 maxFileCount: 10, msgFilesTooMany: "選擇上傳的文件數量 超過允許的最大數值!", previewFileIcon: '<i class="fa fa-file"></i>', layoutTemplates :{ actionUpload:'',//去除上傳預覽縮略圖中的上傳圖片; actionZoom:'', //去除上傳預覽縮略圖中的查看詳情預覽的縮略圖標。 }, allowedPreviewTypes: ['image'], initialPreview: previewJson, initialPreviewConfig: preConfigList, otherActionButtons:'<button type="button" class="kv-file-down btn btn-sm btn-default" data-key = {key} onclick="$.file.download(this)" title="下載附件"><i class="fa fa-cloud-download"></i></button>', previewFileIconSettings: { 'doc': '<i class="fa fa-file-word-o text-primary"></i>', 'xls': '<i class="fa fa-file-excel-o text-success"></i>', 'ppt': '<i class="fa fa-file-powerpoint-o text-danger"></i>', 'pdf': '<i class="fa fa-file-pdf-o text-danger"></i>', 'zip': '<i class="fa fa-file-archive-o text-muted"></i>', 'htm': '<i class="fa fa-file-code-o text-info"></i>', 'txt': '<i class="fa fa-file-text-o text-info"></i>', 'mov': '<i class="fa fa-file-video-o text-warning"></i>', 'mp3': '<i class="fa fa-file-audio-o text-warning"></i>', 'jpg': '<i class="fa fa-file-photo-o text-danger"></i>', 'gif': '<i class="fa fa-file-photo-o text-muted"></i>', 'png': '<i class="fa fa-file-photo-o text-primary"></i>' }, previewFileExtSettings: { // configure the logic for determining icon file extensions 'doc': function(ext) {return ext.match(/(doc|docx)$/i);}, 'xls': function(ext) {return ext.match(/(xls|xlsx)$/i);}, 'ppt': function(ext) {return ext.match(/(ppt|pptx)$/i);}, 'zip': function(ext) {return ext.match(/(zip|rar|tar|gzip|gz|7z)$/i);}, 'htm': function(ext) {return ext.match(/(htm|html)$/i);}, 'txt': function(ext) {return ext.match(/(txt|ini|csv|java|php|js|css)$/i);}, 'mov': function(ext) {return ext.match(/(avi|mpg|mkv|mov|mp4|3gp|webm|wmv)$/i);}, 'mp3': function(ext) {return ext.match(/(mp3|wav)$/i);} } }); }, //執行上傳附件 uploadFile : function(ctrlName,businessType,businessId){ var control = $('#' + ctrlName); var file = control.val(); if(file != '' ){ //執行上傳 control.fileinput("upload"); //上傳成功后的處理 control.on("fileuploaded", function(event, outData) { var result = outData.response; var filePath = result.filePath; var fileNameReal = result.fileNameReal; var fileNameShow = result.fileNameShow; var fileSize = result.fileSize; $.ajax({ cache : true, type : "POST", url : "/system/attachment/save", data : { "businessType" : businessType, "businessId" : businessId, "filePath" : filePath, "fileNameReal" : fileNameReal, "fileNameShow" : fileNameShow, "fileSize" : fileSize, "delFlag" : '0' }, async : false, error : function(request) { }, success : function(data) { } }); }) } }, //執行下載附件 download : function(obj){ var $btn = $(obj),dataKey = $btn.data('key'); if(dataKey == false){ layer.msg('暫未上傳,無法下載!'); }else{ window.location.href="/common/download?fileName="+dataKey; } }
}
7、頁面調用。
在新增頁面上:
<div class="form-group"> <label class="col-sm-3 control-label">附件上傳:</label> <div class="col-sm-8"> <input id="file-Portrait" type="file" multiple="multiple" name="file"> </div> </div>
$(function() { //初始化上傳組件 $.file.initAddFiles("file-Portrait","file");
});
使用ajax保存相應業務數據成功后,調用上傳組件:
注意此處可以從data中獲取businessId,需要覆寫一下toAjax方法,需要將業務保存后的Id傳入該json中,以便獲取。
$.ajax({ cache : true, type : "POST", url : prefix + "/add", data : $('#form-notice-add').serialize(), async : false, error : function(request) { $.modal.alertError("系統錯誤"); }, success : function(data) { var businessId = data.businessId; $.file.uploadFile("file-Portrait","notice",businessId); $.operate.saveSuccess(data); } });
對於編輯頁面上:
$(function() {
var businessId = $("#noticeId").val(); $.file.initEditFiles("file-Portrait","file","notice",businessId); });
自此上傳與下載的功能基本實現了!