ztree+ajax实现文件树下载功能

基于java实现文件树下载,供大家参考,具体内容如下

0.项目准备工作

1.前端用到的插件库:

ztree官网

2.后端maven依赖:

<dependencies>
  <!-- servlet依赖 -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
  </dependency>

  <!-- springMVC依赖 -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.6.RELEASE</version>
  </dependency>

  <!-- 文件上传的jar包 -->
  <dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.8.0</version>
  </dependency>
  <dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
  </dependency>
     // gson可以不要,这是我测试时使用的
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.2.4</version>
    </dependency>

</dependencies>

3.web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
  <!-- 声明springMvc的核心对象 DispatcherServlet -->
  <servlet>
    <servlet-name>web</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springConfig.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>web</servlet-name>
    <url-pattern>*.mvc</url-pattern>
  </servlet-mapping>

  <!--  注册字符集过滤器,解决post请求的中文乱码问题-->
  <filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
    <init-param>
      <param-name>forRequestEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>forResponseEncoding</param-name>
      <param-value>true</param-value>
    </init-param>

  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

4.springConfig.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 开启组件扫描   -->
    <context:component-scan base-package="com.file"></context:component-scan>

    <!--声明 配置springMVC视图解析器-->
    <bean  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--前缀:视图文件的路径-->
        <property name="prefix" value="/WEB-INF/view/" />
        <!--后缀:视图文件的扩展名-->
        <property name="suffix" value=".jsp" />
    </bean>

    <!--读写JSON的支持(Jackson)-->
    <mvc:annotation-driven />

    <!--  配置多媒体解析  -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--  配置字符编码集 -->
        <property name="defaultEncoding" value="utf-8"> </property>
        <!-- 配置文件上传大小 单位是字节    -1代表没有限制 maxUploadSizePerFile是限制每个上传文件的大小,而maxUploadSize是限制总的上传文件大小  -->
        <property name="maxUploadSizePerFile" value="-1"> </property>

        <!-- ,不设置默认不限制总的上传文件大小,这里设置总的上传文件大小不超过1M(1*1024*1024) -->
        <property name="maxUploadSize" value="1048576"/>

    </bean>

</beans>

1.效果展示:

服务器端的文件目录:

2.思路分析

1、需要递归遍历某个目录,并且判断是目录还是文件
2、找到父目录和子文件的关系,构建文件对象,将该对象加入到list集合中
3、将list集合转为json,返回给前端进行渲染
4、前端渲染出来的每个文件都包含一个该文件对应的下载url,点击该文件跳转到该文件的下载接口
5、提供下载接口,前端需要传递一个文件名称,然后后端根据文件名称去遍历指定的目录,查询是否有该文件,如果有,则将该文件进行下载

先来看下如果递归遍历获取到某个目录下的所有文件:

public class Test2 {

    public static void main(String[] args) {
        File file = new File("D:\\IDE2019");
        listFile(file);

    }

    public  static void listFile(File file ) {
        // 判断该文件是否存在
        if (file.exists()){
            // 获取当前文件夹下的所有子文件
            File[] files = file.listFiles();
            if (files!=null&&files.length>0){
                // 对该文件夹进行遍历
                for (int i = 0; i < files.length; i++) {
                    //  // 如果是一个目录继续进行递归
                    if (files[i].exists()&&files[i].isDirectory()){
                        listFile(files[i]);
                    }else {
                        // 不是目录,是一个文件,则输出文件名
                          System.out.println(files[i].getName());
                    }
                }
            }
        }

    }

}

3.前端实现代码:

代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">

  <link rel="stylesheet" href="../../css/zTreeStyle/zTreeStyle.css" rel="external nofollow" type="text/css">
  <script type="text/javascript" src="../../js/jquery-1.4.4.min.js"></script>
  <script type="text/javascript" src="../../js/jquery.ztree.core.min.js"></script>

  <title>文件下载</title>
</head>
<body>

<script>
  var settingss = {
    //zTree 的唯一标识,初始化后,等于 用户定义的 zTree 容器的 id 属性值。
    treeId:"treeDemo",
    data: {
      simpleData: {
        enable: true,  //true 、 false 分别表示 使用 、 不使用 简单数据模式
        idKey: "id",   //节点数据中保存唯一标识的属性名称
        pIdKey: "pId",    //节点数据中保存其父节点唯一标识的属性名称
        rootPId: "0"  //用于修正根节点父节点数据,即 pIdKey 指定的属性值
      },
      key: {
        name: "name"  //zTree 节点数据保存节点名称的属性名称  默认值:"name"
      }
    },
    check:{
      enable:true,  //true 、 false 分别表示 显示 、不显示 复选框或单选框
      nocheckInherit:false,   //当父节点设置 nocheck = true 时,设置子节点是否自动继承 nocheck = true
      chkboxType: { "Y": "p", "N": "s" }
    },

  };

  $(document).ready(function(){
    $.ajax({
      type:"get",
      url:"/file/init.mvc",
      async:true,
      success:function(result){

        console.log(result)
        // 得到ajax返回的数据 并且初始化文件树
       var zTreeObj = $.fn.zTree.init($("#treeDemo"), settingss, result); //初始化树
        zTreeObj.expandAll(false);   //true 节点全部展开、false节点收缩

      }
    });
  });

