文件上传预览插件 Bootstrap-fileinput组件封装及使用

来源:互联网 发布:linux scp拷贝文件 编辑:程序博客网 时间:2024/05/29 14:51

介绍

通过本文,你可以学习到如何封装或者开发一个前端组件,同时学习Bootstrap-fileinput组件的使用,封装后使用更加简单方便。

BaseFile组件 
BaseFile是AdminEAP框架中基于Bootstrap-fileinput的附件上传组件,它支持 支持多文件、在线预览、拖拽上传等功能,封装后BaseFile主要包括以下功能:

  • 弹出窗口的附件上传
  • 当前界面的附件上传
  • 显示附件明细
  • 可编辑的附件明细(删除、预览、不可新增)

关于Bootstrap-fileinput的API文档可参考http://plugins.krajee.com/file-input

本文源码已在AdminEAP框架(一个基于AdminLTE的Java开发平台)中开源,可在Github下载相关代码:

Github:https://github.com/bill1012/AdminEAP

AdminEAP官网:http://www.admineap.com

使用说明

1、初始化

如果需要在当前界面使用附件上传功能(非弹窗方式)则需要在头部引入相关的css和js文件

  • css文件
<link rel="stylesheet" href="./resources/common/libs/fileinput/css/fileinput.min.css">
  • 1
  • 1
  • js文件
<script src="./resources/common/libs/fileinput/js/fileinput.js"></script><script src="./resources/common/libs/fileinput/js/locales/zh.js"></script><!--BaseFile组件--><script src="./resources/common/js/base-file.js"></script>
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

form表单上还需要配置enctype="multipart/form-data"属性

2、弹窗方式调用

BaseFile支持弹窗方式打开一个附件上传窗口,点击附件上传后,弹出窗口,上传附件关闭窗口后,上传的附件在type=file的控件回填。

在表单中点击弹窗上传附件: 
弹窗上传

弹窗上传附件

上传完毕,关闭窗口,附件回填 
附件回显

再次打开上传附件上传窗口时,会把已有的附件回填到附件上传窗口。

配置如下:

  • html代码
          <input type="hidden" name="fileIds" id="fileIds">          <div class="form-group">                <div class="btn btn-default btn-file" id="uploadFile">                    <i class="fa fa-paperclip"></i> 上传附件(Max. 10MB)                </div>            </div>            <div class="form-group" id="file_container">                <input type="file" name="file"  id="attachment">            </div>    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • js代码
