zoukankan      html  css  js  c++  java
  • 关于 EasyExcel 导出下载文件需要知道的那些事

    Part 1. 前言

    好记性不如烂笔头,本着自己已经在开发过程中花费了大把时间去检索“为什么不行”以及“该怎么办”的检索过程,故在这里进行整理和归纳,也将所参考的文章罗列在Part 0中,部分解决方式也经过了校验,方便大家在遇到相同问题时可以方便在茫茫的 cv 博客中找到真正能解决问题的好文(滑稽.jpg

    讲讲我为什么会遇到这个问题,首先业务测使用的文件下载工具采用的是 EasyExcel,这里放上 EasyExcel文档方便大家检索使用,我采用的是最简单的写的方式,需要明确一点,写 excelweb 端下载 excel 的区别:

    Part 2. EasyExcel 写文件

    在最简单的写 excel 中,EasyExcel 所需要的条件即文件名/文件路径、表头数据、sheet 名以及写入的数据,以官网示例为例如下:

    // WriteTest.java
    EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());
    
    private List<DemoData> data() {
        List<DemoData> list = new ArrayList<DemoData>();
        for (int i = 0; i < 10; i++) {
            DemoData data = new DemoData();
            data.setString("字符串" + i);
            data.setDate(new Date());
            data.setDoubleData(0.56);
            list.add(data);
        }
        return list;
    }
    
    // DemoData.java
    import lombok.Data;
    
    @Data
    public class DemoData {
        @ExcelProperty("字符串标题")
        private String string;
        @ExcelProperty("日期标题")
        private Date date;
        @ExcelProperty("数字标题")
        private Double doubleData;
    }
    

    需要注意的是,这里说的是文件名或文件路径,当 fileName 具体到文件路径时,excel 文件写后即写在该路径下,若 fileName 为文件名时,会写在该项目的根目录下

    以上两种方式的写 excel ,都并不是 web 端下载的方式(即浏览器下载文件的形式)来得到的,这是我最开始误会的地方

    Part 3. EasyExcel web 端写文件

    在实现 web 端的写文件之前,这里需要先明确一下自己 web 页面写文件的方式是哪一种,我这里的业务采用的是 jQuery 的 Ajax 的 Post 请求方式,过程里访问接口一直都能够正常访问,但就是没有执行 web 端的文件下载,接口返回的尽是些乱码,于是我就踏上了不断检索的道路,很庆幸检索到和我遇到相同问题的道友,并进一步验证了他的说法,下面就来谈谈为什么可以访问接口但是返回乱码且不执行 web 端下载的问题:

    首先 jQuery 所封装的 ajax 它所能接收的数据类型需要明确一下,从下图文档中可以看到,dataType 在预期的接受类型中,并不包含有二进制流数据 blob,所以直接通过 $.ajax 的方式是无法满足预期需求

    网上有提供通过更新 xhr 的方式改变 $.ajaxresponseType解决方案,我验证了下似乎没有预期效果,因为不接受 blob 类型直接进 error 的回调函数中,报错信息如下:

    DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's '' is '' or 'text' (was 'blob').
    

    这边也就不再多余的赘述,如果有成功的验证,欢迎留言指正我的误解,谢谢大家,下面介绍能够正常使用的两种方式

    • 通过 form 表单的形式进行提交

      var url = 'xxxxxxxxxxxx';
      var form = document.createElement('form');
      var xxx = document.createElement('input');
      
      form.setAttribute('style', 'display:none');
      form.setAttribute('target', '');
      form.setAttribute('method', 'post');
      form.setAttribute('action', url);
      
      xxx.type = 'hidden';
      xxx.name = 'xxx';
      xxx.value = param ? param : '';
      form.appendChild(xxx);
      
      // ...
      
      document.body.appendChild(form);
      form.appendChild(xxx);
      
      // ...
      
      form.submit();
      form.remove();
      
    • 通过原生 js 实现 ajax 的方式,即原生的XMLHttpRequest对象发出 HTTP 请求,对接收的数据先进行 createObjectURL 的包装,再通过以 <a>标签下载链接的方式触发 web 端下载该文件

      var params = {xxx:xxx};
      
      var url = 'xxxxxxxxxxxx';
      var xhr = new XMLHttpRequest();
      xhr.open('POST', url, true); // 也可以使用POST方式,根据接口
      xhr.responseType = 'blob'; // 返回类型blob
      xhr.onload = function () {
      	if (this.status === 200) {
      		var blob = this.response;
      		const url = window.URL.createObjectURL(blob);
      		const a = document.createElement('a');
      		a.style.display = 'none';
      		a.href = url;
      		a.download = 'xxx.xlsx';
      		document.body.appendChild(a);
      		a.click();
      		window.URL.revokeObjectURL(url);
      	}
      };
      // 发送ajax请求
      xhr.send(params);
      

    Part 0. Reference

    1. EasyExcel 使用说明 - 如何使用 EasyExcel
    2. web页面实现文件下载的几种方法 - 阐述 web 端文件下载方式
    3. EasyExcel实现下载Excel(解决无法从浏览器下载问题) - jQuery 的 ajax 无法接收二进制流
    4. Handle file download from ajax post
    5. Receiving binary data using JavaScript typed arrays - 二进制文件流
    6. jQuery.ajax() API 文档 - ajax API 文档
    7. 关于javascript:使用jQuery的ajax方法将图片检索为blob
    8. AJAX 之 XHR, jQuery, Fetch 的对比
  • 相关阅读:
    第一篇:spring boot 初始
    数据结构 -- 线段树
    数据结构 -- 优先队列和堆排序
    javaIO -- 流的体系设计思路、基础分类
    JavaIO -- Reader 和 Writer
    javaIO -- InputStream和OutStream
    javaIO -- File源码
    数据结构 -- 二叉树(Binary Search Tree)
    数据结构 -- 链表(LinkedList)
    数据结构 -- 栈(Stack)
  • 原文地址:https://www.cnblogs.com/S031602219/p/15059166.html
Copyright © 2011-2022 走看看