</script>
<div>
  <ul id="treeDemo" class="ztree"></ul>
</div>
</body>
</html>

4.后端代码实现:

1.抽象出来的实例对象bean

/**
 * @author compass
 * @version 1.0
 * @date 2021-05-14 22:41
 */
public class MyFile {

    private int id;
    private int pId;
    private String name;
    private String url;

    public MyFile(int id, int pId, String name, String url) {
        this.id = id;
        this.pId = pId;
        this.name = name;
        this.url = url;
    }

    @Override
    public String toString() {
        return "MyFile{" +
                "id=" + id +
                ", pId=" + pId +
                ", name='" + name + '\'' +
                ", url='" + url + '\'' +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getpId() {
        return pId;
    }

    public void setpId(int pId) {
        this.pId = pId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

2.渲染数据和指定文件名查询文件地址的类

/**
 * @author compass
 * @version 1.0
 * @date 2021-05-15 12:31
 */
public class FilerService {

    // 将构建为文件对象的文件或目录放到list集合中
    List<MyFile> fileList = new ArrayList<>();

    /**
     * 功能:递归遍历文件,并且将文件或目录按照规定构建为对象 撞到List集合返回
     * @param file 待遍历的文件夹
     * @param index 扫描文件赋值指针 初始值为 :1
     * @return
     */
    public  List<MyFile> listAll1(File file , int index) {

        File[] listFiles=  file.listFiles();

        // 将文件或目录构建为对象
        for (int i=1;i<listFiles.length+1;i++){
            if (listFiles[i-1].isDirectory()){
                // 如果是目录 则url为空 pid=0说明是根目录
                MyFile myFile = new MyFile(i,0,listFiles[i-1].getName(),"");
                fileList.add(myFile);
            }else {
                // 如果是文件则拼接下载地址
                String filename=listFiles[i-1].getName();
                // 文件的id为:(目录id*100)+文件序列
                MyFile myFile = new MyFile((100*index)+i,index,listFiles[i-1].getName(),"http://localhost:8080/file/download.mvc?filename="+filename);
                fileList.add(myFile);
            }
        }
        // 判断该文件是否存在
        if (file.exists()){
            // 获取当前文件夹下的所有子文件
            File[] files = file.listFiles();
            if (files!=null&&files.length>0){
                // 对文件进行遍历
                for (int i = 0; i < files.length; i++) {
                    if (files[i].exists()&&files[i].isDirectory()){
                        // 如果是一个目录继续进行递归 直到找到文件为止 每遍历一个目录 index+1
                        listAll1(files[i],i+1);
                    }
                }
            }
        }
        return fileList;
    }

    // 制定文件的父目录
    String parentDir=null;

    /**
     * 根据传递过来的文件名 找到该文件的父文件夹,如果没有找到返回null
     * @param fileName 文件名
     * @param dir 需要查找的目录
     * @return
     */
    public  String getFileName(String fileName,File dir){
        if (dir.exists()){
             File[] files = dir.listFiles();
             if (files!=null&&files.length>0){
                for (int i=0;i<files.length;i++){
                    if (files[i].exists()&&files[i].isDirectory()){
                        getFileName(fileName,files[i]);
                    }else {
                        // 如果找到传递过来的文件名则赋值给 parentDir
                        if (fileName.equals(files[i].getName())){
                            parentDir=files[i].getParent();
                            break;
                        }
                    }
                }
             }
         }
        return parentDir;
    }
}

3.下载和渲染数据的Controller

/**
 * @author compass
 * @version 1.0
 * @date 2021-05-14 21:43
 */
@Controller
@RequestMapping("/file/")
public class FileDownloadController {

    // 提供访问接口
    @GetMapping("downloadIn.mvc")
    public String downloadIn(){
        return "index";
    }

    // 初始化页面数据
    @ResponseBody
    @GetMapping("init.mvc")
    public List<MyFile> test(){
        File file = new File("D:\\IDE2019\\work");
        FilerService service = new FilerService();
        // 将制定目录的文件夹 下的目录和文件构建为MyFile对象装到List集合中
        List<MyFile> listAll1 = service.listAll1(file, 1);
        // 返回Json数据给前端进行渲染
        return listAll1;
    }

    // 提供下载接口
    @GetMapping("download.mvc")
    public ResponseEntity <byte[]> fileDownload1(String filename,HttpServletRequest request) throws IOException {
        // 指定下载那个目录下的文件
        File file = new File("D:\\IDE2019\\work");
        FilerService service = new FilerService();
        // 获取到该文件的父目录
        String path = service.getFileName(filename, file);

        // 创建文件下载对象
        File downloadFile = new File(path, filename);

        HttpHeaders header = new HttpHeaders();
        header.setContentDispositionFormData("attachment",filename);
        header.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        ResponseEntity<byte[]> result = new ResponseEntity<>(FileUtils.readFileToByteArray(downloadFile), header, HttpStatus.OK);
        return result;
    }
}

测试:可以看到我们每点击一个文件都可以跳转到我们的下载接口,进行下载的。

这只是一个简单的使用,还有很多地方需要进行优化,当然也可以使用别的方法进行实现,这就是算是一个小练习吧,复习一下ajax和递归的知识。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • PHP使用ajax的post方式下载excel文件简单示例

    本文实例讲述了PHP使用ajax的post方式下载excel文件.分享给大家供大家参考,具体如下: 项目需求,前端发起ajax请求,后端生成excel并下载,同时需要在header头中,带上token验证信息,参考了很多文章,最终实现如下: PHP后端使用base64: $filename = 'demo.xlsx'; $objWriter = \PHPExcel_IOFactory::createWriter($objectPHPExcel, 'Excel2007'); ob_start();

  • jQuery使用动态渲染表单功能完成ajax文件下载

    复制代码 代码如下: // Ajax 文件下载 jQuery.download = function(url, data, method){ // 获取url和data if( url && data ){ // data 是 string 或者 array/object data = typeof data == 'string' ? data : jQuery.param(data); // 把参数组装成 form的 input var inputs = ''; jQuery.each

  • Ajax 生成流文件下载(实现代码)

    复制代码 代码如下: // 绑定导出按钮    $("#btnExport").clickCheckLogin(function () { var form = $("<form>");        form.attr('style', 'display:none');        form.attr('target', '');        form.attr('method', 'post');        form.attr('action

  • Jquery Ajax请求文件下载操作失败的原因分析及解决办法

    jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯. 废话少说,直接进入正题,我们先来分析一下失败的原因 一.失败的原因 那是因为response原因,一般请求浏览器是会处理服务器输出的response,例如生成png.文件下载等,然而ajax请求只是个"字符型"的请求,即请求的内容是以文本类型存放的.文件的下载是以二进制形式进行的,虽然可以读取到返回的response,但只是读取而已,是无法执行的,说白

  • Ajax请求二进制流进行处理(ajax异步下载文件)的简单方法

    摘要: ajax请求一个二进制流(文件),转换为Blob进行处理或者下载保存文件 需求 管理后台需要随时下载数据报表,数据要实时生成后转换为excel下载. 文件不大,页面放置"导出"按钮,点击按钮后弹出保存文件对话框保存 说明:第一种方法使用a标签直接可以满足大部分人需求,第二种方法纯粹是在说实现方法以及更好的操作体验,不需要(举一个需要第二种方法的例子:如果生成很慢就需要生成过程中禁用按钮,防止连续生成)用到的可以不用看 解决方案 方法一 请求文件的接口能改为GET则可以使用这种方

  • Ajax实现文件下载

    JQuery的ajax函数的返回类型只有xml.text.json.html等类型,没有"流"类型,所以我们要实现ajax下载,不能够使用相应的ajax函数进行文件下载.但可以用js生成一个form,用这个form提交参数,并返回"流"类型的数据.在实现过程中,页面也没有进行刷新. 1. 使用ajax,ajax的返回值类型是json,text,html,xml类型,或者可以说ajax的发送,接受都只能是string字符串,不能流类型,所以无法实现文件下载,强用会出现

  • jQuery的ajax下载blob文件

    乍一听有点蒙,之前用ng和react时也写过类似的功能,但是很顺利(所以忘记具体细节了).jquery为啥会不行呢?看了一下具体场景,发现原来jq的ajax回调已经把response的数据傻瓜式的以字符串的方式解析了. 查了一下gg,发现国内的解决方案就是在该场景下不实用jq,而是自己手动创建XMLHttpRequest.虽然这个方法很可靠,但之前封装的jq的ajax就不能使用了. 查了查jq的文档,本打算自己根据jq提供的jQuery.ajaxSetup()接口来拓展数据类型,但怎么都搞不定.

  • JQuery的AJAX实现文件下载的小例子

    复制代码 代码如下: var form=$("<form>");//定义一个form表单form.attr("style","display:none");form.attr("target","");form.attr("method","post");form.attr("action","exportData"

  • 使用Ajax生成的Excel文件并下载的实例

    很久沒有寫文章啦,今天分享一個如何在ASP.NET MVC里使用Ajax下載生成文件的方法,以下只是個人心得: 大家都應該知道,在ASP.NET MVC里,如果通過Ajax調用后臺控制器時,可以返回一個JSON對象,但并不能直接返回文件(除非刷新頁面,那就不是Ajax啦),所以如果想用Ajax生成文件并下載的話,那只要將生成的文件先保存到服務器上,然後再將文件路徑通過JSON返回,之後才可以進行下載,當然由於是暫時性存放,所以當下載完后就需要馬上刪除相應的文件. 以下是做法以動態生成Excel為

  • SpringMVC+Ajax实现文件批量上传和下载功能实例代码

    今天做了文件的上传下载,小小总结一下,基本的web项目建立及SpringMVC框架搭建此处不详细写出来了. 上传form: <form id="uploadfiles" enctype="multipart/form-data"> <input type="file" multiple="multiple" id="file_upload" name="file_upload&q

随机推荐