基于springboot和vue的文本文件上传下载在线编辑功能

基于springboot和vue的文本文件上传下载在线编辑功能,前端页面比较简陋,主要是记录一下文件的上传下载逻辑


一、Maven依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--借用thymeleaf整合vue-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

二、配置文件

# 应用端口
server:
  port: 8080
spring:
  thymeleaf:
    cache: false
# 文件上传下载路径
upload:
# windows下的默认路径
  windowsFilePath: F:/my/uploadFile/
# linux下的默认路径
  linuxFilePath: /tmp/uploadFile/

三、后端接口

  • 业务接口
package com.carson.springbootfile.controller;

import com.carson.springbootfile.entity.FileVo;
import com.carson.springbootfile.entity.RequestResult;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Locale;

/**
 * @author: carson
 * @date: 20:18 2022/6/19
 * @description: 上传与下载文件接口
 */
 
@Controller
public class uploadController {
    //windows下的默认路径
    @Value("${upload.windowsFilePath}")
    private String wUpFilePath;
    //linux下的默认路径
    @Value("${upload.linuxFilePath}")
    private String lUpFilePath;

    /**
     * 上传文件
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/upload")
    @ResponseBody
    public RequestResult upload(@RequestParam("file") MultipartFile file) throws IOException {
        RequestResult requestResult = new RequestResult();
        String upFilePath = getUpFilePath();

        if(upFilePath==null||"".endsWith(upFilePath)){
            requestResult.setRequestMsg("添加失败,路径为空");
            requestResult.setRequestObject(false);
            requestResult.setRequestSuccess(false);
            return requestResult;
        }

        File file1 = new File(upFilePath);
        if(!file1.exists()){
            //不存在则创建文件路径
            file1.mkdirs();
        }

        File localFile = new File(upFilePath + file.getOriginalFilename());
        //文件写入磁盘
        file.transferTo(localFile);

        //封装返回结果
        requestResult.setRequestMsg("添加成功");
        requestResult.setRequestObject(true);
        requestResult.setRequestSuccess(true);
        return requestResult;
    }


    /**
     * 获取文件路径
     * @param fileDir
     * @return
     * @throws IOException
     */
    @GetMapping("/getFilePath")
    @ResponseBody
    public RequestResult getFilePath(@RequestParam("fileDir")String fileDir) throws IOException {
        RequestResult requestResult = new RequestResult();
        File file = new File(fileDir);

        File[] files = file.listFiles();
        requestResult.setRequestMsg("查询成功");
        requestResult.setRequestObject(files);
        requestResult.setRequestSuccess(true);
        return requestResult;
    }


