阿风啦的gravatar头像
阿风啦2021-07-31 11:41:48
vue使用原生js做下载,一个月实习生活的总结,内附后台demo源码

大家好呀,最近工作中遇到的问题,给大家做一个分享和记录。截止到九月开学,我还是一个大三的学生,所以呢,我目前还是一个练习时长一个月的开发实习生。很幸运,我到的项目组是使用开源框架开发的,就是vue + Spring Boot,我其他实习生同事被分到了老项目,还是jsp、servlet哪些东西,还会在页面里面写Java代码,确实有点……

 

虽然用到了 vue + Spring Boot ,但是呢全是用的公司的框架,就像vue,平时查看用法去vue.js官网看就行,我们公司呢,也有一个官网,上面是前端框架用法,当然呢,这个网站没有发布,得连公司内网才能访问。跟vue用法一样,有vue基础几乎都能看懂“大致意思”,看懂归看懂,自己想写还得多努力几天的哈;还有那个Spring Boot也是不常规的,就是跟我们平时在学校和在网课上看的不一样,也是公司框架┭┮﹏┭┮,有基础的话,多努力努力,做个增删改查还是上手很快的O(∩_∩)O,希望让一些还没有去工作的牛牛有一定的了解。多学习一下:SQL 、VUE 、Spring Boot ,当然为了过面试那关,还得多学习一些其他知识的。

 

(注:我是一个学后端的,但是来公司了,前后端都得写,毕竟是个搞web开发的,Html和css不可能一点不会,但是……懂得都懂┭┮﹏┭┮)

 

好的,正文开始(源码在最后):

 

目的是要用vue和后台做一个下载功能,我们平时前端调用后端一般都是使用axios,但是axios无法实现下载功能,所以我想到了,原生js,当然axios也有解决方法,大家可以自行百度了解。

 

下载Excel表格,后端呢,我知道两种方法:阿里的EasyExcel ,和阿帕奇的poi

 

easyExcel官网:https://www.yuque.com/easyexcel/doc/easyexcel (汉化,易懂)

 

里面有文件下载的例子,我就不粘过来了

 

poi : https://poi.apache.org/components/spreadsheet/quick-guide.html#ReadWriteWorkbook

 

其实下载功能我们都是用的:esponse中的OutputStream进行文件下载

一个下载小例子:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//使用response获得字节输出流
		ServletOutputStream out=response.getOutputStream();
		
		//获得服务器上面的图片
		String realpath=this.getServletContext().getRealPath("456.png");
		InputStream in=new FileInputStream(realpath);
		int len=0;
		byte[] buffer=new byte[1024];
		while((len=in.read(buffer))>0){
			out.write(buffer,0,len);
		}
		in.close();
		out.close();	
	}

 

下面就是我的源码,两种都有,注解详细:

easyexcel不要忘记,实体类哟,根据实体类上注解生成表格列名:

public class User extends BaseRowModel {
    // 主键id
    @ExcelIgnore // 生成报表时忽略,不生成次字段
    private Integer id;

    @ExcelProperty(value = "姓名", index = 0) // 定义表头名称和位置,0代表第一列
    private String name;

    @ExcelProperty(value = "年龄", index = 1)
    private Integer age;

    @ColumnWidth(20) // 定义列宽
    @DateTimeFormat(value = "yyyy/MM/dd")
    @ExcelProperty(value = "出生日期", index = 2)
    private Date birthday;
}
/*easyExcel导出*/
    @RequestMapping(value = "/exportExcel")
    public void exportExcel(HttpServletResponse response) throws IOException {
        //设置编码与文件类型
        response.setContentType("mutipart/form-data");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition","attachment;filename=test.xlsx");
        ServletOutputStream out=response.getOutputStream();
        //导出的数据
        List<User> users = userService.findAll();
        //导出并下载
        EasyExcel.write(out,User.class).sheet("test").doWrite(users);
        out.flush();
        out.close();
    }

