欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

springboot和vue构建文件的下载

程序员文章站 2022-05-30 21:25:59
...

一.简介:做一个文件下载功能前后端都可以随便玩,这次主要做的是html的下载,其中html是从别人那里找到的,忘记了原链接,反正挺好看的,适合用于表白。
二.整体的构建:首先看下别人的html文件
html链接
打开效果是个动态的图片.
springboot和vue构建文件的下载
我敲,这他妹的也太好看了吧,大佬膜拜下。
然后可以分析下他的源码,我打算修改它的时间和对应表白人还有自己的姓名与标题名,其他的写的挺不错的就懒得改了。大概就是爱心里面的内容。
源码要改的
a.表白的人和自己

 <div id="loveHeart">
            <canvas id="garden"></canvas>
            <div id="words">
                <div id="messages">
                    ***,I LOVE YOU<div id="elapseClock"></div>
                </div>
                <div id="loveu">
                    Love u forever and ever.<br/>
                    <div class="signature">- LXL</div>
                </div>
            </div>
        </div>
b.标题
    <title>I Love ***</title>
c.时间
时间的计算,是当前时间减去认识的时间,所以一直在变化了。
   var offsetX = $("#loveHeart").width() / 2;
    var offsetY = $("#loveHeart").height() / 2 - 55;
    var together = new Date();
    together.setFullYear(2019, 8, 25);
    together.setHours(0);
    together.setMinutes(0);
    together.setSeconds(0);
    together.setMilliseconds(0);

d.看了下我们只要设置前端传四个参数,然后后端接收生成一个新的html,并返回展示给前端,我敲好简单的样子,确实不过对于我这种vue菜鸟就有点难搞了。
三。代码的编写
a.后端代码
写一个生成html的方法,在写一个获取html的方法。
Controller层

package com.example.demo.controller;


import com.alibaba.fastjson.JSONObject;
import com.example.demo.enetity.ResponseBean;
import com.example.demo.service.LoveHtmlService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@CrossOrigin
@RestController
@RequestMapping("/love")
public class LoveHtmlController {


    @Autowired
    LoveHtmlService loveHtmlService;


    /**
     *  用于生成html
     * @param httpServletResponse
     * @param jsonObject
     * @return
     */
    @PostMapping(value = "/html/create")
    public ResponseBean createFile(HttpServletResponse httpServletResponse, @RequestBody JSONObject jsonObject){
        return  loveHtmlService.createHtmleFile(jsonObject,httpServletResponse);
    }
    
    /**
     *  用于get下载html
     * @param httpServletResponse
     * @param jsonObject
     * @return
     */
    @GetMapping(value = "/html/down1")
    public ResponseBean createFile1(HttpServletResponse httpServletResponse, HttpServletRequest request){
        String downName = request.getParameter("downName");
        return  loveHtmlService.downLoad(downName,httpServletResponse);
    }
	 /**
     *  用于post下载html
     * @param httpServletResponse
     * @param jsonObject
     * @return
     */
    @PostMapping(value = "/html/down")
    public ResponseBean getDownFile(HttpServletResponse httpServletResponse, @RequestBody JSONObject jsonObject){
        String downName = jsonObject.getString("downName");
        return  loveHtmlService.downLoad(downName,httpServletResponse);
    }


}

2.Service层

	package com.example.demo.service;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.enetity.ResponseBean;

import javax.servlet.http.HttpServletResponse;

public interface LoveHtmlService {


     ResponseBean downLoad(String downLoad, HttpServletResponse httpServletResponse);

     ResponseBean createHtmleFile(JSONObject jsonObject, HttpServletResponse httpServletResponse);
}

