为了上传预览pdf与图片特用此插件。
源码以及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
一、效果展示
1、原始的input type='file',简直不忍直视。
2、不做任何装饰的bootstrap fileinput:(bootstrap fileinput初级进化)
3、bootstrap fileinput高级进化:中文化、可拖拽上传、文件扩展名校验(如果不是需要的文件,不让上传)
二、一个bootstrap插件:
<!DOCTYPE html> <!-- release v4.3.6, copyright 2014 - 2017 Kartik Visweswaran --> <html lang="en"> <head> <meta charset="UTF-8"/> <title>Krajee JQuery Plugins - © Kartik</title> <link href="http://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="css/default.css"> <link href="css/fileinput.css" media="all" rel="stylesheet" type="text/css"/> <script src="http://cdn.bootcss.com/jquery/1.11.0/jquery.min.js" type="text/javascript"></script> <script>window.jQuery || document.write('<script src="js/jquery-1.11.0.min.js"><\/script>')</script> <script src="js/fileinput.js" type="text/javascript"></script> <!--简体中文--> <script src="js/locales/zh.js" type="text/javascript"></script> <!--繁体中文--> <script src="js/locales/zh-TW.js" type="text/javascript"></script> <script src="http://cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> <style> /***限制图片框的大小**/ .kv-file-content { height: 160px; width: 160px !important; } .kv-preview-data { height: 90%; width: 90% !important; } </style> </head> <body> <div class="htmleaf-container"> <div class="container kv-main"> <div class="page-header"> <h2>文件上传</h2> </div> <form enctype="multipart/form-data"> <input id="file-0a" class="file" type="file" multiple data-min-file-count="6"> <br> <button type="submit" class="btn btn-primary">Submit</button> <button type="reset" class="btn btn-default">Reset</button> </form> <form enctype="multipart/form-data"> <hr> <div class="form-group"> <input id="file-0b" class="file" type="file" multiple data-preview-file-type="any" data-upload-url="#"> </div> </form> </div> </div> </body> <script> //准备附件上传的样式 $("#file-0a").fileinput({ language: 'zh', showUpload: true, //是否显示上传按钮 allowedFileExtensions: ['doc', 'docx', 'pdf'] }); $("#file-0b").fileinput({ showPreview: true, //是否显示预览 uploadUrl: '#', // you must set a valid URL here else you will get an error allowedFileExtensions: ['jpg', 'png', 'gif'], showUpload: true, //是否显示上传按钮 overwriteInitial: false, maxFileSize: 1000, maxFilesNum: 10, language: 'zh', //allowedFileTypes: ['image', 'video', 'flash'], slugCallback: function (filename) { return filename.replace('(', '_').replace(']', '_'); } }); $(".btn-warning").on('click', function () { if ($('#file-4').attr('disabled')) { $('#file-4').fileinput('enable'); } else { $('#file-4').fileinput('disable'); } }); $(document).ready(function () { $("#test-upload").fileinput({ 'showPreview': false, 'allowedFileExtensions': ['jpg', 'png', 'gif'], 'elErrorContainer': '#errorBlock' }); }); </script> </html>
效果:
JS解释:
$("#file-0b").fileinput({ showPreview: true, //是否显示预览 uploadUrl: '#', // you must set a valid URL here else you will get an error allowedFileExtensions: ['jpg', 'png', 'gif'], showUpload: true, //是否显示上传按钮 overwriteInitial: false, maxFileSize: 1000, maxFilesNum: 10, language: 'zh', //allowedFileTypes: ['image', 'video', 'flash'], slugCallback: function (filename) { return filename.replace('(', '_').replace(']', '_'); } });
定义显示哪些按钮。
bootstrap都有一些默认值,参考:fileinput.js
$.fn.fileinput.defaults = { language: 'en', showCaption: true, showBrowse: true, showPreview: true, showRemove: true, showUpload: true, showCancel: true, showClose: true, showUploadedThumbs: true, browseOnZoneClick: false, autoReplace: false, previewClass: '', captionClass: '', mainClass: 'file-caption-main', mainTemplate: null, purifyHtml: true, fileSizeGetter: null, initialCaption: '', initialPreview: [], initialPreviewDelimiter: '*$$*', initialPreviewAsData: false, initialPreviewFileType: 'image', initialPreviewConfig: [], initialPreviewThumbTags: [], previewThumbTags: {}, initialPreviewShowDelete: true, removeFromPreviewOnError: false, deleteUrl: '', deleteExtraData: {}, overwriteInitial: true, layoutTemplates: defaultLayoutTemplates, previewTemplates: defaultPreviewTemplates, previewZoomSettings: defaultPreviewZoomSettings, previewZoomButtonIcons: { prev: '<i class="glyphicon glyphicon-triangle-left"></i>', next: '<i class="glyphicon glyphicon-triangle-right"></i>', toggleheader: '<i class="glyphicon glyphicon-resize-vertical"></i>', fullscreen: '<i class="glyphicon glyphicon-fullscreen"></i>', borderless: '<i class="glyphicon glyphicon-resize-full"></i>', close: '<i class="glyphicon glyphicon-remove"></i>' }, previewZoomButtonClasses: { prev: 'btn btn-navigate', next: 'btn btn-navigate', toggleheader: 'btn btn-default btn-header-toggle', fullscreen: 'btn btn-default', borderless: 'btn btn-default', close: 'btn btn-default' }, preferIconicPreview: false, preferIconicZoomPreview: false, allowedPreviewTypes: defaultPreviewTypes, allowedPreviewMimeTypes: null, allowedFileTypes: null, allowedFileExtensions: null, defaultPreviewContent: null, customLayoutTags: {}, customPreviewTags: {}, previewSettings: defaultPreviewSettings, fileTypeSettings: defaultFileTypeSettings, previewFileIcon: '<i class="glyphicon glyphicon-file"></i>', previewFileIconClass: 'file-other-icon', previewFileIconSettings: {}, previewFileExtSettings: {}, buttonLabelClass: 'hidden-xs', browseIcon: '<i class="glyphicon glyphicon-folder-open"></i> ', browseClass: 'btn btn-primary', removeIcon: '<i class="glyphicon glyphicon-trash"></i>', removeClass: 'btn btn-default', cancelIcon: '<i class="glyphicon glyphicon-ban-circle"></i>', cancelClass: 'btn btn-default', uploadIcon: '<i class="glyphicon glyphicon-upload"></i>', uploadClass: 'btn btn-default', uploadUrl: null, uploadAsync: true, uploadExtraData: {}, zoomModalHeight: 480, minImageWidth: null, minImageHeight: null, maxImageWidth: null, maxImageHeight: null, resizeImage: false, resizePreference: 'width', resizeQuality: 0.92, resizeDefaultImageType: 'image/jpeg', minFileSize: 0, maxFileSize: 0, maxFilePreviewSize: 25600, // 25 MB minFileCount: 0, maxFileCount: 0, validateInitialCount: false, msgValidationErrorClass: 'text-danger', msgValidationErrorIcon: '<i class="glyphicon glyphicon-exclamation-sign"></i> ', msgErrorClass: 'file-error-message', progressThumbClass: "progress-bar progress-bar-success progress-bar-striped active", progressClass: "progress-bar progress-bar-success progress-bar-striped active", progressCompleteClass: "progress-bar progress-bar-success", progressErrorClass: "progress-bar progress-bar-danger", progressUploadThreshold: 99, previewFileType: 'image', elCaptionContainer: null, elCaptionText: null, elPreviewContainer: null, elPreviewImage: null, elPreviewStatus: null, elErrorContainer: null, errorCloseButton: '<span class="close kv-error-close">×</span>', slugCallback: null, dropZoneEnabled: true, dropZoneTitleClass: 'file-drop-zone-title', fileActionSettings: {}, otherActionButtons: '', textEncoding: 'UTF-8', ajaxSettings: {}, ajaxDeleteSettings: {}, showAjaxErrorDetails: true };
(1) 一些重要的参数解释:(下面标红的地方是为了去掉预览区域的删除按钮与上传按钮)
解释:
模板采用的默认配置:
查看默认配置:
继续追踪发现都是小图标
去掉上传按钮
layoutTemplates:{//预览区域删除按钮与上传按钮的显示 actionUpload:''//上传按钮不显示 },
也可以去掉进度条:
layoutTemplates:{//预览区域删除按钮与上传按钮的显示 actionUpload:'',//上传按钮不显示 progress:''//隐藏进度条 },
(2) 另一个问题:如何知道选择了几个文件:
有时候我们需要验证该插件选择上文件才可以上传(也就是我们需要知道选择了几个文件):
通过debugger可以看到::通过如下方法就可以知道选择了几个文件:
var scanFile = $("#bootUpOne")[0].files; var scanFile_length = scanFile.length;
上面的 scanFile_length 就是选择的文件个数。
例如:如果选择上文件,将文件上传:
//判断申请书电子版文件是否选上 var applyFile = $("#attach")[0].files; var applyFile_length = applyFile.length; if(applyFile_length > 0){//上传申请书附件 //上传扫描的照片附件 $("#attach").fileinput("upload"); }
(3) 携带额外的数据上传到服务器:(支持jQuery获取动态值)
另一种方法:(这种方法对于动态设置的值不起作用,也就是此方法不会在上传的时候再去获取数据,而上面的方法是可以获取动态的值)
(4)如果想要设置图片在预览区域内的大小:
previewSettings: {//限制预览区域的宽高 image: {width: "100px", height: "100px"}, }
效果:
我们打开默认配置可以看到其采用的是默认配置::(两次追踪看出如下配置:)
(5)如果想要改变整个预览区域的大小:
至今没有找到办法,只能设置里面内容区域的大小改变外面的值,也就是改变(4)值。
(6)今天遇到有个问题就是需要上传四种不同的图片,我设计的时候是点击单选按钮然后切换不同的图片显示,结果只有第一个区域查看详情的时候有显示,后面三个区域查看详情只是背景色变暗,图片显示不出来:
(1)效果:
查看平面简图的时候正常:
查看后面三种图的时候不正常:
(2)原因:
原因:上面四种图查看详情使用的是同一个模态框,并且只在第一种图片的form表单中有,当点击另外三只按钮的实施,我的JS代码将第一个图片的div的display属性变为none,因此在之后的另外三种图片点击查看详情的时候会出现模态框显示不出来的情况。
我的JS代码:
//单选按钮的点击事件 $("[name='pictureType']").click(function(){ var clazz = $(this).prop("class"); $(".pictureDiv").css("display","none");//隐藏所有的div $("div."+clazz).css("display","block"); });
(3)解决办法:将上面插件初始化的模态框删除,并且将预览的div拿出来单独放到页面中。
删除插件初始化的模态框:
/**页面执行一次删除插件初始化的预览图片的模态框的函数**/ (function(){ alert("开始删除插件自带的预览div") $(".pictureDiv .modal").remove();//删除bootstrapFileinput初始化预览的div })();
页面中写上预览插件的模态框:
<!-- 预览模态框(单独放出来,否则隐藏div的时候图片不显示) --> <div> <div id="kvFileinputModal" class="file-zoom-dialog modal fade" tabindex="-1" aria-labelledby="kvFileinputModalLabel"><div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header"> <div class="kv-zoom-actions pull-right"><button type="button" class="btn btn-default btn-header-toggle btn-toggleheader" title="缩放" data-toggle="button" aria-pressed="false" autocomplete="off"><i class="glyphicon glyphicon-resize-vertical"></i></button><button type="button" class="btn btn-default btn-fullscreen" title="全屏" data-toggle="button" aria-pressed="false" autocomplete="off"><i class="glyphicon glyphicon-fullscreen"></i></button><button type="button" class="btn btn-default btn-borderless" title="无边界模式" data-toggle="button" aria-pressed="false" autocomplete="off"><i class="glyphicon glyphicon-resize-full"></i></button><button type="button" class="btn btn-default btn-close" title="关闭当前预览" data-dismiss="modal" aria-hidden="true"><i class="glyphicon glyphicon-remove"></i></button></div> <h3 class="modal-title">详细预览 <small><span class="kv-zoom-title"></span></small></h3> </div> <div class="modal-body"> <div class="floating-buttons"></div> <div class="kv-zoom-body file-zoom-content"></div> <button type="button" class="btn btn-navigate btn-prev" title="预览上一个文件"><i class="glyphicon glyphicon-triangle-left"></i></button> <button type="button" class="btn btn-navigate btn-next" title="预览下一个文件"><i class="glyphicon glyphicon-triangle-right"></i></button> </div> </div> </div> </div> </div>
(7)今天在对多种图片处理的时候需要继续对插件进行改造:(选中之后上传,携带数据上传,上传完成重置插件而且重新执行一个JS查询函数)
/** * 上传频谱图 */ $("#upFrequencyPicture").fileinput({ language: 'zh',//中文 uploadUrl:"upLoadMultiple.do",//上传的地址,加上这个才会出现删除按钮 dropZoneEnabled: false,//是否显示拖拽区域 showUpload: true, //是否显示上传按钮,跟随文本框的那个 showRemove : false, //显示移除按钮,跟随文本框的那个 showClose:false,//显示关闭按钮 showCaption: true,//是否显示标题,就是那个文本框 uploadAsync:true,//是否异步 layoutTemplates:{//预览区域删除按钮与上传按钮的显示 actionUpload:'',//上传按钮不显示 progress:''//隐藏进度条 }, enctype: 'multipart/form-data', previewFileIcon : "<i class='glyphicon glyphicon-king'></i>", previewSettings: {//限制预览区域的宽高 image: {width: "160px", height: "160px"} }, uploadExtraData: function (previewId, index) {//携带其他一些数据的格式 var data = { applyId:$("#hidden_apply_id").val(), pictureType:'2' }; return data; }, validateInitialCount:true, allowedFileExtensions: ['png','jpg']//允许上传问价你的后缀 }).on('filepreupload', function(event, data, previewId, index) { var form = data.form, files = data.files, extra = data.extra, response = data.response, reader = data.reader; }).on("filebatchselected", function(event, files) {//文件选中函数(选中之后上传文件) $(this).fileinput("upload"); }).on("fileuploaded", function(event, data) {//上传成功之后的一些处理 if(data.response) { alert("上传成功!"); $(this).fileinput("reset");//将此插件重置(前提是不显示上传进度条,否则将留下进度条) loadEnTestPic("2");//执行页面的一个JS函数重新查询图片 } });
最后在测试的时候发现一次传多个上面的函数会失败:(改造:每次上传前将一个变量置为false,成功置为true,根据变量判断是否重置:)
/** * 上传频谱图 */ $("#upFrequencyPicture").fileinput({ language: 'zh',//中文 uploadUrl:"upLoadMultiple.do",//上传的地址,加上这个才会出现删除按钮 dropZoneEnabled: false,//是否显示拖拽区域 showUpload: true, //是否显示上传按钮,跟随文本框的那个 showRemove : false, //显示移除按钮,跟随文本框的那个 showClose:false,//显示关闭按钮 showCaption: true,//是否显示标题,就是那个文本框 uploadAsync:true,//是否异步 layoutTemplates:{//预览区域删除按钮与上传按钮的显示 actionUpload:'',//上传按钮不显示 progress:''//隐藏进度条 }, enctype: 'multipart/form-data', previewFileIcon : "<i class='glyphicon glyphicon-king'></i>", previewSettings: {//限制预览区域的宽高 image: {width: "160px", height: "160px"} }, uploadExtraData: function (previewId, index) {//携带其他一些数据的格式 var data = { applyId:$("#hidden_apply_id").val(), pictureType:'2' }; return data; }, validateInitialCount:true, allowedFileExtensions: ['png','jpg']//允许上传问价你的后缀 }).on('filepreupload', function(event, data, previewId, index) { var form = data.form, files = data.files, extra = data.extra, response = data.response, reader = data.reader; }).on("filebatchselected", function(event, files) {//文件选中函数(选中之后上传文件) isReset = false; $(this).fileinput("upload"); }).on("fileuploaded", function(event, data) {//上传成功之后的一些处理 if(data.response) { alert("上传成功!"); if(!isReset){ $("#upFrequencyPicture").fileinput("reset");//将此插件重置(前提是不显示上传进度条,否则将留下进度条) loadEnTestPic("2");//执行页面的一个JS函数重新查询图片 isReset = true; } } });
此插件还有很多自带的函数:大概在fileinput.js中3000行
(8)在多个插件同时上传的时候可以通过上传前后设置变量来表示什么时候上传完成,上传前置为false,上传后置为true,也就两个插件有两个变量标记,当第一个上传完成后将其对应的置为true,第二个上传完成也将其置为true,最后一比当两个都为true的时候就表示上传完成了就可以进行页面跳转(上传的时候基本上是同时进行,上传完成是一前一后,可以通过变量知道最后传完的)/***S 上传文件相关操作****/
/** * 上传扫描的pdf原件 */
//利用插件异步上传单文件
var saveScan=true,saveAtta=true;
$("#bootUpOne").fileinput({
language: 'zh',//中文 uploadUrl:"upLoadOne.do",//上传的地址,加上这个才会出现删除按钮 dropZoneEnabled: false,//是否显示拖拽区域 showPreview:true,//是否显示预览区域 showClose:false,//显示关闭按钮 showUpload: false, //是否显示上传按钮,跟随文本框的那个 showRemove : true, //显示移除按钮,跟随文本框的那个 showCaption: true,//是否显示标题,就是那个文本框 uploadAsync:true, enctype: 'multipart/form-data', previewFileIcon : "<i class='glyphicon glyphicon-king'></i>", layoutTemplates:{//预览区域删除按钮与上传按钮的显示 actionUpload:''//上传按钮不显示 }, previewSettings: {//限制预览区域的宽高 pdf: {width: "0px", height: "0px"} }, uploadExtraData: function (previewId, index) {//携带其他一些数据的格式 var data = { applyId:$("#hidden_apply_id").val(), attachType:'3' }; return data; }, validateInitialCount:true, allowedFileExtensions: ['pdf'],//允许上传问价你的后缀 }).on('filepreupload', function(event, data, previewId, index) { var form = data.form, files = data.files, extra = data.extra, response = data.response, reader = data.reader; saveScan = false; alert("上传前置为false"); }) .on("fileuploaded", function(event, data) {//上传成功之后的一些处理 if(data.response) { saveScan = true; if(saveScan&&saveAtta){ alert("上传成功!"); window.location.href=contextPath+"/environment/enApplyInfo_list.jsp"; } } }); /** * 上传申请书电子版 */ $("#attach").fileinput({ language: 'zh',//中文 uploadUrl:"upLoadOne.do",//上传的地址,加上这个才会出现删除按钮 dropZoneEnabled: false,//是否显示拖拽区域 showUpload: false, //是否显示上传按钮,跟随文本框的那个 showRemove : true, //显示移除按钮,跟随文本框的那个 showCaption: true,//是否显示标题,就是那个文本框 showClose:false,//显示关闭按钮 uploadAsync:true,//是否异步 layoutTemplates:{//预览区域删除按钮与上传按钮的显示 actionUpload:''//上传按钮不显示 }, enctype: 'multipart/form-data', previewSettings: {//限制预览区域的宽高 pdf: {width: "0px", height: "0px"}, other: {width: "0px", height: "0px"} }, previewFileIcon : "<i class='glyphicon glyphicon-king'></i>", uploadExtraData: function (previewId, index) {//携带其他一些数据的格式 var data = { applyId:$("#hidden_apply_id").val(), attachType:'1' }; return data; }, validateInitialCount:true, allowedFileExtensions: ['pdf','doc','docx']//允许上传问价你的后缀 }).on('filepreupload', function(event, data, previewId, index) { var form = data.form, files = data.files, extra = data.extra, response = data.response, reader = data.reader; saveAtta = false; }) .on("fileuploaded", function(event, data) {//上传成功之后的一些处理 if(data.response) { saveAtta = true; if(saveScan&&saveAtta){ alert("上传成功!"); window.location.href=contextPath+"/environment/enApplyInfo_list.jsp"; } } }); /***E 上传文件相关操作****/
三、Struts2后台接收文件:(测试了普通的ajax传文件与直接表单提交上传与利用插件上传文件)
例如:Struts接收后台文件:
<!DOCTYPE html> <!-- release v4.3.6, copyright 2014 - 2017 Kartik Visweswaran --> <html lang="en"> <head> <meta charset="UTF-8"/> <title>Krajee JQuery Plugins - © Kartik</title> <link href="http://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="css/default.css"> <link href="css/fileinput.css" media="all" rel="stylesheet" type="text/css"/> <script src="http://cdn.bootcss.com/jquery/1.11.0/jquery.min.js" type="text/javascript"></script> <script>window.jQuery || document.write('<script src="js/jquery-1.11.0.min.js"><\/script>')</script> <script src="js/fileinput.js" type="text/javascript"></script> <!--简体中文--> <script src="js/locales/zh.js" type="text/javascript"></script> <!--繁体中文--> <script src="js/locales/zh-TW.js" type="text/javascript"></script> <script src="http://cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> <script src="index.js" type="text/javascript"></script> <style> /***限制图片框的大小**/ .kv-file-content { height: 160px; width: 160px !important; } .kv-preview-data { height: 90%; width: 90% !important; } </style> </head> <body> <div class="htmleaf-container"> <div class="container kv-main"> <!--S 没有用插件的上传功能,与普通文件上传一样--> <form enctype="multipart/form-data" method="post" action="http://localhost/bootstrapFileUpload/upLoadOne.action"> <hr> 同步单文件上传(类似于普通的表单提交,直接提交) <input id="fileUpOne" class="file" type="file" name="fileName"> <button type="submit" class="btn btn-primary">Submit</button> <button type="reset" class="btn btn-default">Reset</button> <hr> </form> <form id="ajaxUpOneForm"> <hr> ajax异步上传单文件(类似于普通的ajax上传文件) <input id="ajaxUploadOneFile" class="file" type="file" name="fileName"/> <button type="button" class="btn btn-primary" id="ajaxUploadOneFileBtn">ajax异步上传单文件</button> <hr> </form> <form enctype="multipart/form-data" method="post" action="http://localhost/bootstrapFileUpload/upLoadMultiple.action"> <hr> 同步多文件上传(类似于普通的表单提交,直接提交) <input id="fileUpMultiple" class="file" type="file" multiple name="fileName"> <button type="submit" class="btn btn-primary">Submit</button> <button type="reset" class="btn btn-default">Reset</button> <hr> </form> <form enctype="multipart/form-data" id="ajaxUpMultipleForm"> <hr> ajax异步上传多文件(类似于普通的ajax上传文件) <input id="ajaxUploadMultiple" class="file" type="file" multiple name="fileName"> <button type="button" class="btn btn-primary" id="ajaxUploadMultipeleFileBtn">ajax异步上传单文件</button> <hr> </form> <!--E 没有用插件的上传功能,与普通文件上传一样--> <!--S 开始使用插件的上传功能--> <form> <hr> 利用插件自带的(上传单个文件) <input id="bootUpOne" class="file-loading" type="file" name="fileName"> <hr> </form> <form enctype="multipart/form-data"> <hr> 利用插件自带的(上传多个文件) <input id="bootUpMultiple" class="file" multiple type="file" name="fileName"> <hr> </form> <!--E 开始使用插件的上传功能--> </div> </div> </body> <script> /*********S 文件上传按钮的样式显示内容设定*****/ /*S 没有使用插件的上传功能*/ //同步单文件上传(类似于普通的表单提交) $("#fileUpOne").fileinput({ language: 'zh', uploadUrl:"#",//上传的地址,加上这个才会出现删除按钮 showPreview: true, //是否显示预览,不写默认为true allowedPreviewMimeTypes: ['jpg', 'png', 'doc', 'pdf'],//控制被预览的所有mime类型 showUpload: false, //是否显示上传按钮 dropZoneEnabled: false,//是否显示拖拽区域 allowedFileExtensions: ['doc', 'docx', 'pdf'], layoutTemplates:{//预览区域删除按钮与上传按钮的显示 actionUpload:''//上传按钮不显示 } }); //ajax异步上传单文件(类似于普通的ajax上传文件) $("#ajaxUploadOneFile").fileinput({ language: 'zh', dropZoneEnabled: false,//是否显示拖拽区域 uploadUrl:"#",//上传的地址,加上这个才会出现删除按钮 showUpload: false, //是否显示上传按钮 allowedFileExtensions: ['doc', 'docx', 'pdf'], layoutTemplates:{//预览区域删除按钮与上传按钮的显示 actionUpload:''//上传按钮不显示 } }); //同步多文件上传(类似于普通的表单提交) $("#fileUpMultiple").fileinput({ language: 'zh', uploadUrl:"#",//上传的地址,加上这个才会出现删除按钮 dropZoneEnabled: false,//是否显示拖拽区域 showUpload: false, //是否显示上传按钮,跟随文本框的那个 showRemove : true, //显示移除按钮,跟随文本框的那个 showCaption: true,//是否显示标题,就是那个文本框 allowedFileExtensions: ['jpg', 'png', 'gif'], layoutTemplates:{//预览区域删除按钮与上传按钮的显示 actionUpload:''//上传按钮不显示 } }); //ajax异步上传多文件(类似于普通的ajax上传文件) $("#ajaxUploadMultiple").fileinput({ language: 'zh',//中文 uploadUrl:"#",//上传的地址,加上这个才会出现删除按钮 dropZoneEnabled: false,//是否显示拖拽区域 showUpload: false, //是否显示上传按钮,跟随文本框的那个 showRemove : true, //显示移除按钮,跟随文本框的那个 showCaption: true,//是否显示标题,就是那个文本框 allowedFileExtensions: ['jpg', 'png', 'gif'],//允许上传问价你的后缀 layoutTemplates:{//预览区域删除按钮与上传按钮的显示 actionUpload:''//上传按钮不显示 } }); /*E 没有使用插件的上传功能*/ /*S 开始使用插件的上传功能*/ //利用插件异步上传单文件 $("#bootUpOne").fileinput({ language: 'zh',//中文 uploadUrl:"upLoadOne.action",//上传的地址,加上这个才会出现删除按钮 dropZoneEnabled: false,//是否显示拖拽区域 showUpload: true, //是否显示上传按钮,跟随文本框的那个 showRemove : true, //显示移除按钮,跟随文本框的那个 showCaption: true,//是否显示标题,就是那个文本框 uploadAsync:true, enctype: 'multipart/form-data', previewFileIcon : "<i class='glyphicon glyphicon-king'></i>", uploadExtraData: function (previewId, index) {//携带其他一些数据的格式 var data = { ID:"123" }; return data; }, validateInitialCount:true, allowedFileExtensions: ['jpg', 'png', 'gif'],//允许上传问价你的后缀 }).on('filepreupload', function(event, data, previewId, index) { var form = data.form, files = data.files, extra = data.extra, response = data.response, reader = data.reader; }) .on("fileuploaded", function(event, data) { if(data.response) { alert('处理成功'); } }); //利用插件异步上传多文件 $("#bootUpMultiple").fileinput({ language: 'zh',//中文 uploadUrl:"upLoadMultiple.action",//上传的地址,加上这个才会出现删除按钮 dropZoneEnabled: false,//是否显示拖拽区域 showUpload: true, //是否显示上传按钮,跟随文本框的那个 showRemove : true, //显示移除按钮,跟随文本框的那个 showCaption: true,//是否显示标题,就是那个文本框 uploadAsync:true, enctype: 'multipart/form-data', previewFileIcon : "<i class='glyphicon glyphicon-king'></i>", uploadExtraData: function (previewId, index) {//携带其他一些数据的格式 var data = { ID:"123" }; return data; }, validateInitialCount:true, allowedFileExtensions: ['jpg', 'png', 'gif'],//允许上传文件的后缀 }).on('filepreupload', function(event, data, previewId, index) { var form = data.form, files = data.files, extra = data.extra, response = data.response, reader = data.reader; }) .on("fileuploaded", function(event, data) { if(data.response) { alert('处理成功'); } }); /*E 开始使用插件的上传功能*/ /*********E 文件上传按钮的样式显示内容设定*****/ $(".btn-warning").on('click', function () { if ($('#file-4').attr('disabled')) { $('#file-4').fileinput('enable'); } else { $('#file-4').fileinput('disable'); } }); $(".btn-info").on('click', function () { $('#file-4').fileinput('refresh', {previewClass: 'bg-info'}); }); $(document).ready(function () { $("#test-upload").fileinput({ 'showPreview': false, 'allowedFileExtensions': ['jpg', 'png', 'gif'], 'elErrorContainer': '#errorBlock' }); }); </script> </html>
index.js
/** * Created by liqiang on 2018/2/4. */ /** * 页面初始化函数 */ $(function () { //ajax上传单文件函数 $("#ajaxUploadOneFileBtn").click(function(){ ajaxUploadOneFile(); }); //ajax上传多文件函数 $("#ajaxUploadMultipeleFileBtn").click(function(){ ajaxUploadMultipleFile(); }); }); /** * 没有使用插件 */ /****************S ajax上传单文件 *******************************************/ function ajaxUploadOneFile() { var formData = new FormData($( "#ajaxUpOneForm" )[0]); $.ajax({ url: 'http://localhost/bootstrapFileUpload/upLoadOne.action' , type: 'POST', data: formData, async: false, cache: false, contentType: false, processData: false, success: function (returndata) { alert(returndata); }, error: function (returndata) { alert(returndata); } }); } /****************E ajax异步上传单文件 *******************************************/ /****************S ajax上传多文件 *******************************************/ function ajaxUploadMultipleFile() { var formData = new FormData($( "#ajaxUpMultipleForm" )[0]); $.ajax({ url: 'http://localhost/bootstrapFileUpload/upLoadMultiple.action' , type: 'POST', data: formData, async: false, cache: false, contentType: false, processData: false, success: function (returndata) { alert(returndata); }, error: function (returndata) { alert(returndata); } }); } /****************E ajax上传多文件 *******************************************/ /** * 开始使用插件 */
后台Action:
OneFileUpAction.java
package cn.qlq.fileupload; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import javax.servlet.ServletContext; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; /** * 单文件上传 * @author liqiang * */ public class OneFileUpAction extends ActionSupport{ private File fileName; private String fileNameContentType; private String fileNameFileName; private String ID;//测试是否可以携带额外的数据上来 public String execute() throws Exception{ ServletContext servletContext = ServletActionContext.getServletContext(); String dir = servletContext.getRealPath("/files/"+fileNameFileName); FileOutputStream outputStream = new FileOutputStream(dir); FileInputStream inputStream = new FileInputStream(fileName); byte[] buffer = new byte[1024]; int len = 0; // 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中.读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1。 while((len = inputStream.read(buffer))!=-1){ // 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。 outputStream.write(buffer, 0, len); } inputStream.close(); outputStream.close(); return SUCCESS; } public File getFileName() { return fileName; } public void setFileName(File fileName) { this.fileName = fileName; } public String getFileNameContentType() { return fileNameContentType; } public void setFileNameContentType(String fileNameContentType) { this.fileNameContentType = fileNameContentType; } public String getFileNameFileName() { return fileNameFileName; } public void setFileNameFileName(String fileNameFileName) { this.fileNameFileName = fileNameFileName; } public String getID() { return ID; } public void setID(String iD) { ID = iD; } }
MultipleFileUpAction.java
package cn.qlq.fileupload; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import javax.servlet.ServletContext; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class MultipleFileUpAction extends ActionSupport{ private File[] fileName; private String[] fileNameContentType; private String[] fileNameFileName; public String execute() throws Exception{ for(int i=0;i<fileName.length;i++){ ServletContext servletContext = ServletActionContext.getServletContext(); String dir = servletContext.getRealPath("/files/"+fileNameFileName[i]); System.out.println(dir); FileOutputStream outputStream = new FileOutputStream(dir); FileInputStream inputStream = new FileInputStream(fileName[i]); byte[] buffer = new byte[1024]; int len = 0; // 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中.读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1。 while((len = inputStream.read(buffer))!=-1){ // 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。 outputStream.write(buffer, 0, len); } inputStream.close(); outputStream.close(); } return SUCCESS; } public File[] getFileName() { return fileName; } public void setFileName(File[] fileName) { this.fileName = fileName; } public String[] getFileNameContentType() { return fileNameContentType; } public void setFileNameContentType(String[] fileNameContentType) { this.fileNameContentType = fileNameContentType; } public String[] getFileNameFileName() { return fileNameFileName; } public void setFileNameFileName(String[] fileNameFileName) { this.fileNameFileName = fileNameFileName; } }
struts配置:
struts.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!-- 配置常量 --> <!-- 字符集 --> <constant name="struts.i18n.encoding" value="UTF-8"></constant> <!-- 开发模式 --> <constant name="struts.devMode" value="false"></constant> <!-- 扩展名 --> <constant name="struts.action.extension" value="action"></constant> <!-- 通用package --> <package name="file" namespace="/" extends="struts-default,json-default"> <global-results> <result name="success" type="json"></result> </global-results> <!--测试struts环境是否搭建成功 --> <action name="testEn" class="cn.qlq.fileupload.TestEn"></action> <!-- 测试上传单个文件 --> <action name="upLoadOne" class="cn.qlq.fileupload.OneFileUpAction"></action> <!-- 测试上传多个文件 --> <action name="upLoadMultiple" class="cn.qlq.fileupload.MultipleFileUpAction"></action> </package> </struts>
结果:
git源码地址:https://github.com/qiao-zhi/bootstrapFileUpload