App H5+ 实现下载、查看功能 前后端实现(SpringBoot)

复制代码
	<!doctype html>
	<html>
		<head>
			<meta charset="utf-8">
			<title>维修指南</title>
	<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0, maximum-scale=0.85, user-scalable=yes" />
			<meta name="apple-mobile-web-app-capable" content="yes">
			<meta name="apple-mobile-web-app-status-bar-style" content="black">
			<link href="../css/mui.min.css" rel="stylesheet" />
			<link rel="stylesheet" type="text/css" href="../css/mui.picker.min.css" />
			<link href="../css/mui.poppicker.css" rel="stylesheet" />
			<style>
				html,
				body {
					background-color: #efeff4;
				}
			</style>
		</head>
		<body>
			<header class="mui-bar mui-bar-nav">
				<a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a>
				<h1 id="title" class="mui-title">维修指南</h1>
			</header>
			<div class="mui-content mui-scroll-wrapper">
				<div class="mui-scroll">
					<div class="mui-card">
						<ul class="mui-table-view" id="treeMenu"> 
						
						</ul>
						
					</div>
				</div>
			</div>

			<script src="../js/jq.js"></script>
			<script src="../js/mui.min.js"></script>
			<script src="../js/device_status.js"></script>
			<script>		
				(function(jq, $, doc) {
					var info = {};
					info.type="directory";
					info.fileName="";
					info.filePath="";
					$.init({
						swipeBack: true
					});
					$.plusReady(function() {
						getFileListInfo();
					});
					
					mui("#treeMenu").on('tap','.mui-table-view-cell',function(e){
						info.type="file";
						info.fileName = this.getAttribute("id");
						info.filePath = this.getAttribute("val");
						getFileListInfo()
					})
					
					mui("#treeMenu").on('tap','.download',function(e){
						var infoDownload = {}
						infoDownload.fileName = this.getAttribute("id");
						infoDownload.filePath = this.getAttribute("val");
						
						var routePath='/viewFile';					
						routePath=deviceStatus.getAddress()+routePath + '?fileName=' + infoDownload.fileName + '&filePath=' + infoDownload.filePath;
			
						console.log(routePath)
						var url = encodeURI(routePath);
						//方式一
						// var downToak =plus.downloader.createDownload(routePath, {retryInterval:10}, function(d, status){
						// 						if(status == 200){
						// 							var btnArray = ['否', '是'];
						// 							mui.confirm('是否采用第三方方式打开?', '预览', btnArray, function(e) {
						// 								if (e.index == 1) {
						// 									plus.runtime.openFile(d.filename, {}, function(e) {//打开文件
						// 										plus.nativeUI.toast('打开失败');
						// 									});
						// 								} else {
						// 								}
						// 							});
													
						// 						}else{
						// 							plus.nativeUI.alert("文件查看失败!");  
						// 						}
						// 					});
						// 					downToak.start();
						//方式二
						
						var wait = plus.nativeUI.showWaiting("正在打开文件...");
						var dtask = plus.downloader.createDownload(url, {retryInterval:10}, function(d, status) {
								if(status == 200) {
									plus.runtime.openFile(d.filename, {}, function(e) {
										wait.close();
										mui.alert("无法打开此文件:" + e.emssage, "我的软件");
									});
									wait.close();
								} else {
									wait.close();
									mui.alert("文件打开失败: " + status, "我的软件");
								}
						});
						dtask.start();
					})
					
					
					
					function getFileListInfo(){
						deviceStatus.FileGetListInfo(info,function(list, err){
							if(err){
								$.toast(err);
								return;
							}
							var menu = ''
							mui.each(list,function(i,n){
								menu = menu + treeMenu(n)
							})
							// console.log("menu:"+menu)
							if(info.type=="directory"){
								jq('#treeMenu').append(menu);
							}
							else{
								jq('#'+info.fileName).empty();
								menu = '<a class="mui-navigate-right" href="#">'+info.fileName+'</a>'+menu
								jq('#'+info.fileName).append(menu);
							}
								
						});
					}
					
					function treeMenu(n){
						var result = ''
						if(n.children != undefined){
							result = '<li class="mui-table-view-cell mui-collapse" id="'+n.label+'" val="'+n.path+'">'+
									'<a class="mui-navigate-right" href="#">'+n.label+'</a>'
							var childFile = ''
							mui.each(n.children,function(i,n){
								childFile = childFile + treeMenu(n)
							})
							result = result + childFile + '</li>'
						}else if(n.size != undefined){
							result = '<div class="mui-row mui-collapse-content">'+
									'<p class="mui-col-sm-10 mui-col-xs-10" style="padding: 1%;">'+n.label+'</p>'+
									'<p class="mui-col-sm-2 mui-col-xs-2 download" style="padding: 1%;color:blue;"  id="'+n.label+'" val="'+n.path+'">查看</p>'+
									'</div>'
						}
						return result
					}

				}($, mui, document));
				//允许滑动
				(function() {
					mui('.mui-scroll-wrapper').scroll({
						bounce: true, //是否启用回弹
						indicators: true, //是否显示滚动条
						deceleration: 0.0006
					});
				})();
			</script>
			<style>
				
			</style>
		</body>
	</html>

