HTML+Springboot 实现图片上传显示进度条

该文介绍了如何使用SpringBoot创建一个文件上传接口,以及利用原生HTML和CSS实现一个简单的图片上传界面。用户可以选择图片,文件会被上传到服务器的指定目录,并显示上传进度和结果。
摘要由CSDN通过智能技术生成

目录

一、springboot实现上传接口

二、原生html+css实现图片上传

三、实现效果


一、springboot实现上传接口

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

@RestController
@RequestMapping("/file")
public class FileController {
    /*上传文件的接口*/
    @PostMapping("/upload")
    public String getUplode(@RequestPart("file") MultipartFile mf) throws IOException {

        System.out.println("单文件上传信息为:"+mf.getOriginalFilename()+",文件大小:"+mf.getSize()/1000+"kb");

        /*将文件上传到指定文件夹*/
        if (!mf.isEmpty()){
            String fileName=mf.getOriginalFilename();
            //文件上传
            mf.transferTo(new File("E:\\image\\"+fileName));
        }
        return "成功";
    }

}

二、原生html+css实现图片上传

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>上传</title>
		<style>
			.upload-border {
				border: 1px dashed #dcdfe6;
				width: 200px;
				height: 200px;
				border-radius: 6px;
				cursor: pointer;
				position: relative;
				display: inline-flex;
				justify-content: center;
				align-items: center;
			}

			.result {
				width: 100%;
				height: 100%;
				position: absolute;
				cursor: default;
				opacity: 0;
				display: none;
				background-color: #00000080;
			}

			.result_button {
				border: none;
				background-color: transparent;
				color: #e8e8e8;
			}

			.result:hover {
				opacity: 1;
			}

			.upload-border .input-upload {
				position: absolute;
				display: none;

			}

			.uploading {
				width: 100%;
				height: 100%;
				position: absolute;
				cursor: default;
				opacity: 0;
				background-color: #00000080;
				display: grid;
			}

			.progress {
				display: flex;
				flex-direction: column;
				justify-content: center;
				padding: 0 10px;
			}

			.progress-bar {
				width: 100%;
				box-sizing: border-box;
				border-radius: 100px;
				background-color: #ebeef5;
				height: 16px;
				overflow: hidden;
				position: relative;
				vertical-align: middle;
			}

			.progress-bar__inner {
				position: absolute;
				height: 100%;
				background-color: #409eff;
				text-align: right;
				border-radius: 10px;
				/* display: flex;
				justify-content: flex-end; */
				width: 50%;
			}

			.upload-border .upload-background {
				width: 100%;
				height: 100%;
				position: absolute;
				object-fit: contain;
				display: none;
			}

			.active {
				background-image: url(img/add.png);
			}

			.progress-bar__innerText {
				color: #fff;
				font-size: 6px;
				margin: 0 5px;
			}

			.progress-bar_button {
				border: none;
				background-color: transparent;
				color: #e8e8e8;
			}

			.progress-text {
				margin-top: 10px;
				text-align: center;
				display: grid;
			}
		</style>
	</head>
	<body>
		<div class="upload-border active">
			<img class="upload-background" />
			<input type="file" class="input-upload" onchange="changeFile()" />
			<div class="uploading">
				<div class="progress">
					<div class="progress-bar">
						<div class="progress-bar__inner">
							<div class="progress-bar__innerText">50%</div>
						</div>
					</div>
					<div class="progress-text">
						<span style="color: #d8d8d8;">上传中....</span>
						<button class="progress-bar_button" onclick="cancel()">取消</button>
					</div>
				</div>
			</div>
			<div class="result">
				<button class="result_button"><img src="img/close.png" /></button>
			</div>
		</div>
	</body>
	<script>
		let btn = document.querySelector(".upload-border")
		let uploading = document.querySelector(".uploading")
		let result = document.querySelector(".upload-border .result")
		let img = document.querySelector(".upload-border img")
		let progress = document.querySelector('.progress-bar__innerText');
		const fileInputs = document.querySelector('.input-upload');
		let timer;
		btn.onclick = btnclick;
		result.onclick = del;

		/**
		 * 拖拽覆盖
		 */
		btn.addEventListener('dragover', event => {
			event.stopPropagation();
			event.preventDefault();
			event.dataTransfer.dropEffect = 'copy';
		});
		/**
		 * 拖拽停留后文件上传
		 */
		btn.addEventListener('drop', event => {
			// Get the files
			event.stopPropagation();
			event.preventDefault();
			fileInputs.files = event.dataTransfer.files;
			console.log(event, event.dataTransfer);
			changeFile();
		});

		function btnclick(e) {
			console.log("父级点击", e.target.classList)
			if (e.target.classList.contains('progress-bar_button')) {
				return
			}

			if (e.target.classList.contains('result')) {
				return
			}
			if (fileInputs.files.length > 0) {
				return;
			}
			fileInputs.click()
		}


		function changeFile(e) {
			console.log("上传", fileInputs.files[0])
			if (fileInputs.files.length < 1) {
				return;
			}
			//页面先预加载图片
			let reader = new FileReader();
			reader.readAsDataURL(fileInputs.files[0]);
			reader.onload = function(a) {
				img.src = a.target.result; //等同于reader.result
				img.style.display = 'block';
			}
			upload(fileInputs.files[0]);
		}

		function cancel(e) {
			console.log("取消")
			uploading.style.opacity = 0;
			uploading.style.display = 'none';
			clearInterval(timer);
			del();
			// btn.classList.remove('result')
		}

		function del(e) {
			console.log("删除")
			if (e) {
				e.stopPropagation();
			}
			result.style.display = 'none';
			img.style.display = 'none';
			btn.classList.add('active');
			fileInputs.value = null;
		}


		function onprogress(event) {
			console.log("进度", event)
			let perenct = (event.loaded / event.total) * 100;
			let str = perenct.toFixed(2) + '%';
			document.querySelector('.progress-bar__inner').style.width = str;
			progress.textContent = str;
			uploading.style.opacity = 1;
			uploading.style.display = 'grid';
			btn.classList.remove('active');
			if (perenct == 100) {
				result.style.display = 'grid';
				uploading.style.opacity = 0;
				uploading.style.display = 'none';
			}
		}

		function upload(file) {
			console.log("服务器上传", file)
			var formData = new FormData();

			formData.append('file', file);
			let xhr = new XMLHttpRequest();
			xhr.open('post', 'http://localhost:11011/file/upload');
			// xhr.setRequestHeader('Content-Type', 'multipart/form-data');
			xhr.upload.addEventListener("progress", onprogress, false);
			xhr.addEventListener("load", uploadComplete, false);
			xhr.addEventListener("error", uploadFailed, false);
			xhr.addEventListener("abort", uploadCanceled, false);
			xhr.send(formData);
			xhr.onload = function() {
				console.log(JSON.parse(xhr.response));
			}
		}

		function uploadComplete(evt) {
			/* 当服务器响应后,这个事件就会被触发 */
			alert(evt.target.responseText);
		}

		function uploadFailed(evt) {
			alert("上传文件发生了错误尝试");
		}

		function uploadCanceled(evt) {
			alert("上传被用户取消或者浏览器断开连接");
		}
	</script>
</html>

三、实现效果

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值