poi:

    //poi生成xls文件并下载
    @GetMapping("/download")
    public void download(HttpServletResponse response){
        response.setContentType("application/binary;charset=UTF-8");
        try{
            ServletOutputStream out=response.getOutputStream();
            //文件名
            String name = "扫描榜单下载";
            try {
                //设置文件头:最后一个参数是设置下载文件名
                response.setHeader("Content-Disposition", "attachment;fileName=" +
                        URLEncoder.encode(name+".xls", "UTF-8"));
            } catch (UnsupportedEncodingException e1) {
                e1.printStackTrace();
            }
            //表格的列的标题
            String[] titles = { "姓名","年龄","出生日期" };
            //表格的数据,这里是查询,因为是例子,我做的查询全部,可自定义
            List<User> tops = userService.findAll();
            export(tops,titles, out);
        } catch(Exception e){
            e.printStackTrace();
        }
    }
    //转成.xls文件
    public void export(List<User> tops,String[] titles, ServletOutputStream out) throws Exception{
        try{
            // 第一步,创建一个workbook,对应一个Excel文件
            HSSFWorkbook workbook = new HSSFWorkbook();
            //表名
            String sheetName="扫描榜单";
            // 第二步,在webbook中添加一个sheet,对应Excel文件中的sheet
            HSSFSheet hssfSheet = workbook.createSheet(sheetName);

            // 第三步,在sheet中添加表头第0行(表头),注意老版本poi对Excel的行数列数有限制short

            HSSFRow row = hssfSheet.createRow(0);
            // 第四步,创建单元格,并设置值表头 设置表头居中
            HSSFCellStyle hssfCellStyle = workbook.createCellStyle();

            //居中样式
            hssfCellStyle.setAlignment(HorizontalAlignment.CENTER);
            //创建列
            HSSFCell hssfCell = null;
            for (int i = 0; i < titles.length; i++) {
                hssfCell = row.createCell(i);//列索引从0开始
                hssfCell.setCellValue(titles[i]);//列名1
                hssfCell.setCellStyle(hssfCellStyle);//列居中显示
            }
            /*把要导入的值放到一个二维数组中,表格正好对应二维数组*/
            String[][] dataList =new String[tops.size()][3];
            //将日期类型转换成字符串类型
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
            for(int i=0;i<tops.size();i++){
                dataList[i][0]=tops.get(i).getName();
                dataList[i][1]=String.valueOf(tops.get(i).getAge());
                //日期类型格式化成字符型
                dataList[i][2]=sdf.format(tops.get(i).getBirthday());
            }

            //把表格内容加入,从第二行开始
            for(int i=0;i<dataList.length;i++){
                row=hssfSheet.createRow(i+1);
                for(int j=0;j<3;j++){
                    row.createCell(j).setCellValue(dataList[i][j]);
                }
            }

            // 第七步,将文件输出到客户端浏览器
            try {
                workbook.write(out);
                out.flush();
                out.close();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }catch(Exception e){
            e.printStackTrace();
            throw new Exception("导出信息失败!");

        }
    }

 

当然第一步都是先导依赖哈

 

<!--导出导入easyexcel-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.1.4</version>
        </dependency>
        <!-- org.apache.poi/poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>

然后就是原生js发送post请求:

<button onclick="send()">测试</button>

<script>
    function post(url, params) {
        var temp = document.createElement("form");
        temp.action = url;
        temp.method = "post";
        temp.style.display = "none";
        for ( var x in params) {
            var opt = document.createElement("input");
            opt.name = x;
            opt.value = params[x];
            temp.appendChild(opt);
        }
        document.body.appendChild(temp);
        temp.submit();
        return temp;
    }
    //调用post方法,发送请求,只是例子,age写死了
    function send() {
        post(
            "http://127.0.0.1:8080/user/download",
            {
                age : 23
            });
    }
</script>

AJAX无法下载文件的原因

下载其实是浏览器的内置事件,浏览器的 GET请求(frame、a)、 POST请求(form)具有如下特点:

response会交由浏览器处理

response内容可以为二进制文件、字符串等

但是AJAX请求不一样

response会交由 Javascript 处理

response内容只能接收字符串才能继续处理

因此,AJAX本身无法触发浏览器的下载功能。

 

最后在vue中整合:

//下载,调用post请求
      download() {
        this.post({
          pageNumber: this.pageNumber,
          pageSize: this.pageSize,
          sonarState: this.appState,
          appName: this.searchContent,
          roleName: this.roleName
        });
      },
      //发送post请求
      post( params){
        var form = document.createElement("form");
        form.style.display = "none";
        form.action = 'http://localhost:8090/download';
        form.method = "post";
        document.body.appendChild(form);

        for (var key in params) {
          var input = document.createElement("input");
          input.type = "hidden";
          input.name = key;
          input.value = params[key];
          form.appendChild(input);
        }

        form.submit();
        form.remove();
        return form;
      },

后台demo下载:

链接:https://pan.baidu.com/s/1lGlE1qrN7oFSlbDsfCtBRQ 
提取码:o0ud


打赏

已有1人打赏

最代码官方的gravatar头像
最近浏览
无敌波9月14日
暂无贡献等级
天天tttt LV39月7日
星星星星星星
好的好的 LV69月5日
月亮星星星星
1739496132 LV28月31日
星星星星
Luis虎子 LV168月31日
太阳
yyqyyqqyy LV18月31日
星星
dafeiyu LV108月27日
月亮月亮星星星星
zlmbr2012 LV38月27日
星星星星星星
mengyr LV38月26日
星星星星星星
顶部客服微信二维码底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友