Ajax

复制代码
owner.FileDownload = function(info) {
		var routePath='/viewFile';
		// callback = callback || $.noop;
		routePath=owner.getAddress()+routePath + '?fileName=' + info.fileName + '&filePath=' + encodeURI(info.filePath);
		// var userId=owner.getUser();
		// //创建访问参数
		// var paraJson={};
		// paraJson.userID=userId;
		// paraJson.file_name=info.fileName;
		// paraJson.file_path=info.filePath;
		
		// var paraData=JSON.stringify(paraJson);
		console.log(routePath)
		
		var wait = plus.nativeUI.showWaiting("正在打开文件...");
		var dtask = plus.downloader.createDownload(routePath, {retryInterval:10}, function(d, status) {
				if(status == 200) {
					plus.runtime.openFile(d.filename, {}, function(e) {
						wait.close();
						mui.alert("无法打开此文件:" + e.emssage, "我的软件");
					});
					wait.close();
				} else {
					wait.close();
					mui.alert("文件打开失败: " + status, "我的软件");
				}
		});
		dtask.start();
};

以上为前端,以下为后端

复制代码
@RequestMapping(value = "/viewFile",method = {RequestMethod.POST,RequestMethod.GET})
    public void pdfStreamHandler(HttpServletResponse response,String fileName,String filePath)  throws ServletException,IOException {

        InputStream in = null;
        String errorMsg=null;
        String userID="-1";
        try {

            fileName =java.net.URLEncoder.encode(fileName,"UTF-8");很重要!!!如果没有这样编码文件名,下载的时候,如果是中文,下载文件名会乱码。
			in = new FileInputStream(new File(filePath));//本地文件

            String fileDirPath=uploadFileParentPath+fileName;
            if(filePath==null || filePath.equals("")) {
                filePath=fileDirPath;
            }

            File file=new File(filePath);
            if(!file.exists()){
                return;
            }

            // 重置response对象中的缓冲区,该方法可以不写,但是你要保证response缓冲区没有其他数据,否则导出可能会出现问题,
            response.reset();
            response.setContentType("bin");//application/octet-stream
            // 直接下载时加attachment,预览时候不加
//			response.addHeader("Content-Disposition", "attachment; filename=\""+fileName+"\"");
            response.addHeader("Content-Disposition", "attachment; filename=\""+fileName+"\"");

            byte[] buffer = new byte[1024];
            int length;
            while ((length = in.read(buffer)) > 0) {
                response.getOutputStream().write(buffer, 0, length);
            }
        } catch (Exception e) {
//			logger.error("下载文件出错", e);
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
        }
    }
相关推荐
不能放弃治疗1 小时前
单 Agent 实现模式
后端
IT_陈寒3 小时前
Redis内存爆了,原来我漏掉了这个致命配置
前端·人工智能·后端
小bo波4 小时前
从"任意文件复制"深挖Java I/O:字符流与字节流的本质抉择
java·nio·io流·后端开发·文件复制
fliter4 小时前
最后一块拼图:用 bitvec 构造 IPv4 包,真正做出自己的 Ping
后端
用户3521802454755 小时前
🎆从 Prompt 到 Skill:让 Spring AI Agent 学会"装新技能"
人工智能·spring boot·ai编程
fliter5 小时前
用 Rust 解析并生成 ICMP 包:checksum、nom 与 cookie-factory
后端
蝎子莱莱爱打怪5 小时前
XZLL-IM干货系列 03|消息 ID 设计:一个 UUID 搞不定的事,我用两个 ID 解决了
后端·面试·开源
fliter5 小时前
从 panic 到 Result:用 Rust 重新整理一个 ping 项目的错误处理
后端
森蓝情丶6 小时前
我给 AI 搭了个法庭:一个前端仔的 LangGraph 实战全记录
前端·后端
JensCS猿6 小时前
从 Spring Boot 回看 SSM 框架:手动挡与自动挡的驾驶哲学
后端