Java实现下载文件到本地

2023-05-16

需求

导出文件后存留在了服务器中,需要提供下载按钮,点击后可下载到本地;(因为涉及多个文件,下载前先将文件进行压缩,提供下载压缩文件)

效果预览

clipboard.png

代码

主要方法

/**
     * 下载生成的所有在线/离线用户信息表格
     * @param request
     * @param response
     * @return 压缩文件
     * @throws FTPConnectionClosedException
     * @throws IOException
     */
    public File downloadExcel (HttpServletRequest request, HttpServletResponse response) 
            throws FTPConnectionClosedException, IOException {
        //提供下载文件前进行压缩,即服务端生成压缩文件
        File file = new File(zipPath);
        FileOutputStream fos = new FileOutputStream(file);
        ZipUtils.toZip(path, fos, true);
        //1.获取要下载的文件的绝对路径
        String realPath = zipPath;
        //2.获取要下载的文件名
        String fileName = realPath.substring(realPath.lastIndexOf(File.separator)+1);
        response.reset();        
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/octet-stream");
        //3.设置content-disposition响应头控制浏览器以下载的形式打开文件
        response.addHeader("Content-Disposition","attachment;filename=" + new String(fileName.getBytes(),"utf-8"));
        //获取文件输入流
        InputStream in = new FileInputStream(realPath);
        int len = 0;
        byte[] buffer = new byte[1024];
        OutputStream out = response.getOutputStream();
        while ((len = in.read(buffer)) > 0) {
            //将缓冲区的数据输出到客户端浏览器
            out.write(buffer,0,len);
        }
        in.close();
        return file;
    }