$("#uploadFile").file({            title: "请上传附件",            fileinput: {                maxFileSize: 10240,                maxFileCount:3            },            fileIdContainer:"[name='fileIds']",            showContainer:'#attachment',            //显示文件类型 edit=可编辑  detail=明细 默认为明细            showType:'edit',            //弹出窗口 执行上传附件后的回调函数(window:false不调用此方法)            window:true,            callback:function(fileIds,oldfileIds){                //更新fileIds                this.showFiles({                    fileIds:fileIds                });            }        });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

3、本地界面调用

本地界面调用附件上传,如下图所示:

将上传附件嵌入到当前界面方式 
内嵌附件上传

上传后的附件可删除、可预览 
上传后

预览 
(目前图片文件可预览,其他文件不可预览,后期将集成txt/xml/html/pdf的预览功能)

配置如下:

  • html代码
<div class="form-group" id="file_container">      <input type="file" name="file"  id="attachment"></div>
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3
  • js代码
    $("#attachment").file({            fileinput: {                maxFileSize: 10240,                maxFileCount:3            },            fileIdContainer:"[name='fileIds']",            window:false        });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4、控件参数说明

  • window 默认为true,弹窗方式打开

  • title window=true时配置,弹窗的标题,默认为“文件上传”

  • width window=true时配置,弹窗的宽度,默认900

  • winId window=true时配置,弹出的id,默认为fileWin

  • fileinput Bootstrap-fileinput的配置参数,会覆盖默认配置,比如允许上传哪种类型的附件allowedFileTypes,允许上传最大附件大小maxFileSize,允许上传附件的个数maxFileCount等,具体的配置参数可以查询Bootstrap-fileinput的API文档。

  • fileIdContainer 必须,上传后的附件id存储的位置,id以逗号分隔

  • showContainer window=true必须配置,文件上传后回填的区域,window=false时如不配置,则取base-file的初始对象

  • showType window=true配置,值为edit或者detail,edit表示回填后可对数据进行删除、预览,detail只能显示,不能删除

  • callback window=true配置,关闭附件上传的窗口后执行的回调函数(比如更新当前的文件列表),fileIds,oldfileIds两个参数分别是更新后文件ids和更新前的文件ids

  • BaseFile默认配置,BaseFile的更多实现,请查看BaseFile源码

BaseFile.prototype.default = {        winId: "fileWin",        width: 900,        title: "文件上传",        //通用文件上传界面        url: basePath + "/file/uploader",        //默认支持多文件上传        multiple: true,        //默认弹出附件上传窗口        window:true,        showType:"detail",        fileinput: {            language: 'zh',            uploadUrl: basePath + "/file/uploadMultipleFile",            deleteUrl:basePath+"/file/delete",            uploadAsync:false,            validateInitialCount:true,            overwriteInitial: false,            allowedPreviewTypes: ['image'],            previewFileIcon:'<i class="fa fa-file-o"></i>',            previewFileIconSettings: null,            slugCallback: function (text) {                var newtext=(!text||text=='') ? '' : String(text).replace(/[\-\[\]\/\{}:;#%=\(\)\*\+\?\\\^\$\|<>&"']/g, '_');                //去除空格                return newtext.replace(/(^\s+)|(\s+$)/g,"").replace(/\s/g,"");            }        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

5、BaseFile控件源码

/** * 通用文件管理组件 * @author billjiang qq:475572229 */(function ($, window, document, undefined) {    'use strict';    var pluginName = 'file';    $.fn[pluginName] = function (options) {        var self = $(this);        if (this == null)            return null;        var data = this.data(pluginName);        if (!data) {            data = new BaseFile(this, $.extend(true, {}, options));            self.data(pluginName, data);        }    };    var BaseFile = function (element, options) {        this.element = element;        //extend优先级 后面的会覆盖前面的        //alert(this.element.selector);        //将容器ID传过去便于弹窗获取到BaseFile对象,如果页面布局不在使用jquery.load方法,则该方法会失效,因为不是一个页面了        options.container = options.container || this.element.selector.replace("#", "");        //初始化文件图标信息        this.getFileIconSettings();        this.options = $.extend(true, {}, this.default, options);        //初始化图标信息        this.initFileIds();        if(this.options.window) {            this.element.click(function () {                $(this).data('file').openWin();            });        }else{            //非弹窗形式            if(this.options.multiple)                this.element.attr("multiple","multiple");        }        //如果配置了附件编辑容器showContainer(附件列表,可单个删除),则进行初始化        if(this.hasDisplayZone()){            this.showFiles();        }    }    BaseFile.prototype.default = {        winId: "fileWin",        width: 900,        title: "文件上传",        //通用文件上传界面        url: basePath + "/file/uploader",        //默认支持多文件上传        multiple: true,        //默认弹出附件上传窗口        window:true,        showType:"detail",        fileinput: {            language: 'zh',            uploadUrl: basePath + "/file/uploadMultipleFile",            deleteUrl:basePath+"/file/delete",            uploadAsync:false,            validateInitialCount:true,            overwriteInitial: false,            allowedPreviewTypes: ['image'],            previewFileIcon:'<i class="fa fa-file-o"></i>',            previewFileIconSettings: null,            slugCallback: function (text) {                var newtext=(!text||text=='') ? '' : String(text).replace(/[\-\[\]\/\{}:;#%=\(\)\*\+\?\\\^\$\|<>&"']/g, '_');                //去除空格                return newtext.replace(/(^\s+)|(\s+$)/g,"").replace(/\s/g,"");            }        }    }    BaseFile.prototype.getFileInputConfig=function () {        return this.options.fileinput;    }    BaseFile.prototype.getFileIconSettings = function () {        var self = this;        ajaxPost(basePath + "/file/icons", null, function (icons) {            self.previewFileIconSettings = icons;            //console.log(self.previewFileIconSettings);        })    }    BaseFile.prototype.openWin = function () {        var that = this;        var self = $.extend(true, {}, this.options);        //深拷贝后删除属性,这样不会通过后台传送过去,防止被XSS过滤掉特殊字符        //不需要通过参数config=传递到弹窗的参数可使用delete删除        delete self.callback;        delete self.fileIds;        delete self.showContainer;        delete self.fileIdContainer;        delete self.fileinput;        /*console.log(this.options);         console.log("=============");         console.log(self);*/        modals.openWin({            winId: that.options.winId,            url: that.options.url + "?config=" + JSON.stringify(self),            width: that.options.width + "px",            title: that.options.title,            backdrop: "static"        });    }    BaseFile.prototype.callbackHandler = function (fileIds) {        //更新fileIds并执行回调函数        var oldfileIds = this.options.fileIds;        this.options.fileIds = fileIds;        this.updateFileIds();        if (this.options.callback) {            this.options.callback.call(this, fileIds, oldfileIds);        }    }    //调用成功后执行显示附件    BaseFile.prototype.showFiles=function(options){        options=options||{};        if(!this.hasDisplayZone()){            modals.error("请配置showContainer属性,并在容器下配置type=file的input组件");            return;        }        var fileIds=options.fileIds||this.options.fileIds;        if(!fileIds&&this.options.window){           $(this.options.showContainer).hide();            return;        }        //显示        $(this.options.showContainer).show();        var fileComponet=$(this.options.showContainer);        var fileResult=this.getFileResult(fileIds),preview=fileResult.initialPreview,previewConfig=fileResult.initialPreviewConfig,self=this;        //配置三类参数 edit=附件列表(可删除) detail=附件列表(显示) 可上传        var defaultConfig={            initialPreview:preview,            initialPreviewConfig:previewConfig        };        var config;        if(this.options.window){            if(this.options.showType=="edit"){                //全局配置->本方法默认配置->edit属性下配置->外部参数                config=$.extend({},self.options.fileinput,defaultConfig,{                    showRemove:false,                    showUpload:false,                    showClose:false,                    showBrowse:false,                    showCaption:false                },options);            }else if(this.options.showType=="detail"){                config=$.extend({},self.options.fileinput,defaultConfig,{                    showRemove:false,                    showUpload:false,                    showClose:false,                    showBrowse:false,                    showCaption:false,                    initialPreviewShowDelete:false                },options);            }        }else{            config=$.extend({},self.options.fileinput,defaultConfig,{                showClose:false            },options);        }        if(!config){            modals.error("未找到showFiles中的相关配置");            return;        }        //console.log("config=========="+JSON.stringify(config));        fileComponet.fileinput('destroy');        fileComponet.fileinput(config).on("filedeleted",function (event,key) {            var newfids=self.deleteFileIds(key,self.options.fileIds);            self.options.fileIds=newfids;            self.updateFileIds();        }).on("fileuploaded",function(event,data,previewId,index){            var newfids=self.addFileIds(data.response.fileIds,self.options.fileIds);            self.options.fileIds=newfids;            self.updateFileIds();        }).on("filebatchuploadsuccess",function (event,data,previewId,index) {            var newfids=self.addFileIds(data.response.fileIds,self.options.fileIds);            self.options.fileIds=newfids;            self.updateFileIds();        }).on("filezoomhidden", function(event, params) {            $(document.body).removeClass('modal-open');            $(document.body).css("padding-right","0px");        });    }     /**     * 向targetIds里删除数据fileIds     * @param fileIds     * @param targetIds     */    BaseFile.prototype.deleteFileIds=function(fileIds,targetIds){        if(!fileIds) return targetIds;        //没有文件删除,其中必有蹊跷        if(!targetIds){            modals.error("没有要删除的文件,请检查是否数据没有初始化");            return;        }        var fileIdArr=fileIds.split(",");        var fresult=targetIds.split(",");        $.each(fileIdArr,function (index,fileId){            //存在则删除            if($.inArray(fileId,fresult)>-1){                fresult.splice($.inArray(fileId,fresult),1);            }        })        return fresult.join();    }    /**     * 向targetIds里加数据fileIds     * @param fileIds     * @param targetIds     */    BaseFile.prototype.addFileIds=function (fileIds,targetIds) {        if(!fileIds)return targetIds;        var fileIdArr=fileIds.split(",");        var fresult=[];        if(targetIds){            fresult=targetIds.split(",");        }        $.each(fileIdArr,function (index,fileId){            //不存在,新增            if($.inArray(fileId,fresult)==-1){                fresult.push(fileId);            }        })        return fresult.join();    }    BaseFile.prototype.updateFileIds=function(){        if(this.options.fileIdContainer)            $(this.options.fileIdContainer).val(this.options.fileIds);    }    BaseFile.prototype.initFileIds=function(){        //不弹出窗口的话一定要绑定fileIdContainer        if(!this.options.window){            if(!this.options.fileIdContainer||!$(this.options.fileIdContainer)){                modals.info("请设置fileIdContainer属性");                return;            }        }        if(!this.options.fileIds){            if(this.options.fileIdContainer){                this.options.fileIds=$(this.options.fileIdContainer).val();            }        }    }    BaseFile.prototype.getFileResult=function(fileIds){        var ret=null;        ajaxPost(basePath+"/file/getFiles",{fileIds:fileIds},function(result){            ret=result;        });        return ret;    };    /**     * 是否有显示区域     * @returns {boolean}     */    BaseFile.prototype.hasDisplayZone=function(){        if(!this.options.showContainer){           this.options.showContainer=this.element.selector;        }        if(!this.options.showContainer||!$(this.options.showContainer)){            return false;        }        return true;    }})(jQuery, window, document);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286

6、后端源码

@Controller@RequestMapping("/file")public class UploaderController {    private static Logger logger= LoggerFactory.getLogger(UploaderController.class);    //previewFileIconSettings    public static Map fileIconMap=new HashMap();    @Resource    private UploaderService uploaderService;    static {        fileIconMap.put("doc" ,"<i class='fa fa-file-word-o text-primary'></i>");        fileIconMap.put("docx","<i class='fa fa-file-word-o text-primary'></i>");        fileIconMap.put("xls" ,"<i class='fa fa-file-excel-o text-success'></i>");        fileIconMap.put("xlsx","<i class='fa fa-file-excel-o text-success'></i>");        fileIconMap.put("ppt" ,"<i class='fa fa-file-powerpoint-o text-danger'></i>");        fileIconMap.put("pptx","<i class='fa fa-file-powerpoint-o text-danger'></i>");        fileIconMap.put("jpg" ,"<i class='fa fa-file-photo-o text-warning'></i>");        fileIconMap.put("pdf" ,"<i class='fa fa-file-pdf-o text-danger'></i>");        fileIconMap.put("zip" ,"<i class='fa fa-file-archive-o text-muted'></i>");        fileIconMap.put("rar" ,"<i class='fa fa-file-archive-o text-muted'></i>");        fileIconMap.put("default" ,"<i class='fa fa-file-o'></i>");    }    //从setting.properties文件中注入文件相对目录(相对目录为显示文件)    //@Value("${uploaderPath}") 只有配置@Config才能注入    private static final String uploaderPath=PropertiesUtil.getValue("uploaderPath");    /**     * 跳转到通用文件上传窗口     * @return     */    @RequestMapping(value="/uploader",method = RequestMethod.GET)    public String uploader(String config,HttpServletRequest request){        request.setAttribute("config",config);        return "base/file/file_uploader";    }    /**     * 通用文件上传接口,存储到固定地址,以后存储到文件服务器地址     */    @RequestMapping(value = "/uploadFile", method = RequestMethod.POST)    @ResponseBody    public SysFile uploadFile(@RequestParam(value = "file", required = false) MultipartFile file,                              HttpServletRequest request, HttpServletResponse response) {        //TODO dosomething        return new SysFile();    }    /**     * 多文件上传,用于uploadAsync=false(同步多文件上传使用)     * @param files     * @param request     * @param response     * @return     */    @RequestMapping(value = "/uploadMultipleFile", method = RequestMethod.POST)    @ResponseBody    public FileResult uploadMultipleFile(@RequestParam(value = "file", required = false) MultipartFile[] files,                                         HttpServletRequest request, HttpServletResponse response) throws IOException {        System.out.println("the num of file:"+files.length);        FileResult msg = new FileResult();        ArrayList<Integer> arr = new ArrayList<>();        //缓存当前的文件        List<SysFile> fileList=new ArrayList<>();        String dirPath = request.getRealPath("/");        for (int i = 0; i < files.length; i++) {            MultipartFile file = files[i];            if (!file.isEmpty()) {                InputStream in = null;                OutputStream out = null;                try {                    File dir = new File(dirPath+uploaderPath);                    if (!dir.exists())                        dir.mkdirs();                    //这样也可以上传同名文件了                    String filePrefixFormat="yyyyMMddHHmmssS";                    System.out.println(DateUtil.format(new Date(),filePrefixFormat));                    String savedName=DateUtil.format(new Date(),filePrefixFormat)+"_"+file.getOriginalFilename();                    String filePath=dir.getAbsolutePath() + File.separator + savedName;                    File serverFile = new File(filePath);                    //将文件写入到服务器                    //FileUtil.copyInputStreamToFile(file.getInputStream(),serverFile);                    file.transferTo(serverFile);                    SysFile sysFile=new SysFile();                    sysFile.setFileName(file.getOriginalFilename());                    sysFile.setSavedName(savedName);                    sysFile.setCreateDateTime(new Date());                    sysFile.setUpdateDateTime(new Date());                    sysFile.setCreateUserId(SecurityUtil.getUserId());                    sysFile.setDeleted(0);                    sysFile.setFileSize(file.getSize());                    sysFile.setFilePath(uploaderPath+File.separator+savedName);                    uploaderService.save(sysFile);                    fileList.add(sysFile);                    /*preview.add("<div class=\"file-preview-other\">\n" +                            "<span class=\"file-other-icon\"><i class=\"fa fa-file-o text-default\"></i></span>\n" +                            "</div>");*/                    logger.info("Server File Location=" + serverFile.getAbsolutePath());                } catch (Exception e) {                    logger.error(   file.getOriginalFilename()+"上传发生异常,异常原因:"+e.getMessage());                    arr.add(i);                } finally {                    if (out != null) {                        out.close();                    }                    if (in != null) {                        in.close();                    }                }            } else {                arr.add(i);            }        }        if(arr.size() > 0) {            msg.setError("文件上传失败!");            msg.setErrorkeys(arr);        }        FileResult preview=getPreivewSettings(fileList,request);        msg.setInitialPreview(preview.getInitialPreview());        msg.setInitialPreviewConfig(preview.getInitialPreviewConfig());        msg.setFileIds(preview.getFileIds());        return msg;    }    //删除某一项文件    @RequestMapping(value="/delete",method = RequestMethod.POST)    @ResponseBody    public Result delete(String id,HttpServletRequest request){        SysFile sysFile=uploaderService.get(SysFile.class,id);        String dirPath=request.getRealPath("/");        FileUtil.delFile(dirPath+uploaderPath+File.separator+sysFile.getSavedName());        uploaderService.delete(sysFile);        return new Result();    }    /**     * 获取字体图标map,base-file控件使用     */    @RequestMapping(value="/icons",method = RequestMethod.POST)    @ResponseBody    public Map getIcons(){        return fileIconMap;    }    /**     * 根据文件名获取icon     * @param fileName 文件     * @return     */    public String getFileIcon(String fileName){        String ext= StrUtil.getExtName(fileName);        return fileIconMap.get(ext)==null?fileIconMap.get("default").toString():fileIconMap.get(ext).toString();    }    /**     * 根据附件IDS 获取文件     * @param fileIds     * @param request     * @return     */    @RequestMapping(value="/getFiles",method = RequestMethod.POST)    @ResponseBody    public FileResult getFiles(String fileIds,HttpServletRequest request){        String[] fileIdArr=fileIds.split(",");        DetachedCriteria criteria=DetachedCriteria.forClass(SysFile.class);        criteria.add(Restrictions.in("id",fileIdArr));        criteria.addOrder(Order.asc("createDateTime"));        List<SysFile> fileList=uploaderService.findByCriteria(criteria);        return getPreivewSettings(fileList,request);    }    /**     * 回填已有文件的缩略图     * @param fileList 文件列表     * @param request     * @return initialPreiview initialPreviewConfig fileIds     */    public FileResult getPreivewSettings(List<SysFile> fileList,HttpServletRequest request){        FileResult fileResult=new FileResult();        List<String> previews=new ArrayList<>();        List<FileResult.PreviewConfig> previewConfigs=new ArrayList<>();        //缓存当前的文件        String dirPath = request.getRealPath("/");        String[] fileArr=new String[fileList.size()];        int index=0;        for (SysFile sysFile : fileList) {            //上传后预览 TODO 该预览样式暂时不支持theme:explorer的样式,后续可以再次扩展            //如果其他文件可预览txt、xml、html、pdf等 可在此配置            if(FileUtil.isImage(dirPath+uploaderPath+File.separator+sysFile.getSavedName())) {                previews.add("<img src='." + sysFile.getFilePath().replace(File.separator, "/") + "' class='file-preview-image kv-preview-data' " +                        "style='width:auto;height:160px' alt='" + sysFile.getFileName() + " title='" + sysFile.getFileName() + "''>");            }else{                previews.add("<div class='kv-preview-data file-preview-other-frame'><div class='file-preview-other'>" +                        "<span class='file-other-icon'>"+getFileIcon(sysFile.getFileName())+"</span></div></div>");            }            //上传后预览配置            FileResult.PreviewConfig previewConfig=new FileResult.PreviewConfig();            previewConfig.setWidth("120px");            previewConfig.setCaption(sysFile.getFileName());            previewConfig.setKey(sysFile.getId());            // previewConfig.setUrl(request.getContextPath()+"/file/delete");            previewConfig.setExtra(new FileResult.PreviewConfig.Extra(sysFile.getId()));            previewConfig.setSize(sysFile.getFileSize());            previewConfigs.add(previewConfig);            fileArr[index++]=sysFile.getId();        }        fileResult.setInitialPreview(previews);        fileResult.setInitialPreviewConfig(previewConfigs);        fileResult.setFileIds(StrUtil.join(fileArr));        return fileResult;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225

总结

本文源码已在AdminEAP框架(一个基于AdminLTE的Java开发平台)中开源,可在Github下载相关代码:

Github:https://github.com/bill1012/AdminEAP

AdminEAP官网:http://www.admineap.com

0 0