JAVA后台实现文件批量下载

工具类:

	/**
     * 本地文件路径
     */
	private static final String FILE_PATH = "F:\\test";
/**
     * 批量下载文件
     *
     * @param list     批量文件集合(前端只传id集合,后端去查数据库拿到文件信息)
     * @param request  request
     * @param response response
     * @param <T>      实体类 extends BaseEntityPoJo 
     */
    public static <T extends BaseEntityPoJo> void batchDownloadFile(List<T> list, HttpServletRequest request, HttpServletResponse response) {
        //设置响应头信息
        response.reset();
        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        //设置压缩包的名字,date为时间戳
        String date = DateUtil.formatDateTimeSecond(new Date());
        String downloadName = "压缩包" + date + ".zip";
        //返回客户端浏览器的版本号、类型
        String agent = request.getHeader("USER-AGENT");
        try {
            //针对IE或者以IE为内核的浏览器:
            if (agent.contains("MSIE") || agent.contains("Trident")) {
                downloadName = java.net.URLEncoder.encode(downloadName, "UTF-8");
            } else {
                //非IE浏览器的处理:
                downloadName = new String(downloadName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        response.setHeader("Content-Disposition", "attachment;fileName=\"" + downloadName + "\"");

        //设置压缩流:直接写入response,实现边压缩边下载
        ZipOutputStream zipOs = null;
        //循环将文件写入压缩流
        DataOutputStream os = null;
        //文件
        File file;
        try {
            zipOs = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
            //设置压缩方法
            zipOs.setMethod(ZipOutputStream.DEFLATED);
            //遍历文件信息(主要获取文件名/文件路径等)
            for (T t : list) {
                try {
                    //文件名(包含后缀名,如:测试.pdf)
                    Field field = t.getClass().getDeclaredField("name");
                    field.setAccessible(true);
                    String name = field.get(t).toString();
                    //本地文件路径(绝对路径,包含后缀名,如:F:\\test\\测试.pdf),这里是在windows上测试的,路径是反斜杠
                    String path = FILE_PATH + File.separator + name;
                    log.info("batchDownloadFile:[filePath:{}]", path);
                    file = new File(path);
                    if (!file.exists()) {
                        throw new RuntimeException("文件不存在");
                    }
                    //添加ZipEntry,并将ZipEntry写入文件流
                    zipOs.putNextEntry(new ZipEntry(name));
                    os = new DataOutputStream(zipOs);
                    FileInputStream fs = new FileInputStream(file);
                    byte[] b = new byte[100];
                    int length;
                    //读入需要下载的文件的内容,打包到zip文件
                    while ((length = fs.read(b)) != -1) {
                        os.write(b, 0, length);
                    }
                    //关闭流
                    fs.close();
                    zipOs.closeEntry();
					//==============此处如果是网络文件路径,可按如下方式读取=============
					/*
					//文件名(包含后缀名,如:测试.pdf)
                    Field field = t.getClass().getDeclaredField("name");
                    field.setAccessible(true);
                    String name = field.get(t).toString() + ".pdf";
                    //网络文件路径(浏览器可直接访问的路径,如:http://192.168.0.12/frame-service-gengbao/document/四川省2022第四季度报告.pdf)
                    Field urlField = t.getClass().getDeclaredField("url");
                    urlField.setAccessible(true);
                    URL url = new URL(urlField.get(t).toString());
                    URLConnection connection = url.openConnection();
                    InputStream is = connection.getInputStream();
                    //添加ZipEntry,并将ZipEntry写入文件流
                    zipOs.putNextEntry(new ZipEntry(name));
                    os = new DataOutputStream(zipOs);
                    byte[] b = new byte[100];
                    int length;
                    //读入需要下载的文件的内容,打包到zip文件
                    while ((length = is.read(b)) != -1) {
                        os.write(b, 0, length);
                    }
                    is.close();
                    zipOs.closeEntry();
                    */
                } catch (IllegalAccessException | NoSuchFieldException e) {
                    log.error("下载文件出错![{}]", e.getMessage());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭流
            try {
                if (os != null) {
                    os.flush();
                    os.close();
                }
                if (zipOs != null) {
                    zipOs.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

控制层:

	/**
     * 批量下载(测试时可改为GET请求,浏览器直接调用接口)
     *
     * @param ids      用于查询相关表获取文件信息
     * @param request  request
     * @param response response
     */
    @GetMapping("/batchDownloadFile")
    @ApiOperation("批量下载")
    public void batchDownloadFile(@RequestParam("ids") final String ids,
                                  HttpServletRequest request,
                                  HttpServletResponse response) {
        log.info("downloadPlanFile:批量下载[ids:{},request:{},response:{}]", ids, request, response);
        List<Integer> idList = ControllerHelper.splitToLong(ids);
        List<RegulatoryReport> list = service.list(idList);
        FileUtil.batchDownloadFile(list, request, response);
    }

上面用到的方法
分割字符串:

public static List<Integer> splitToLong(final String str) {
        return StringUtils.isEmpty(str) ? Collections.emptyList() : Stream.of(str.split(",")).map(Integer::valueOf).collect(Collectors.toList());
    }

获取时间戳:

	/**
     * 将日期解析成yyyyMMddHHmmss的字符串
     *
     * @param date the date
     * @return the string
     */
    public static String formatDateTimeSecond(Date date) {
        if (date == null) {
            return "";
        }
        return new SimpleDateFormat(DATETIME_STAMP_SECOND, Locale.CHINA).format(date);
    }

注意:我这里为了对各种文件通用下载,工具类用的泛型方法,如果不需要泛型的,直接传入自己需要的实体类集合就可以了。

测试接口:
在这里插入图片描述
在这里插入图片描述
其他记录:
在Java中,当变量的数据类型为File时,值的斜杠都是“\”(new File(filePath), 就会变成xx\xx\1.txt);
当变量的数据类型为String 时,斜杠都是“/”(String filePath = “xx/xx/1.txt”);

File f = new File(filePath);
String path = (f+“”).replaceAll(“\\”, “/”);把f转成String类型,然后把里面的“\”替换成“/”就行了。

  • 6
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Java 批量上传文件本地保存的步骤如下: 1. 创建一个用于接收上传文件的表单页面,使用 HTML 和 CSS 进行布局并添加上传文件的控件。 2. 在 Java 后台代码中,使用 Java 的 Servlet 或者其他框架(如 Spring MVC)来处理表单的提交。通过表单的 enctype 设置为 "multipart/form-data",使其支持文件上传。 3. 在 Servlet 中,通过获取表单的输入流,可以获得用户上传的文件信息。 4. 创建一个文件夹来保存上传的文件。可以通过使用Java的 File 类来创建文件夹,如:`File folder = new File("文件夹路径")`。可以在服务器的文件系统中指定一个路径,用于保存上传的文件。 5. 遍历用户上传的文件列表,并为每一个文件创建一个新的文件路径。使用文件的原始名称(可能需要处理文件名称中的非法字符)或者使用随机生成的文件名称来避免文件名冲突。可以使用如下代码来生成一个新的文件路径:`String newPath = folder.getPath() + File.separator + newName`。 6. 通过文件的输入流将上传的文件保存到刚刚创建的文件路径中。可以使用 Java IO 的一些类(如 FileInputSteam 和 OutputStream)来实现文件的读写操作。如:`FileOutputStream out = new FileOutputStream(newPath)`。 7. 最后关闭输入流和输出流,并释放资源。 通过以上步骤,可以实现 Java 批量上传文件并将文件保存在本地的功能。需要注意的是,在实际开发中,还需要进行一些异常处理和安全性校验(如文件类型、大小等)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值