压缩方法[1]

    public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure)
            throws RuntimeException{
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null ;
        try {
            zos = new ZipOutputStream(out);
            File sourceFile = new File(srcDir);
            compress(sourceFile,zos,sourceFile.getName(),KeepDirStructure);
            long end = System.currentTimeMillis();
            System.out.println("压缩完成,耗时:" + (end - start) +" ms");
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils",e);
        }finally{
            if(zos != null){
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }        
    }
    
     * 递归压缩方法
     * @param sourceFile 源文件
     * @param zos        zip输出流
     * @param name       压缩后的名称
     * @param KeepDirStructure  是否保留原来的目录结构,true:保留目录结构; 
     *                          false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
     * @throws Exception
     */
    private static void compress(File sourceFile, ZipOutputStream zos, String name,
            boolean KeepDirStructure) throws Exception{
        byte[] buf = new byte[BUFFER_SIZE];
        if(sourceFile.isFile()){
            // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
            zos.putNextEntry(new ZipEntry(name));
            // copy文件到zip输出流中
            int len;
            FileInputStream in = new FileInputStream(sourceFile);
            while ((len = in.read(buf)) != -1){
                zos.write(buf, 0, len);
            }
            // Complete the entry
            zos.closeEntry();
            in.close();
        } else {
            File[] listFiles = sourceFile.listFiles();
            if(listFiles == null || listFiles.length == 0){
                // 需要保留原来的文件结构时,需要对空文件夹进行处理
                if(KeepDirStructure){
                    // 空文件夹的处理
                    zos.putNextEntry(new ZipEntry(name + "/"));
                    // 没有文件,不需要文件的copy
                    zos.closeEntry();
                }
            }else {
                for (File file : listFiles) {
                    // 判断是否需要保留原来的文件结构
                    if (KeepDirStructure) {
                        // 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
                        // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
                        compress(file, zos, name + "/" + file.getName(),KeepDirStructure);
                    } else {
                        compress(file, zos, file.getName(),KeepDirStructure);
                    }
                    
                }
            }
        }
    }

SpringMVC

@Download
    @Path("downloadExcel")
    public File DownloadExcel(HttpServletRequest request, HttpServletResponse response) throws FTPConnectionClosedException, IOException {
        File file = exportXMPPUserInfo.downloadExcel(request, response);
        return file;
    }

前端

公司内部写法,理解其中含义即可。

    ...
    <input id="downloadExcel" type="submit" value="下载" />
    ...
    
<script>
    ...
    //下载excel
    W.$('downloadExcel').on('click',function(e){    
        W.download('userLoginService/downloadExcel');
        /* W.get('userLoginService/downloadExcel').done(function(result){
            console.log("下载用户信息表");
            
        }); */
    }); 
    ...
</script>

必要的说明

目前存在下载中文的文件名出现乱码,但好在不影响其中的内容,只是文件名会乱码。有兴趣的同学可以帮忙解答下。问题链接

引用

[1] https://www.cnblogs.com/zeng1... Java实现将文件或者文件夹压缩成zip

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java实现下载文件到本地 的相关文章

  • new Date() 方法到底是获取什么时间

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 1 问题 java 中 xff0c new Date 方法 获取的时间 xff0c 究竟与当前的系统时间有什么关联 xff1f 简单的时刻对应关系吗 xff1f 2 测试环
  • Windows使用

    将压缩包安装的软件放入开始菜单 平台需求配置 平台 本文针对windows平台 xff0c 在win11上进行过测试 xff0c 其他平台请自行确认是否可用 需求 最近在安装软件时 xff0c 发现了一个问题 很多软件直接给一个压缩包 xf
  • Python装饰器高级版—Python类内定义装饰器并传递self参数

    本文重点 xff1a 解决了类里面定义的装饰器 xff0c 在同一个类里面使用的问题 xff0c 并实现了装饰器的类属性参数传递 目录 xff1a 一 基本装饰器 二 在类里定义装饰器 xff0c 装饰本类内函数 三 类装饰器 正文 xff
  • 华为交换机链路聚合命令

    配置链路聚合 1 创建聚合组 sys interface eth trunk 2 2 配置聚合模式为手工模式 interface eth trunk 2 mode manual load balance 表示手工模式 mode lacp l
  • VC EXE程序删除自身

    在开发程序过程中 xff0c 有许多情况中都需要执行程序自己把自己从物理磁盘上删除 xff0c 例如 xff0c 卸装程序 xff0c 一些黑客程序获取信息后自清除等 xff0c 我们把这些具有自删除功能的程序统称为 自杀 程序 对于一名程
  • 理解WinRT

    WinRT Windows Runtime 是微软新一代在Win8 Metro下开发框架 xff0c 它是一套面向对象 跨语言并且是Native的库 如果有人问我WinRT的核心技术是什么 xff1f 我的答案是 COM 43 Net Me
  • vim 基本使用

    vim 下基本命令 重新加载 vimrc source vimrc 列出当前缓冲区的所有文档 ls 然后使用 b 43 编号 移至该文档 选中多行 v 43 shift 然后 j k 上下移动 缩进单行 gt gt lt lt 当前行到结尾
  • hashcode()和equals()的作用、区别、联系

    介绍一 hashCode 方法和equal 方法的作用其实一样 xff0c 在Java里都是用来对比两个对象是否相等一致 xff0c 那么equal 既然已经能实现对比的功能了 xff0c 为什么还要hashCode 呢 xff1f 因为重
  • c语言文件中存入/读取double型矩阵型数据

    test c Created on Jun 1 2019 Author lgh include lt stdio h gt include lt stdlib h gt double allocation memory double int
  • windows自动更新变成了灰色,不能选择的原因

    现象 发现我的电脑 属性 自动更新里面所有的按钮都已经是灰色的了 xff0c 而且每次开机都会自动运行自动更新 xff0c 关闭进程也无法停止 xff0c 几秒钟后又会开始更新 xff0c 而且更新后会要求重新启动 控制面板里的安全中心显示
  • 在 Debian Stretch 上安装 FFmpeg

    FFmpeg 是一款流行的多媒体框架 xff0c 可以用来记录 转换数字音频 视频 xff0c 并能将其转化为流的开源计算机程序 采用LGPL或GPL许可证 它提供了录制 转换以及流化音视频的完整解决方案 它包含了非常先进的音频 视频编解码
  • MHA使用手册一:概述(基于0.56版本)

    本文基于MHA官方文档0 56版wiki翻译而成 原文链接 xff1a https github com yoshinorim mha4mysql manager wiki 概述 概述 MHA以最少的停机时间 xff08 通常在10 30秒
  • 海思开发板FFmpeg+Nginx,推流RTMP播放(优秀教程收集+实操整理)

    海思开发板FFmpeg 43 Nginx推流RTSP播放 xff08 优秀教程收集 43 实操整理 xff09 安装FFmpeg及移植FFmpeg编译问题收录 xff1a static declaration of 39 cbrt 39 f
  • mysql配置文件详解

    basedir 61 path使用给定目录作为根目录 安装目录 character sets dir 61 path给出存放着字符集的目录 datadir 61 path从给定目录读取数据库文件 pid file 61 filename为m
  • 华测服务器进不去系统,华测云服务器如何登陆

    华测云服务器如何登陆 内容精选 换一换 当您拥有一台专属主机后 xff0c 您可以在专属主机上创建相应规格族的云服务器 在专属主机上创建云服务器前 xff0c 您必须先完成以下工作 xff1a 购买专属主机如果不使用系统自动创建的默认安全组
  • 七牛云存储 CDN 使用指南

    七牛cdn 使用指南 更新于2016 3 13 分为两种情况 xff1a 1 使用七牛存储 2 直接使用七牛cdn 一 使用七牛存储 xff08 七牛的存储默认使用cdn加速 xff09 静态资源存储到七牛后 xff0c 可以使用七牛提供的
  • 如何在 Debian 中安装 DHCP 服务器

    动态主机配置协议 xff08 DHCP xff09 是一种用于使主机能够从服务器自动分配 IP 地址和相关的网络配置的网络协议 DHCP 服务器分配给 DHCP 客户端的 IP 地址处于 租用 状态 xff0c 租用时间通常取决于客户端计算
  • 重磅更新:码云企业版之项目多仓库功能上线!!!

    开发四年只会写业务代码 xff0c 分布式高并发都不会还做程序员 xff1f 现在的软件开发是越来越复杂了 xff0c 以前讲系统化 模块化 xff0c 现在讲微服务化 xff0c 前后端分离 xff0c 各种编程语言混搭 xff0c 还有
  • tracking 问题解决

    1 dir 或者C 43 43 函数读文件名 xff0c 不推荐 搞乱了名字 2 matio读写矩阵 转载于 https www cnblogs com Wanggcong p 5651081 html
  • Docker系列07—Dockerfile 详解

    Docker系列07 Dockerfile 详解 1 认识Dockerfile 1 1 镜像的生成途径 基于容器制作 dockerfile xff0c docker build 基于容器制作镜像 xff0c 已经在上篇Docker系列06

随机推荐