    /**
     * @author: carson
     * @date: 21:45 2022/6/20
     * @description: 下载文件
     * @param fileName
     * @param response
     * @return: void
     */
    @GetMapping("/downloadFile")
    public void downloadFile(@RequestParam("fileName")String fileName,HttpServletResponse response) throws Exception {
        String upFilePath = getUpFilePath();
        File file = new File(upFilePath + fileName);
        //设置编码格式,防止下载的文件内乱码
        response.setCharacterEncoding("UTF-8");
        //获取路径文件对象
        String realFileName = file.getName();
        //设置响应头类型,这里可以根据文件类型设置,text/plain、application/vnd.ms-excel等
        response.setHeader("content-type", "application/octet-stream;charset=UTF-8");
        response.setContentType("application/octet-stream;charset=UTF-8");
        //如果不设置响应头大小,可能报错:“Excel 已完成文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃”
        response.addHeader("Content-Length", String.valueOf(file.length()));
        try{
        //Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存
        //attachment表示以附件方式下载   inline表示在线打开   "Content-Disposition: inline; filename=文件名.mp3"
        // filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
        response.setHeader("Content-Disposition", "inline;filename=" + java.net.URLEncoder.encode(realFileName.trim(), "UTF-8"));
    } catch (
    UnsupportedEncodingException e1) {
        e1.printStackTrace();
    }
    //初始化文件流字节缓存
    byte[] buff = new byte[1024];
        BufferedInputStream bis = null;
        try {
        //开始写入
        OutputStream os = response.getOutputStream();
        //写入完成,创建文件流
            bis = new BufferedInputStream(new FileInputStream(file));
        // bis.read(data):将字符读入数组。在某个输入可用、发生I/O错误或者已到达流的末尾前,此方法一直阻塞。
        // 读取的字符数,如果已到达流的末尾,则返回 -1
        int i = bis.read(buff);
        while (i != -1) {
            os.write(buff, 0, buff.length);
            os.flush();
            i = bis.read(buff);
        }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if (bis != null) {
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

    /**
     * 读取文件内容
     * @param fileName
     * @return
     */
    @GetMapping("/readFile")
    @ResponseBody
    public RequestResult readFile(@RequestParam("fileName")String fileName){
        String upFilePath = getUpFilePath();
        RequestResult requestResult = new RequestResult();
        File file = new File(upFilePath + fileName);
        StringBuilder result = new StringBuilder();
        String content = "";//文件内容
        BufferedReader br = null;
        try {
            //写入完成,创建文件流
            br = new BufferedReader(new FileReader(file));
            //使用readLine方法,一次读一行
            while((content = br.readLine())!=null){
                result.append(System.lineSeparator()+content);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //封装返回结果
        requestResult.setRequestSuccess(true);
        requestResult.setRequestObject(result.toString());
        requestResult.setRequestMsg("读取成功");
        return requestResult;
    }

    /**
     * 写入文件
     * @param vo
     * @return
     */
    @PostMapping("/writeToFile")
    @ResponseBody
    public RequestResult writeToFile(FileVo vo){
        RequestResult requestResult = new RequestResult();
        String upFilePath = getUpFilePath();
        //获取文件名
        String fileName = vo.getFileName();
        //获取文件内容
        String fileContent = vo.getFileContent();
        File file = new File(upFilePath + fileName);

        //删除旧文件
        if(file.exists())file.delete();

        //创建新文件
        try {
            file.createNewFile();
            file = new File(upFilePath + fileName);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


        try {
            //写入内容
            FileWriter fileWriter = new FileWriter(file, true);
            fileWriter.write(fileContent);
            fileWriter.flush();
            fileWriter.close();

            //封装返回结果
            requestResult.setRequestMsg("写入成功");
            requestResult.setRequestObject(upFilePath+fileName);
            requestResult.setRequestSuccess(true);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return requestResult;
    }

}
  • 页面跳转接口
package com.carson.springbootfile.controller.page;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @author: carson
 * @date: 21:18 2022/6/20
 * @description: 页面跳转
 */
@Controller
public class pageUploadController {

    @GetMapping("/index")
    public String toIndexPage(){
    //跳转到src/main/resources/templates/index.html
        return "index";
    }
}

四、前端页面

index.html

  • 引入依赖
<!-- element-ui样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!--引入vue-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<!--引入element-ui-->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<!--引入axios-->
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  • 完整前端代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!-- element-ui样式 -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <title>上传文件</title>
</head>
<!--引入vue-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<!--引入element-ui-->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<!--引入axios-->
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<body>
    <div id="app">
        <el-row>
            <el-upload
                    class="upload-demo"
                    drag
                    action="http://localhost:8080/upload"
                    :file-list="fileList"
                    :on-success="handleSuccessUpload"
                    multiple>
                <i class="el-icon-upload"></i>
                <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<!--                <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>-->
            </el-upload>
        </el-row>
        <el-row>
            <el-col :span="5">
                <el-select v-model="fileName" placeholder="请选择文件" clearable>
                    <el-option
                            v-for="item in loadFileList"
                            :key="item.value"
                            :label="item.label"
                            :value="item.value">
                    </el-option>
                </el-select>
            </el-col>
            <el-col :span="2">
                <el-button @click="downloadFile">下载</el-button>
            </el-col>
            <el-col :span="2">
                <el-button @click="readFile">读取</el-button>
            </el-col>
        </el-row>
        <el-row>
            <el-input
                    type="textarea"
                    autosize
                    placeholder="请输入内容"
                    v-model="textarea"
                    clearable>
            </el-input>
            <el-button @click="saveToFile">保存</el-button>
        </el-row>
    </div>
</body>

<script>
    new Vue({
        el: '#app',
        data() {
            return {
                fileList:[],
                loadFileList:[],
                fileName:'',
                textarea:''
            }
        },
        created(){
            var that = this
            that.getLoadFileList()
        },
        methods: {
            handleSuccessUpload(){
                this.getLoadFileList()
            },
            //下载文件
            downloadFile(){
              var that = this
                axios({
                  method:"GET",
                  url:"/downloadFile",
                  params:{
                      fileName: that.fileName
                  },
                    headers: {
                        //和后端设置的一样
                        'Content-Type': 'application/octet-stream;charset=UTF-8'
                    },
                    responseType: 'blob'
              }).then(res => {
                    var url = window.URL.createObjectURL(new Blob([res.data]));
                    var link = document.createElement('a');
                    link.href = url;
                    link.setAttribute('download', that.fileName);
                    document.body.appendChild(link);
                    link.click();
              })
            },
            //读取文件内容
            readFile(){
                var that = this
                that.textarea = ''
                axios({
                    method:"GET",
                    url:"/readFile",
                    params:{
                        fileName: that.fileName
                    }
                }).then(res =>{
                    if(res.data.requestSuccess){
                        that.textarea = res.data.requestObject
                    }
                }).catch(err=>{
                    console.log(err)
                })
            },
            //保存文件
            saveToFile(){
                var that = this
                axios({
                    method:"POST",
                    url:"/writeToFile",
                    params:{
                        fileContent: that.textarea,
                        fileName: that.fileName
                    }
                }).then(res =>{
                    if(res.data.requestSuccess){
                        that.$message.success('保存成功')
                        that.getLoadFileList()
                    }
                })
            },
            //获取文件列表
            getLoadFileList(){
                var that = this
                that.loadFileList = []
                axios({
                    method:'get',
                    url: '/getFilesInPath'
                }).then(res=>{
                    if(res.data.requestSuccess){
                        that.loadFileList = res.data.requestObject;
                    }
                })
            }
        }
    })
</script>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值