mongo读取文件压缩成压缩包在浏览器下载

基本逻辑 :将mongo文件读取到GridFsResource 转成输入流 用输出流写到本地 然后 读取本地文件 用ZipOutputStream 进行压缩 然后 输出到浏览器 删除 本地的 文件和压缩包

void downloadZipByMongodb(TtxSession sess, HttpServletRequest request, HttpServletResponse response)
            throws Exception {
            String ids = "23.jpg,23.pdf"
            List<String> paths = new ArrayList<>()
            String filePath = "D:\\test\\zip"
//            String filePath = request.getSession().getServletContext().getRealPath("");
            String[] idList = ids.split(",")

            /*	循环从mongodb下载文件*/
            for (String id : idList) {

                List<GridFSFile> gfsFile = mongoService.gridfsFindFileByName(sess.db, "files", id)?.collect({ it })
                if (gfsFile && gfsFile.size() > 0) {
                    OutputStream os = new ByteArrayOutputStream()
                    mongoService.gridfsDownloadToStream(sess.db, "files", gfsFile[0].objectId, os)
                    byte[] buffer =  os.toByteArray()
                    InputStream sbs = new ByteArrayInputStream(buffer)
                    GridFsResource gridFsResource =
                            new GridFsResource(
                                    gfsFile[0],sbs
                                    )
                    String fileName = gfsFile[0].getFilename().replace(",", "")
                    // 处理中文文件名乱码
                    if (request.getHeader("User-Agent").toUpperCase().contains("MSIE")
                            || request.getHeader("User-Agent").toUpperCase().contains("TRIDENT")
                            || request.getHeader("User-Agent").toUpperCase().contains("EDGE")) {
                        fileName = java.net.URLEncoder.encode(fileName, "UTF-8")
                    } else {
                        // 非IE浏览器的处理:
                        fileName = new String(fileName.getBytes(), StandardCharsets.UTF_8)
                    }
                    String newfilePath = filePath + File.separator + fileName
                    paths.add(newfilePath)
                    File file = new File(newfilePath)
                    copyInputStreamToFile(gridFsResource.getInputStream(), file)
                }
            }
            plistDownLoad(paths,filePath, response)
        }
    private static void copyInputStreamToFile(InputStream inputStream, File file) throws IOException {
            FileOutputStream outputStream = new FileOutputStream(file)
            int read
            byte[] bytes = new byte[1024]
            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read)
            }
            outputStream.close()
        }

    /** 批量压缩并下载 */
     void plistDownLoad(List<String> paths,String filePath , HttpServletResponse response) throws Exception {
        if (paths.size() != 0) {
            // 创建临时路径,存放压缩文件
            String zipFilePath = filePath + File.separator + "label.zip"
            // 压缩输出流,包装流,将临时文件输出流包装成压缩流,将所有文件输出到这里,打成zip包
            ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(Paths.get(zipFilePath)))
            // 循环调用压缩文件方法,将一个一个需要下载的文件打入压缩文件包
            for (String path : paths) {
                // 该方法在下面定义
                fileToZip(path, zipOut)
            }
            // 压缩完成后,关闭压缩流
            zipOut.close()
            // 拼接下载默认名称并转为ISO-8859-1格式
            String fileName = new String(("label.zip").getBytes(), StandardCharsets.UTF_8)
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName)
            // 该流不可以手动关闭,手动关闭下载会出问题,下载完成后会自动关闭
            ServletOutputStream outputStream = response.getOutputStream()
            FileInputStream inputStream = new FileInputStream(zipFilePath)
            // 如果是SpringBoot框架,在这个路径
            // org.apache.tomcat.util.http.fileupload.IOUtils产品
            // 否则需要自主引入apache的 commons-io依赖
            // copy方法为文件复制,在这里直接实现了下载效果
            IOUtils.copy(inputStream, outputStream)
            // 关闭输入流
            inputStream.close()
            outputStream.close()
            // 下载完成之后,删掉这个zip包
            File fileTempZip = new File(zipFilePath)
            fileTempZip.delete()
            /*循环删除输出到本地的文件*/
            for (String path : paths) {
                File file = new File(path)
                file.delete()
            }
        }
    }

    /** 单个文件压缩进zip文件 */
     static void fileToZip(String filePath, ZipOutputStream zipOut) throws IOException {
        // 需要压缩的文件
        File file = new File(filePath)
        // 获取文件名称,如果有特殊命名需求,可以将参数列表拓展,传fileName
        String fileName = file.getName()
        FileInputStream fileInput = new FileInputStream(filePath)
        // 缓冲
        byte[] bufferArea = new byte[1024 * 10]
        BufferedInputStream bufferStream = new BufferedInputStream(fileInput, 1024 * 10)
        // 将当前文件作为一个zip实体写入压缩流,fileName代表压缩文件中的文件名称
        zipOut.putNextEntry(new ZipEntry(fileName))
        int length = 0
        // 最常规IO操作
        while ((length = bufferStream.read(bufferArea, 0, 1024 * 10)) != -1) {
            zipOut.write(bufferArea, 0, length)
        }
        // 关闭流
        fileInput.close()
        // 需要注意的是缓冲流必须关闭掉,否则输出无效
        bufferStream.close()
        // 压缩流不必关闭,使用完后再关
    }
GridFsResource 包   compile "org.springframework.boot:spring-boot-starter-data-mongodb:1.6.1"

可参考 https://blog.csdn.net/qq_37010513/article/details/127967555

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罗小稳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值