base64方式下载文件【java、js】(绝对路径|相对路径)

需求:

点击按钮下载用户手册,用户手册文件存放在项目中的resources目录下的template文件夹中

后端:

 @RequestMapping(value = "/downLoadYhsc", method = RequestMethod.POST)
    @ResponseBody
    public Map downLoadYhsc(HttpServletResponse response) throws Exception {
        String filePath = "src/main/resources/template/xxx.docx";
        
   InputStream in = null;
        byte[] data = null;
        // 读取文件字节数组
        try {
            in = new FileInputStream(path+filePath);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        // 返回 Base64 编码过的字节数组字符串
        Map<String,String> map = new HashMap<>();
        map.put("data",encoder.encode(data));
        return map;
    }

参考链接:https://blog.csdn.net/qq_35222843/article/details/125517043

前端:

$("#downLoad").click(function () {
    $.ajax({
        url: _ctxPath + "/hj/sbhjApply/downLoadYhsc.sjson",
        async: false,
        dataType: "json",
        data: {},
        type: "post",
        success: function (data) {
            var data = window.atob(data.data); // base64解码
            var arrayBuffer = new ArrayBuffer(data.length);
            var array = new Uint8Array(arrayBuffer);
            for (var i = 0; i < data.length; i++) {
                array[i] = data.charCodeAt(i);
            }

            let blob = new Blob([array], { type: "application/download" });
            let a= document.createElement("a")
            a.href = URL.createObjectURL(blob)
            a.download = "xxx.docx" // 这里填保存成的文件名
            a.click()
            URL.revokeObjectURL(a.href)
            a.remove();
        },
        error: function (e) {
            console.log(e);
        }
    })
})

参考链接1:https://www.cnblogs.com/toggle/p/12186304.html
参考链接2:https://blog.csdn.net/zhangseu77/article/details/123740940

生产环境后端出现的问题:

Linux环境下报找不到路径:src/main/resources/template/xxxx.docx
各种百度后终于解决了这个问题,下面是改版后的后端:

    @RequestMapping(value = "/downLoadYhsc", method = RequestMethod.POST)
    @ResponseBody
    public Map downLoadYhsc(HttpServletResponse response) throws Exception {
        String filePath = "template" + File.separator + "xxx.docx";
        
   InputStream in = null;
        byte[] data = null;
        // 读取文件字节数组
        try {
            in = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath);//读取到文件流来获取文件 — 只可读取
            data = org.springframework.util.FileCopyUtils.copyToByteArray(in);
//            data = new byte[in.available()];  获取字节数组为0
//            in.read(data);    不注释掉就会报 java.io.IOException Stream closed JAVA异常
//            in.close();   不注释掉就会报 java.io.IOException Stream closed JAVA异常
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        // 返回 Base64 编码过的字节数组字符串
        Map<String,String> map = new HashMap<>();
        map.put("data",encoder.encode(data));
        return map;
    }

注意:
Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath); //使用此种方法获取文件流时,访问资源文件返回IO类为DataInputStream,该类没有重写available(),调用该方法会执行父类InputStream的available(),返回的是0,因此不能使用以下方式获取字节数组,可以使用OutputStream来获取数据

相关链接:https://blog.csdn.net/Nile_Holmes/article/details/113091421?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-113091421-blog-124729189.t5_layer_eslanding_C_0&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-113091421-blog-124729189.t5_layer_eslanding_C_0&utm_relevant_index=1

使用OutputStream来获取数据:https://blog.csdn.net/u010253246/article/details/124729189

【工具类】java获取Window和Linux系统的项目ClassPath路径:

/**
 * 在windows和linux系统下均可正常使用
 * Create by yster@foxmail.com 2018/6/6/006 14:51
 */
public class PathUtil {
    //获取项目的根路径
    public final static String classPath;
 
    static {
        //获取的是classpath路径,适用于读取resources下资源
        classPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
    }
 
    /**
     * 项目根目录
     */
    public static String getRootPath() {
        return RootPath("");
    }
 
    /**
     * 自定义追加路径
     */
    public static String getRootPath(String u_path) {
        return RootPath("/" + u_path);
    }
 
    /**
     * 私有处理方法
     */
    private static String RootPath(String u_path) {
        String rootPath = "";
        //windows下
        if ("\\".equals(File.separator)) {
            //System.out.println(classPath);
            rootPath = classPath + u_path;
            rootPath = rootPath.replaceAll("/", "\\\\");
            if (rootPath.substring(0, 1).equals("\\")) {
                rootPath = rootPath.substring(1);
            }
        }
        //linux下
        if ("/".equals(File.separator)) {
            //System.out.println(classPath);
            rootPath = classPath + u_path;
            rootPath = rootPath.replaceAll("\\\\", "/");
        }
        return rootPath;
    }
}

调用:

//自定义追加路径并格式化
System.out.println(ProjectPath.getRootPath("userImg/test.txt"));
//获取根目录
System.out.println(ProjectPath.getRootPath());

有关绝对路径、相对路径的一些讲解:https://blog.csdn.net/liudongdong19/article/details/80436350

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值