html5+java 文件异步读取及上传关键代码段
功能:
1.多文件文件拖拽上传,file input 多文件选择
2.html5 File Api 异步FormData,blob上传,图片显示
3.java端接受
核心代码:
1.拖拽代码段:
<div id="dropzone">
<div>Drag & drop your file here...</div>
<div id='showFile'></div>
<div style='clear: both'></div>
</div> <script>
/*function for drag and drop*/
window.onload = function() {
var dropzone = document.getElementById("dropzone");
dropzone.ondragover = dropzone.ondragenter = function(event) {
event.preventDefault();
event.stopPropagation();
}
dropzone.ondrop = function(event) {
event.preventDefault();
var filesArray = event.dataTransfer.files;
for ( var i = 0; i < filesArray.length; i++) {
var fObj = new fileObj(filesArray[i], idTmp);
// to do tasks with dropData
}
event.stopPropagation();
}
}
</script>
file input 多文件选择:
<p>
Upload File: <input id='uploadFile' type="file" name="file" multiple />
</p> <script>
$("#uploadFile").change(function(e) {
event.preventDefault();
var filesArray = e.target.files;
for ( var i = 0; i < filesArray.length; i++) {
var fObj = new fileObj(filesArray[i], idTmp);
// to do tasks with dropData
idTmp++;
}
event.stopPropagation();
});
</script>
2.html5 File Api 异步上传:
1).使用FormData上传
<!DOCTYPE html>
<html>
<head>
<title>Upload Files using XMLHttpRequest - Minimal</title> <script type="text/javascript">
function fileSelected() {
var file = document.getElementById('fileToUpload').files[0];
if (file) {
var fileSize = 0;
if (file.size > 1024 * 1024)
fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB';
else
fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB'; document.getElementById('fileName').innerHTML = 'Name: ' + file.name;
document.getElementById('fileSize').innerHTML = 'Size: ' + fileSize;
document.getElementById('fileType').innerHTML = 'Type: ' + file.type;
}
} function uploadFile() {
var fd = new FormData();
fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.addEventListener("load", uploadComplete, false);
xhr.addEventListener("error", uploadFailed, false);
xhr.addEventListener("abort", uploadCanceled, false);
xhr.open("POST", "UploadMinimal.aspx");
xhr.send(fd);
} function uploadProgress(evt) {
if (evt.lengthComputable) {
var percentComplete = Math.round(evt.loaded * 100 / evt.total);
document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%';
}
else {
document.getElementById('progressNumber').innerHTML = 'unable to compute';
}
} function uploadComplete(evt) {
/* This event is raised when the server send back a response */
alert(evt.target.responseText);
} function uploadFailed(evt) {
alert("There was an error attempting to upload the file.");
} function uploadCanceled(evt) {
alert("The upload has been canceled by the user or the browser dropped the connection.");
}
</script>
</head>
<body>
<form id="form1" enctype="multipart/form-data" method="post" action="upload.php">
<div class="row">
<label for="fileToUpload">Select a File to Upload</label>
<input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/>
</div>
<div id="fileName"></div>
<div id="fileSize"></div>
<div id="fileType"></div>
<div class="row">
<input type="button" onclick="uploadFile()" value="Upload" />
</div>
<div id="progressNumber"></div>
</form> </body>
</html>
2).使用blob,readAsBinaryString上传
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>HTML5 File Upload[By WangXinsheng]</title>
<script src="../js/jquery-1.11.1.min.js"></script>
</head>
<style>
#dropzone {
margin-top: 10px;
width: 500px;
min-height: 300px;
height: 100%;
border: 1px dotted grey;
} header {
font-weight: bold;
} .uploadFile {
display: inline;
float: left;
width: 45%;
border: 1px solid gray;
margin: 5px;
min-height: 20px;
padding-bottom: 5px;
padding-left: 5px;
} .uploadFile p {
margin: 2px;
} .uploadFile progress {
-webkit-appearance: none;
}
.uploadFile .ok{
cursor:pointer;
} .uploadFile ::-webkit-progress-inner-element { } .uploadFile ::-webkit-progress-bar {
background: white;
border: 1px solid gray;
} .uploadFile ::-webkit-progress-value {
background: green;
} .uploadFile ::-moz-progress-bar {
background: white
} .uploadFile ::-ms-fill {
background: green;
}
</style>
<body>
<header>HTML5 File Upload</header>
<p>
Upload File: <input id='uploadFile' type="file" name="file" multiple />
</p> <div id="dropzone">
<div>Drag & drop your file here...</div>
<div id='showFile'></div>
<div style='clear: both'></div>
</div>
<script>
var oneFileDom = "<div class='uploadFile' id='uf_{%id%}'>"
+"<p>{%name%}</p>"
+"<progress width='100%'></progress>"
+"<span class='ok' style='display:none;padding-left:10px;color:green;font-weight:bold__:bold;'>转换</span>"
+"</div>";
var idTmp = 0;
/*all file obj list*/
var fileObjLst = [];
/*file object*/
var fileObj = function(file, id) {
this.fileName;
this.file = file;
this.uploadSize = 0;
this.finishFlg = false;
this.sliceStart = 0;
this.maxPiece = 0;
this.blockCount = 0;
this.blockCur = 0;
this.reader = null;
this.dom;
this.id = id;
this.xhr;
}
fileObj.prototype.init = function() {
var tmpPiece = Math.ceil(this.file.size * 0.5);
this.maxPiece = tmpPiece > 1024 * 1024 * 0.2 ? 1024 * 1024 * 0.2
: (tmpPiece < 1024 * 1024 * 0.1 ? 1024 * 1024 *0.1: tmpPiece);
this.blockCount = Math.ceil(this.file.size / this.maxPiece);
this.sliceEnd = this.maxPiece;
this.fileName = new Date().getTime();
$("#showFile").prepend(
$(oneFileDom.replace('{%id%}', this.id).replace("{%name%}",
this.file.name)));
}
fileObj.prototype.send = function() {
console.log(this.id);
$("#uf_" + this.id).find("progress").attr("value", '0');
$("#uf_" + this.id).find("progress").attr("max",
this.file.size + ''); this.reader = new FileReader(); this.Bind(this.reader, "loadend", this.onloadend, this);
this.Bind(this.reader, "loadstart", this.onloadstart, this);
this.Bind(this.reader, "progress", this.onprogress, this);
this.Bind(this.reader, "load", this.onload, this); var blob, file = this.file;
console.log(file);
try {
blob = sliceBlob(file, this.sliceStart, this.sliceStart
+ this.maxPiece + 1);
} catch (e) {
console.log("error:" + e);
}
this.sliceStart = this.sliceStart + this.maxPiece + 1;
this.reader.readAsBinaryString(blob);
}
fileObj.prototype.onload = function() {
// 这个事件在读取成功结束后触发
console.log("load complete");
}
fileObj.prototype.onloadstart = function() {
// 这个事件在读取开始时触发
console.log("onloadstart");
//document.getElementById("bytesTotal").innerHTML = file.size;
}
fileObj.prototype.onprogress = function(p) {
// 这个事件在读取进行中定时触发
console.log("onprogress");
//document.getElementById("bytesRead").textContent = p.loaded;
}
fileObj.prototype.onloadend = function() {
// 这个事件在读取结束后,无论成功或者失败都会触发
//console.log(this.id);
if (this.reader.error) {
console.log(this.reader.error);
} else {
var url1 = "/ExcelToWord/morning?over=0&fileName=["
+ this.fileName + "]" + this.file.name, url2 = "/ExcelToWord/morning?over=1&fileName=["
+ this.fileName + "]" + this.file.name, url = url1;
this.blockCur++; this.uploadSize = ((this.sliceStart - 1) < this.file.size) ? (this.sliceStart - 1)
: this.file.size;
$("#uf_" + this.id).find("progress").attr("value",
this.uploadSize + '');
console.log(this.uploadSize, this.file.size);
if (this.blockCur > this.blockCount) {
//$("#uf_"+this.id).find(".ok").show();
console.log('over');
return;
} else if (this.blockCur == this.blockCount) {
// last piece
console.log('last');
url = url2;
}
console.log(this.blockCur, this.blockCount);
// 构造 XMLHttpRequest 对象,发送文件 Binary 数据
var me = this;
this.xhr = new XMLHttpRequest();
this.xhr.open("POST", url);
this.xhr.overrideMimeType("application/octet-stream");
this.xhr.sendAsBinary(this.reader.result);
this.Bind(this.xhr, "readystatechange",
this.onreadystatechange, this);
}
}
fileObj.prototype.onreadystatechange = function() {
var me = this;
if (this.xhr.readyState == 4) {
if (this.xhr.status == 200) {
console.log("upload complete");
console.log("response: " + this.xhr.responseText);
console.log("hello" + me.id);
var json = eval("(" + this.xhr.responseText + ")");
console.log(json.over);
if (json.over == "1") {
$("#uf_" + this.id).find(".ok").attr("serverName",
json.data);
$("#uf_" + this.id).find(".ok").show();
console.log('over');
return;
}
var blob, file = me.file;
try {
blob = sliceBlob(file, me.sliceStart, me.sliceStart
+ me.maxPiece + 1);
} catch (e) {
console.log("error:" + e);
}
me.sliceStart = me.sliceStart + me.maxPiece + 1;
me.reader.readAsBinaryString(blob);
}
}
}
fileObj.prototype.Bind = function(control, eventName, callBack, scope) {
if (!scope) {
scope = window;
}
$(control).bind(eventName, function() {
callBack.apply(scope, arguments);
});
}
function sliceBlob(blob, start, end, type) { type = type || blob.type; if (blob.mozSlice) {
return blob.mozSlice(start, end, type);
} else if (blob.webkitSlice) {
return blob.webkitSlice(start, end, type);
} else if (blob.slice) {
return blob.slice(start, end, type);
} else {
throw new Error("This doesn't work!");
}
}
/*function for drag and drop*/
window.onload = function() {
var dropzone = document.getElementById("dropzone");
dropzone.ondragover = dropzone.ondragenter = function(event) {
event.preventDefault();
event.stopPropagation();
}
dropzone.ondrop = function(event) {
event.preventDefault();
var filesArray = event.dataTransfer.files;
for ( var i = 0; i < filesArray.length; i++) {
var fObj = new fileObj(filesArray[i], idTmp);
fObj.init();
fObj.send(fObj);
fileObjLst.push(fObj);
idTmp++;
}
event.stopPropagation();
}
$("#uploadFile").change(function(e) {
event.preventDefault();
var filesArray = e.target.files;
for ( var i = 0; i < filesArray.length; i++) {
var fObj = new fileObj(filesArray[i], idTmp);
fObj.init();
fObj.send(fObj);
fileObjLst.push(fObj);
idTmp++;
}
event.stopPropagation();
});
} if (window.navigator.userAgent.toLowerCase().indexOf("chrome") > -1) {
XMLHttpRequest.prototype.sendAsBinary = function(datastr) {
function byteValue(x) {
return x.charCodeAt(0) & 0xff;
}
var ords = Array.prototype.map.call(datastr, byteValue);
var ui8a = new Uint8Array(ords);
this.send(ui8a.buffer);
}
}
</script>
</body>
</html>
3).Image 文件上传本地预览
// 图片文件
var reader = new FileReader();
reader.readAsDataURL(imageFile);
// reader读取完成的回调,设置src属性,显示图片.
// 或者设置css的背景属性都可
reader.onload = function(e) {
document.getElementById('imageId').src = e.target.result;
}
3.java端接受
@RequestMapping("/url")
@ResponseBody
public Map<String, Object> handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String fileName = request.getParameter("fileName");
fileName = new String(fileName.getBytes("ISO-8859-1"),"UTF-8");
String overFlg = request.getParameter("over"); // 0:go on;1:over
System.out.println("get: " + fileName);
byte[] buf = new byte[1024]; File file = new File(ExcelTmpPath + /*"[" + UUID.randomUUID().toString()
+ "]" +*/ fileName);
InputStream is = null;
BufferedOutputStream fileOut = new BufferedOutputStream(
new FileOutputStream(file, true));
try { is = request.getInputStream(); while (true) { int bytesIn = is.read(buf, 0, 1024);
System.out.println(bytesIn);
if (bytesIn == -1) {
break;
} else {
fileOut.write(buf, 0, bytesIn);
}
} fileOut.flush();
fileOut.close();
System.out.println(file.getAbsolutePath());
} catch (IOException e) {
System.out.println("error info");
}
Map<String, Object> map = new HashMap<String, Object>();
map.put("over", overFlg);
map.put("data", fileName);
return map;
}