`

使用JS自动从服务器端下载文件到本地

阅读更多

1、文件下载页面用来显示要下载的文件数量和大小,以及总文件大小。数据展示这里就不贴了,就贴后面需要用到的三个弹出层吧:遮罩层、文件下载提示框、下载完成弹出框。

<!-- 遮罩层 -->
<div id="zhegai" style="display:none;width:100%;height: 100%;top:0px;left:0px;position:absolute;filter:Alpha(Opacity=50);z-index:1000;background:#000000;-moz-opacity: 0.5; opacity:.50; " >
  <iframe style="width:100%;height:100%;filter:Alpha(Opacity=10);position:absolute;z-index='1001';border:none\' frameborder=\'no\' border=\'0\' "></iframe>
</div>

<!-- 稍后框 -->
<div align="center" id="msgDiv" style="display:none; border:0px;z-index:9999999; position: absolute; text-align: center;background:none; width: 300px; font: 12px/25px Verdana, Geneva, Arial, Helvetica, sans-serif; height: 100px;margin-top:-50px; margin-left: -150px; top: 50%; left: 50%;">
	<img src="admin/img/wait.gif"/>
	<br />
	<span style="color:#fff;font-size:14px;text-align:center;font-weight:bold;">文件下载中请稍后......</span>
</div>

<!-- 关闭弹出层 -->
<div align="center" id="closeDiv" style="display:none;margin-top:-40px;height:80px;position:absolute;width:299px; overflow:hidden;background:#fff;border: 1px solid #087bb4; left:50%;top:50%;font:12px/1.6em Verdana, Geneva, Arial, Helvetica, sans-serif;lin-height:25px;z-index:9999999;margin-left:-150px;">
	<h4 id="msgTitle" onclick="closeDiv();" style="background:#20AAE5;padding:3px;margin:0px;text-align:right;height:18px;color:#fff;cursor:pointer;">[x]</h4>
	<p align="center" id="msgTxt" style="margin: 1em 0px; padding-left: 5px; padding-right: 5px;color:#666666;font-size:14px;font-weight:bold;">下载完成</p>
</div>

2、点击“下载文件到本地”按钮时触发事件以及后续处理事件:

PS:1、JS中有关使用JS获取U盘信息的功能请参考“获取磁盘信息并扫描是否连接移动磁盘之JS版

2、代码中有关文件下载的代码参考自这里

var tt = 2 *1000;//2秒扫描一次
var interval=null;
var fso = null;
var tt2 = 2 *1000;//2秒扫描一次
var downInterval=null;//文件下载扫描
var currentDisk=null;//当前正在使用的磁盘

//该方法用来从服务器下载文件到U盘
function downFileToUpan(){
	//1、先检测是否连接到U盘
	var diskArr = getDiskInfo(1,1);
	if(diskArr.length<=0){//说明没有连接U盘
		alert("请先插入磁盘");
		return false;
	}else if(diskArr.length>1){//说明至少有2块U盘
		alert("检测到有"+diskArr.length+"块磁盘,请先清除其他磁盘确保只有一块可移动磁盘\n清除之后请重新刷新该页面");
		return false;
	}else{
		currentDisk = diskArr[0];
		var availableSpace = getDiskSpace(currentDisk.AvailableSpace,1,2);//以GB为单位的U盘剩余容量
		var fileTotalSize = $("#fileTotalSize").text();//所选文件总大小
		//alert(typeof(availableSpace)+"\t"+typeof fileTotalSize);
		availableSpace = parseFloat(availableSpace);//将字符串转换成浮点数
		fileTotalSize = parseFloat(fileTotalSize);
		//alert(typeof(availableSpace)+"\t"+typeof fileTotalSize);
		fileTotalSize +=fileTotalSize*0.05;//添加10%的剩余空间,避免出现空间不足的情况
		if(availableSpace-fileTotalSize>=0){//剩余空间比文件总大小要大(可以等于,因为还留有5%的剩余空间)
			$("#zhegai").show();//遮盖层
			$("#msgDiv").show();//稍后框
			
			//从服务器端下载文件
			getFileFromServer();
		}else{
			alert("磁盘空间不够");
			return false;
		}
	}
}

/**
 * 该方法用来从服务器上下载文件
 * **/
var xh=null;
function getFileFromServer(){
	var url="MainServlet?time="+new Date().getTime();
	xh = InitAjax();
    xh.onreadystatechange = getReady;
    xh.open("GET", url, true);
    xh.send();
}

//获取XMLHttpRequest对象
function InitAjax(){
	var ajax=null;
	if(window.ActiveXObject){
		var versions = ['Microsoft.XMLHTTP', 'MSXML.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.7.0', 'Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];
		try {
			for(var i=0; i <versions.length; i++) {
				ajax = new ActiveXObject(versions[i]);
				if(ajax) {return ajax;}
			}
		}catch(e){}
	}else if(window.XMLHttpRequest)	{
		ajax = new XMLHttpRequest();
	}
	return ajax;
}
//该方法用来下载文件
function getReady() {
	if(xh.readyState == 4){
		if(xh.status == 200 || xh.status == 0) {
			var fileName = fileIsExists(currentDisk.Path);
			saveFile(fileName);//保存文件到本地
			return true;
		}else{return false;}
	}else {return false;}
}


//该方法将文件下载到本地
function saveFile(tofile) {
    var objStream;
    var imgs;
    imgs = xh.responseBody;
    objStream = new ActiveXObject("ADODB.Stream");
    objStream.Type = 1;
    objStream.open();
    objStream.write(imgs);
    //将文件流保存到指定目录
    objStream.SaveToFile(tofile);
    //检测文件是否下载完毕
    downloadFinish(tofile);
}

/**
 * 该方法用来判断文件给定的文件目录对应的文件是否存在,若存在则重新命名文件名称并判断是否存在,若还是存在,则继续重命名,否则返回文件名称
 * @param systemPath:盘符根目录
 * */
function fileIsExists(systemPath){
	var count = 1;//用来计数
	var date = new Date();
	var fileName = date.getFullYear()+""+(date.getMonth()+1)+""+date.getDate();
	var filespec = systemPath+"\\"+"下载文件("+fileName+").zip";
	
	if(fso==null){fso=new ActiveXObject("Scripting.FileSystemObject");}
	while(fso.FileExists(filespec)){//文件存在
		count++;
		filespec = systemPath+"\\"+"下载文件("+fileName+")("+count+").zip";
	}
	return filespec;
}

/**
 * 该方法用来判断文件是否下载完成
 * @param downFile:需要进行判断的文件
 * ***/
function downloadFinish(downFile){
	//alert("文件路径:"+downFile);
	if(fso==null){fso=new ActiveXObject("Scripting.FileSystemObject");}
	if(!fso.FileExists(downFile)){//不存在,也就是还没有下载完成
		downInterval = window.setInterval("downloadFinish(downFile)",tt2);//3秒判断一次重复加载
	}else{//已经存在,也就是下载完成了
		clearInterval(downInterval);//清除定时器
		window.setTimeout(function(){//3秒之后关闭
			//alert("下载完成");//需要添加定时自动关闭弹出框的功能
			$("#msgDiv").hide();//提示“正在下载”的弹出框关闭
			$("#closeDiv").show();//显示下载完成提示框
			downInterval = window.setTimeout("closeDiv()",5000);//若是不手动关闭,那么3秒后自动关闭
		},tt2);
	}
}

/**
 * 点击“关闭弹出框”中的[x]时触发该事件,该事件用来关闭弹出层
 * */
function closeDiv(){
	$("#closeDiv").hide();//下载完成提示框
	$("#zhegai").hide();//遮盖层
	clearInterval(downInterval);//清除定时器
	window.location.href="login.jsp";//跳转到首页
}

注: 在创建ActiveXObject的时候,可能会碰到“automation服务器不能创建对象”的问题,大家可以去网上搜一下解决办法,也可以参考这里

3、服务器端处理请求的servlet代码:

//1、查找要下载的文件
List<SFile> fileList = services.getFileList();//下载所有的文件
if(fileList!=null && fileList.size()>1){//最后一个为文件总大小
	//2、添加压缩包信息
	String zipName = System.currentTimeMillis()+"";//以当前时间为名称
	String zipFilePath = com.tzj.tsp.util.WebAppConfig.app("zipPath");
	if(zipFilePath==null || zipFilePath.trim().length()<=0){//说明没有设置值
		zipFilePath = request.getRealPath(""+java.io.File.separator+"")+"zip";
	}
	zipFilePath =zipFilePath+java.io.File.separator+zipName;
	File zip = new File(zipFilePath);
	if(!zip.isDirectory()){//指定目录不存在则新建   
		 zip.mkdir(); 
	}
	
	//3、将文件拷贝到压缩包中
	File fileLoad = null;
	File toLoadFile = null;//复制的文件
	SFile file = null;//要复制的文件
	for(int i=0;i<fileList.size()-1;i++){
		file = fileList.get(i);

		fileLoad = new File(file.getFilePath());
		//System.out.println((i+1)+"、"+fileLoad);
		//确保文件存在再添加
		if(fileLoad.exists() && fileLoad.isFile()){
			toLoadFile = new File(zip+java.io.File.separator+file.getFileName());
			//System.out.println(toLoadFile);
			toLoadFile = renameFile(toLoadFile);
			FileUtils.copyFile(fileLoad,toLoadFile);//将fileLoad复制到压缩文件夹中
		}
	}
	
	//4、打压缩包
	File zipFile = new File(zipFilePath+".zip");
	compress(zipFilePath,zipFile);
	
	//5、提供下载
	fileDown(zipFile,response);
	
	zipFile.delete();//5、删除文件
	FileUtils.deleteDirectory(zip);//删除目录
}

/**
 * 该方法用来文件重命名
 * @param renameFile:要进行重命名的文件
 * **/
private File renameFile(File renameFile){
	//该文件在指定的文件夹中不存在了,则退出循环
	int count=1;
	String filePath = "";//文件路径
	String fileName="";//文件名称
	int index=0;
	while(renameFile.exists()){
		count++;
		fileName = renameFile.getName();
		index = fileName.lastIndexOf(".");
		filePath = renameFile.getParent()+File.separator+fileName.substring(0,index)+"("+count+")."+fileName.substring(index);
		renameFile = new File(filePath);
	}
	return renameFile;
}
/**
 * 打压缩包
 * @param srcPathName:需要打成压缩包的文件夹路径
 * @param zipFile:压缩包名称(路径+名称+.+后缀名)
 * */
public void compress(String srcPathName,File zipFile) {  
	File srcdir = new File(srcPathName);  
    if (!srcdir.exists()){  
        throw new RuntimeException(srcPathName + "不存在!");  
    }
    if(zipFile.exists()){//说明当前目录下存在同名压缩文件
    	zipFile.delete();
    }
    Project prj = new Project();  
    Zip zip = new Zip();  
    zip.setEncoding("GBK");//设置编码,防止压缩文件名字乱码,还有被压缩文件的乱码
    zip.setProject(prj);  
    zip.setDestFile(zipFile);  
    FileSet fileSet = new FileSet();  
    fileSet.setProject(prj);  
    fileSet.setDir(srcdir);  
    zip.addFileset(fileSet);  
    zip.execute();  //执行生成
}

/**
 * 进行下载
 * @param file:File对象,需要进行下载的对象
 * */
public void fileDown(File downFile,HttpServletResponse response){
	try{
		if (!downFile.exists())
			throw new Exception("没有找到您需要的资源:" + downFile.getName()+"!");
		FileInputStream in = new FileInputStream(downFile);
		response.setHeader("Content-Disposition","attachment;filename="+ new String(downFile.getName().getBytes("GBK"),"ISO-8859-1"));
        OutputStream outputStream = response.getOutputStream();  
        int i = 0;  
        byte b[] = new byte[1024];  
        while ((i = in.read(b)) != -1) {//读取ZIP文件  
            outputStream.write(b, 0, i);//写入到页面提供下载  
        }  
        outputStream.flush();  
        outputStream.close();  
        outputStream=null;  
        response.flushBuffer(); 
    }catch(Exception e){
    	e.printStackTrace();
    }
}

 

分享到:
评论

相关推荐

    javascript实现将文件保存到本地方法汇总

    而标签"javascript 文件保存到本地"则是对文章主题的一个简洁概括,说明这是一篇专注于在客户端使用JavaScript语言保存文件到本地硬盘的方法的分享文章。 接下来,详细解析给定的示例代码: - 第一个函数saveFile...

    JS端基于download.js实现图片、视频时直接下载而不是打开预览

    针对这一问题,我们可以利用JavaScript和第三方库download.js来实现无论何种文件格式都能直接下载的功能。下面将详细解释如何通过JS实现这个功能。 首先,download.js是一个轻量级的JavaScript库,它允许你在浏览器...

    客户端从服务器下载文件

    在Android开发中,客户端从服务器下载文件是一项常见的任务,它涉及到网络编程、文件操作和多线程技术。本文将深入探讨这一主题,提供客户端和服务器端的实现策略,并结合具体的代码示例进行讲解。 首先,我们需要...

    通过Js实现Html转换成Word下载

    在现代Web应用中,将HTML页面转换为可下载的...这种方法避免了服务器端处理,提高了用户体验,尤其适用于那些找不到Word版本的文件。但也要意识到,由于技术限制,转换可能不会完全精确,需要根据实际情况进行优化。

    HTTP文件下载服务器

    在这个场景中,服务器端运行的程序接收到来自客户端的HTTP GET请求,请求的目标是存在于"file"目录下的文件。服务器解析请求,找到对应的文件,然后将文件内容以HTTP响应的形式发送回客户端,客户端浏览器则负责展示...

    下载连接图片、js、css文件

    标题 "下载连接图片、js、css文件" 描述了一个实用的PHP程序,它能够自动抓取指定URL中的静态资源,包括图片(image)、JavaScript(js)文件和样式表(css)。这个程序对于开发者来说非常有价值,因为它可以帮助...

    本地服务器读文件

    1. **启动本地服务器**:通常我们使用Node.js这样的服务器端运行环境,结合Express.js这样的框架来搭建本地服务器。Express.js是一个轻量级、灵活的HTTP服务器框架,非常适合快速构建Web应用。 2. **设置静态文件...

    Node.js-瓦雀可以帮你把本地的文档markdown目录发布到语雀上

    Node.js是一种基于Chrome V8引擎的JavaScript运行环境,它让开发者能够在服务器端使用JavaScript编写代码,极大地推动了全栈开发的进程。在这个“Node.js-瓦雀可以帮你把本地的文档markdown目录发布到语雀上”的主题...

    web服务器端调用客户端可执行文件

    在IT领域,尤其是在Web开发中,"web服务器端调用客户端可执行文件"是一个涉及到多个技术栈的概念。这个过程通常涉及到服务器与客户端之间的交互,利用JavaScript、PHP等技术来实现。下面将详细解释这一主题。 首先...

    模拟服务器端服务

    例如,Java开发者可以使用官方提供的Java客户端,而JavaScript开发者则可以通过Node.js的npm包进行交互。 另一款常用工具是`WireMock`,它专门设计用于模拟HTTP服务,尤其适合Java项目。`WireMock`可以静态或动态地...

    nodejs 做本地web服务器

    Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它让开发者可以用 JavaScript 语言编写服务器端程序。由于其轻量级、高效的特点,Node.js 成为了搭建本地 Web 服务器的首选工具之一。在本文中,我们将...

    android上传文件至服务器提供客户端下载

    1. **接收请求**:服务器端通常由Web服务器(如Apache或Nginx)和后端应用程序(如Java的Spring Boot、Python的Django或Node.js的Express)组成。后端应用程序需要监听并处理HTTP POST请求。 2. **文件存储**:接收...

    Highcharts导出图片到本地指定路径

    导出图片通常涉及到服务器端处理,因为浏览器出于安全考虑,不允许JavaScript直接将文件写入本地。因此,我们需要向服务器发送一个请求,携带图表的SVG数据,然后由服务器生成图片并返回给客户端。这通常通过`...

    安卓实现录音的AAC格式,并上传到服务器,然后下载播放.zip

    服务器端需要接收上传的AAC文件,通常保存在特定目录下,可以使用PHP、Python、Node.js等后端语言来实现。接收到文件后,可能需要进行验证、存储、生成访问链接等操作。 5. **下载**: 当需要下载时,服务器会...

    JavaScript_代理服务器,为本地主机上的任何应用程序或网站生成API规范.zip

    Node.js是一个基于Chrome V8引擎的JavaScript运行环境,允许开发者在服务器端使用JavaScript。通过安装和配置http-proxy-middleware,我们可以创建一个代理服务器,将本地请求转发到远程API服务器,同时处理跨域问题...

    kindeditor文本编辑器实例(包含本地图片上传及浏览服务器方法)

    首先,你需要从KindEditor官方网站下载最新版本的源码包,然后将包含CSS、JavaScript和图片资源的文件部署到你的项目中。在HTML页面中引入KindEditor的脚本文件,并通过JavaScript初始化编辑器,指定编辑器的ID、...

    文档api系统服务器端代码

    "文档API系统服务器端代码"主要涉及的是构建一个能够处理文档相关的RESTful API服务的后端开发工作。在这个系统中,服务器端代码是核心部分,它负责接收客户端(如Web应用、移动应用或其他API消费者)的请求,进行...

    http本地测试服务器

    6. 自动重载:当检测到文件更改时,服务器能自动重新加载,节省手动刷新页面的时间。 在开发过程中,利用这样的HTTP本地测试服务器,开发者可以避免频繁上传文件到远程服务器,直接在本地查看效果,降低了开发成本...

    蝙蝠CKEditor本地图片自动上传插件.zip

    本插件使用JAVA技术开发,需要配合Javascript使用,可以将网页中含有的本地图片(src为'file:///')自动上传到服务器并修改img标签的src属性为新的图片地址。典型应用场景如:配合ckEditor使用,使从WORD粘贴...

Global site tag (gtag.js) - Google Analytics