3.实现类`

package com.example.demo.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.enetity.ResponseBean;
import com.example.demo.service.LoveHtmlService;
import com.example.demo.util.CommonUtils;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Calendar;
import java.util.Date;

@Service
public class LoveHtmlServiceImpl implements LoveHtmlService {
    @Override
    public ResponseBean downLoad(String downLoad, HttpServletResponse httpServletResponse) {
    	//这个是生成的html的地址
        String s = "D:\\demo\\config\\"+downLoad+".html";
        File file = new File(s);
        Date date = DateUtil.date(Calendar.getInstance());
        String s1 = DateUtil.formatTime(date);
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            //以HTTPResponse返回给前端
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.setHeader("Content-Disposition","attachment;filename="+downLoad+s1+".html");
            ServletOutputStream outputStream = httpServletResponse.getOutputStream();
            byte[] data= new byte[1024];
            int len;
            while ((len=fileInputStream.read(data))>0){
                outputStream.write(data,0,len);
            }
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return CommonUtils.succssonJson();
    }

    @Override
    public ResponseBean createHtmleFile(JSONObject jsonObject, HttpServletResponse httpServletResponse) {
    	//这个是原来的html的地址
        String s = "D:\\demo\\config\\I LOVE YOU.html";
        File file = new File(s);
        //这个方法会把html不包含在内所以后面需要再加上这个。
        String head = readHtmlTitle(file, "html");
        File file1 = new File(file.getPath().replace("I LOVE YOU", "LOVE"));
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(file1);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        //用于那四个页面元素的改变
        String yyyyMMdd = jsonObject.getString("times");
        String Time =yyyyMMdd.substring(0,4)+","+yyyyMMdd.substring(4,6)+","+yyyyMMdd.substring(6);
        String content = jsonObject.getString("content");
        String content1 = jsonObject.getString("content1");
        String content2 = jsonObject.getString("content2");
        head = head.replace("together.setFullYear(2019, 8, 25);", "together.setFullYear("+Time+");");
        head=head.replace("I Love ***",content);
        head=head.replace(" ***,I LOVE YOU!",content1);
        head=head.replace("LXL",content2);
        String head1= "<!DOCTYPE HTML>\n" +
                "<html lang=\"en\">"+head+"</html>";
        try {
            fileOutputStream.write(head1.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            openmHtml("D:\\demo\\config\\LOVE.html");
        } catch (Exception e) {
            e.printStackTrace();
        }

        return CommonUtils.succssonJson();
    }

    public    static String readHtmlTitle(File file, String title) {
        String text = "";
        try {
            FileInputStream iStream = new FileInputStream(file);
            Reader reader = new InputStreamReader(iStream);
            BufferedReader htmlReader = new BufferedReader(reader);
            String line;
            boolean found = false;
            while (!found && (line = htmlReader.readLine()) != null) {
                if (line.toLowerCase().indexOf("<" + title) != -1) { // 在<body>的前面可能存在空格
                    found = true;
                }
            }
            found = false;
            while (!found && (line = htmlReader.readLine()) != null) {
                if (line.toLowerCase().indexOf("</" + title) != -1) {
                    found = true;
                } else {
                    // 如果存在图片,则将相对路径转换为绝对路径
                    String lowerCaseLine = line.toLowerCase();
                    if (lowerCaseLine.contains("src")) {
                        String directory = "D:/test";
                        String[] splitLines = line.split("<img\\s+"); // <img后带一个或多个空格
                        // 因为java中引用的问题不能使用for each
                        for (int i = 0; i < splitLines.length; i++) {
                            if (splitLines[i].toLowerCase().startsWith("src")) {
                                splitLines[i] = splitLines[i].substring(0, splitLines[i].toLowerCase().indexOf("src") + 5)
                                        + directory
                                        + splitLines[i].substring(splitLines[i].toLowerCase().indexOf("src") + 5);
                            }
                        }
                        // 最后进行拼接
                        line = "";
                        for (int i = 0; i < splitLines.length - 1; i++) { // 循环次数要-1,因为最后一个字符串后不需要添加<img
                            line = line + splitLines[i] + "<img ";
                        }
                        line = line + splitLines[splitLines.length - 1];
                    }
                    text = text + line + "\n";
                }
            }
        } catch (Exception e) {

        }
        return text;
    }
    public static void openmHtml(String url) throws Exception {
    	// 谷歌浏览器的地址,用于打开html文件
        ProcessBuilder proc = new ProcessBuilder("C:\\Users\\86159\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe", url);
        proc.start();
    }
}

a1.后端代码的单元测试
	通过postman发请求,我的端口是8090

springboot和vue构建文件的下载
然后请求成功,同时打开页面
springboot和vue构建文件的下载
都改了,哈哈。
然后对于下载接口发送请求
springboot和vue构建文件的下载
springboot和vue构建文件的下载
值得注意的是response是一个html文件的字符串。
b。届时后端代码已经完成了,就差前端了。

<template>
  <div class="index">
  <h1>创建展示html</h1>
  <div>时间<input type="input" id="times" v-model="times"></div>
  <div>文本<input type="input" id="content" v-model="content"></div>
  <div>文本1<input type="input" id="content1" v-model="content1"></div>
  <div>文本2<input type="input" id="content2" v-model="content2"></div>
  <div class="block" v-on:click="createHtml"></div>

  <input type="input" id="downName" v-model="downName"><br/>
  <div class="block" v-on:click="downHtml"></div>
  <div class="block1" v-on:click="testGet1"></div>
  </div>
</template>

<script>
  import axios from 'axios'

  export default {
    name: 'App',
    data() {
      return {
        times: '',
        content: '',
        content1: '',
        content2: '',
        downName: '',
        test:""
      }
    },
    methods: {
      post(url, params, name, header, functionName) {
        axios.post("http://localhost:8090" + url, params,
          header
        ).then(resp => {
          this.data = resp.data
          alert(this.data)
          if (this.data.retCode == "1") {
            functionName()
          } else {
            //alert(resp.data.retMsg);
          }
        }).catch(err => {
          console.log('请求失败:' + err.status + ',' + err.statusText);
        });
      },
      post1(url, params, name, header, functionName) {
        axios.post("http://localhost:8090" + url, params,
          header
        ).then(resp => {
          this.data = resp.data
          functionName()
        }).catch(err => {
          console.log('请求失败:' + err.status + ',' + err.statusText);
        });
      },
      createHtml() {
        this.post('/love/html/create', {
          times: this.times,
          content: this.content,
          content1: this.content1,
          content2: this.content2
        }, "生成html成功", {})
      },

      get(url, params, name, header, functionName) {
        axios.get("http://192.168.203.1:8090" + url, params,
          header
        ).then(resp => {
          this.data = resp.data
     
          if (this.data.retCode == "1") {
            functionName()
          } else {
            //alert(resp.data.retMsg);
          }
        }).catch(err => {
          console.log('请求失败:' + err.status + ',' + err.statusText);
        });
      },
      testGet1() {
        this.downName = 'LOVE'
        axios.get('http://192.168.203.1:8090/love/html/down1', {
          params: {
            downName: 'LOVE'
          }
        })
          .then(resp => {
            //this.windowMethod() //用open的方式对get请求再发一次请求会下载html
       
            //this.test=resp.data
            let result = this.dataToExcelFile({data: resp.data, type: 'application/html', fileName: 'LOVE.html'}) //用流的操作写入到文件中
            //let result1=this.dataToFile({data: resp.data, type: 'application/html', fileName: 'LOVE.html'})
          })
          .catch(function (error) {
            console.log(error);
          })
      },
      testGet() {
        this.post1('/love/html/down', {
          downName: this.downName
        }, "下载成功", {}, this.windowMethod)
      },
      downHtml() {
        this.post1('/love/html/down', {
          downName: this.downName
        }, "下载成功", {}, this.windowMethod)
      },
      windowMethod() {
      //地址需要自己修改哦
        window.location.href = "http://localhost:8090/love/html/down1?downName=" + this.downName
      },
      dataToExcelFile(param) {
        let data = param.data;
        let type = param.type;
        let fileName = param.fileName;
        let blob = new Blob([data], {type: type});
        if (window.navigator.msSaveOrOpenBlob) {
          navigator.msSaveOrOpenBlob(blob, fileName);
        } else {
          let url = window.URL.createObjectURL(blob);
          let link = document.createElement('a');
          link.style.display = "none";
          link.href = url;
          link.setAttribute('download', fileName);
          document.body.appendChild(link);
          link.click();
        }
        return '0'
      },
      dataToFile(param) {
        let data = param.data;
        let type = param.type;
        let fileName = param.fileName;
        if (typeof data == 'string') {
          let bstr = data;
          let n = bstr.length;
          let u8arr = new Uint8Array(n);
          while (n--) {
            u8arr[n]=bstr.charCodeAt(n)
          }
          let blob=new Blob([u8arr],{type:type});
          if (window.navigator.msSaveOrOpenBlob) {
            navigator.msSaveOrOpenBlob(blob, fileName);
          } else {
            let url = window.URL.createObjectURL(blob);
            let link = document.createElement('a');
            alert(url);
            window.open(url);
          }
          return '0'
        } else {
          return '1'
        }
      }
    }
  }
</script>
<style scoped>
  .block {
    height: 20px;
    width: 100px;
    background-color: blue;
    margin: 0 auto;
  }
  .block1 {
    height: 20px;
    width: 100px;
    background-color: blanchedalmond;
    margin: 0 auto;
  }
  .white {
    height: 200px;
    width: 400px;
    background-color: white;
    margin: 0 auto;
  }

</style>

b1的测试
springboot和vue构建文件的下载
点击第一个蓝框,页面效果
springboot和vue构建文件的下载
哈哈,我可真厉害呢,创建html好了,该下载了
点击第二个蓝框,用post请求实现
springboot和vue构建文件的下载
下载的时候带了一个时间戳。
点粉色的,用get请求实现,后台的逻辑也是一样,但是get懒得写时间戳了就这样
springboot和vue构建文件的下载
四。总结这就基本完成了前后端文件下载与新建的了,不过没有base64加密,不是很安全,但是挺不错的,就是自己前端技术太菜了,需要一些前端的精美照片。加油吧骚年