先上效果图
前端代码
<div class="left_part"> <div class="layui-card-header"> 上传文件 </div> <div class="layui-card-body" style="border-right:1px solid #f6f6f6;"> <div class="layui-form-item" style="padding: 20px;"> <div class="layui-inline"> <label class="layui-form-label" style="padding-left: 0;">版本号:</label> <div class="layui-input-block" style="width: 100%;min-width: 200px;"> <input type="text" id="client_version" placeholder="请输入客户端版本号" autocomplete="off" class="layui-input"> </div> </div> </div> <div class="file-upload"> <div class="file-box"> <input type="file" class="file-btn" id="choose-file" multiple=""> <i class="layui-icon layui-icon-upload"></i>上传客户端安装文件 </div> <ul class="file-list" id="addFileUl"> </ul> </div> <div class="upload"> <button name="sendbtn" id="upload" class="layui-btn layui-btn-primary" href="">提交</button> </div> </div> </div>
自写css(如下代码)+layui.css
.layui-card-header{ font-size: 18px; font-weight: 500; padding: 20px; } .left_part{ width:50%; float:left; } .right_part{ width:50%; float:right; } .file-list{ list-style-type: none; padding: 0; } .file-item{ padding: 5px; background: #e0ecf9; border-bottom: 1px solid #eff5fb; } .file-list img{ vertical-align: middle; } .file-list .file-item .file-name{margin-left: 10px} .file-list .file-item .file-del{ color: red; margin-left: 20px; } .file-box{ display: inline-block; position: relative; padding: 5px; overflow: hidden; color:#000; background-color: #c1d9f3; height: 100%; width: 171px; } .file-btn{ position: absolute; width: 100%; height: 100%; top: 0; left: 0; outline: none; background-color: transparent; filter:alpha(opacity=0); -moz-opacity:0; -khtml-opacity: 0; opacity: 0; } .file-upload{ padding-left: 110px; padding-right: 30px; } .upload{ padding-left: 110px; padding-right: 30px; margin-top: 100px; } #upload{ border-radius: 5px; background-color: #eee; }
JS
var $file = $("#choose-file"), //选择文件按钮 //回显的列表 $list = $(‘#addFileUl‘), //选择要上传的所有文件 fileList = [], sendList = []; //当前选择上传的文件 var curFile; $file.on(‘change‘,function() { //原生的文件对象,相当于$file.get(0).files[0]; curFile = this.files; var fileNum = fileList.length; if (fileNum == 0) { //将FileList对象变成数组 fileList = fileList.concat(Array.from(curFile)); for (var i = 0, len = curFile.length; i < len; i++) { reviewFile(curFile[i]) } } else { var s = 0; for (var i = 0; i <= fileNum - 1; i++) { for (var j = 0; j <= curFile.length - 1; j++) { var isResult = isFilesEqual(curFile[0], fileList[i]); if (isResult) { s = s + 1; } } } if (s > 0) { layer.msg("不能重复添加", { icon: 2 }) } else { //将FileList对象变成数组 fileList = fileList.concat(Array.from(curFile)); for (var i = 0, len = curFile.length; i < len; i++) { reviewFile(curFile[i]) } } } }) $("#addFileUl").on(‘click‘, ‘.file-del‘,function() { let $parent = $(this).parent(); let index = $parent.index(); fileList.splice(index, 1); $parent.remove() }); //文件上传 $("#upload").on(‘click‘,function() { var myMessage=confirm(‘您确定要提交编辑内容吗?‘); if (myMessage==true) { var client_version=$("#client_version").val(); if (client_version==‘‘) { layer.msg("版本号不能为空", {icon: 5}) }else{ var dataFile=new FormData(); for (var i = 0; i <= fileList.length-1; i++) { dataFile.append("files",fileList[i]) } dataFile.append("version",client_version); $.ajax({ url: ‘savefile‘, type: ‘post‘, data: dataFile, processData: false, contentType: false, success: function(res) { layer.msg(res.data, {icon: 6}) }, error: function(res) { layer.msg("保存失败", {icon: 2}) } }) } } // }) function reviewFile(file) { //实例化fileReader, let fd = new FileReader(); //获取当前选择文件的类型、大小 //调它的readAsDataURL并把原生File对象传给它, // fd.readAsDataURL(file); //base64 // fd.onload = function() { var fileType = getFileTypeImageUrl(file.name); var fileSize=(file.size/1024).toFixed(2); $list.append(‘<li class="file-item"><img src="‘+fileType+‘" width="20" height="20"><span class="file-name">‘ + file.name + ‘(‘+file.size+‘K)</span><span style="cursor:pointer" class="file-del">删除</span></li>‘); // } } function isFilesEqual(a, b) { if ((a.name == b.name) && (a.size == b.size) && (a.lastModified == b.lastModified)) { return true; } else { return false; } } function getFileTypeImageUrl(fileName) { //1表示excel,2代表word,3代表pdf,4代表压缩文件,5代表0代表其他 var fileType = fileName.split(‘.‘); if (fileType[fileType.length - 1] === "xlsx" || fileType[fileType.length - 1] === "xls" || fileType[fileType.length - 1] === "xltx" || fileType[fileType.length - 1] === "xlt" || fileType[fileType.length - 1] === "xlsm" || fileType[fileType.length - 1] === "xlsb" || fileType[fileType.length - 1] === "xltm" || fileType[fileType.length - 1] === "csv") { return "/static/images/excel.png" } else if (fileType[fileType.length - 1] === "docx" || fileType[fileType.length - 1] === "doc" || fileType[fileType.length - 1] === "docm" || fileType[fileType.length - 1] === "dot" || fileType[fileType.length - 1] === "dotm" || fileType[fileType.length - 1] === "xml" || fileType[fileType.length - 1] === "xps" || fileType[fileType.length - 1] === "dotx") { return "/static/images/word.png" } else if (fileType[fileType.length - 1] === "pdf") { return "/static/images/pdf.jfif" } else if (fileType[fileType.length - 1] === "ppt" || fileType[fileType.length - 1] === "pptx" || fileType[fileType.length - 1] === "pptm" || fileType[fileType.length - 1] === "potx" || fileType[fileType.length - 1] === "potm" || fileType[fileType.length - 1] === "pot" || fileType[fileType.length - 1] === "ppsx" || fileType[fileType.length - 1] === "pps" || fileType[fileType.length - 1] === "ppam" || fileType[fileType.length - 1] === "ppa" || fileType[fileType.length - 1] === "ppsm") { return "/static/images/ppt.png" } else if (fileType[fileType.length - 1] === "rar" || fileType[fileType.length - 1] === "zip") { return "/static/images/zip.jfif" }else if (fileType[fileType.length - 1] === "jpg" || fileType[fileType.length - 1] === "jpeg"|| fileType[fileType.length - 1] === "png"|| fileType[fileType.length - 1] === "gif"|| fileType[fileType.length - 1] === "jfif") { return "/static/images/image.jfif" }else { return "/static/images/txt.jfif" } }
python代码
def save_file(request): if request.is_ajax(): res = request.POST client_version = res.get("version") files = request.FILES.getlist("files") path = ‘D:/demi/‘ + client_version if not files: # 文件夹存在判断,防止系统错误 pass else: dir_exist = os.path.exists(r‘D:/demi/‘ + client_version) if dir_exist: for f in files: # 这里一定要使用wb方式写入,chunks获取的数据是字节类型 with open(‘D:/demi/‘ + client_version + ‘/‘ + f.name, ‘wb+‘) as destination: for chunk in f.chunks(): destination.write(chunk) # save_client_path.my_main(client_version, path) else: os.mkdir(r‘D:/demi/‘ + client_version) for f in files: # 这里一定要使用wb方式写入,chunks获取的数据是字节类型 with open(‘D:/demi/‘ + client_version + ‘/‘ + f.name, ‘wb+‘) as destination: for chunk in f.chunks(): destination.write(chunk) # save_client_path.my_main(client_version, path) response = JsonResponse({"status": ‘服务器接收成功‘, ‘data‘: "安装包保存成功"}) return response return HttpResponse("111")
代码还有可优化的地方,直接拿来用没问题。
有bug 的话望提出
多文件上传,html+css+js(ajax)+后端django
原文:https://www.cnblogs.com/Demiwang/p/12842766.html