前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端

图片拖拉拽 等比压缩上传

为了在前端对图片文件进行等比压缩后再上传到后端,可以使用 canvas 元素来实现图片的压缩。以下是一个详细的实现步骤:

  1. 前端实现图片等比压缩 :使用 canvas 元素对图片进行压缩。
  2. 前端上传压缩后的图片 :使用 el-upload 组件上传压缩后的图片。
  3. 后端接收并保存图片:在 Spring Boot 中接收上传的图片并保存。

下面是一个详细的实现示例。

1. 前端实现图片等比压缩

首先,确保你已经安装了 jszipfile-saver 库来处理文件压缩。

bash

bash 复制代码
npm install jszip file-saver

2. 创建拖拽上传组件

修改 DragUpload.vue 组件以支持图片等比压缩和上传。

vue

html 复制代码
<template>
  <div>
    <el-upload
      class="upload-dragger"
      drag
      action="http://localhost:8080/upload"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :file-list="fileList"
      :on-change="handleChange"
      :auto-upload="false"
      multiple>
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
      <template #tip>
        <div class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
      </template>
    </el-upload>
    <el-button style="margin-top: 20px;" type="success" @click="submitUpload">上传到服务器</el-button>
    <div v-if="fileList.length > 0">
      <h3>已上传文件列表:</h3>
      <ul>
        <li v-for="(file, index) in fileList" :key="index">
          {{ file.name }}
          <img v-if="isImage(file)" :src="file.url" alt="Uploaded file" style="max-width: 100px; margin-left: 10px;" />
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import { ref } from 'vue';
import JSZip from 'jszip';
import { saveAs } from 'file-saver';

export default {
  setup() {
    const fileList = ref([]);

    const handleRemove = (file, fileList) => {
      console.log(file, fileList);
    };

    const handlePreview = (file) => {
      console.log(file);
    };

    const handleChange = (file, fileList) => {
      fileList = fileList.slice(-3); // 限制最多上传3个文件
      fileList.forEach((file) => {
        if (file.raw) {
          file.url = URL.createObjectURL(file.raw);
        }
      });
      fileList.value = fileList;
    };

    const submitUpload = async () => {
      const zip = new JSZip();
      for (const file of fileList.value) {
        if (isImage(file)) {
          const compressedFile = await compressImage(file.raw);
          zip.file(file.name, compressedFile);
        } else {
          zip.file(file.name, file.raw);
        }
      }

      const content = await zip.generateAsync({ type: 'blob' });
      const formData = new FormData();
      formData.append('file', content, 'files.zip');

      const response = await fetch('http://localhost:8080/upload', {
        method: 'POST',
        body: formData
      });

      if (response.ok) {
        console.log('文件上传成功');
      } else {
        console.error('文件上传失败');
      }
    };

    const isImage = (file) => {
      const imageTypes = ['image/jpeg', 'image/png'];
      return imageTypes.includes(file.raw.type);
    };

    const compressImage = (file) => {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = (event) => {
          const img = new Image();
          img.onload = () => {
            const canvas = document.createElement('canvas');
            const MAX_WIDTH = 800; // 设置最大宽度
            const MAX_HEIGHT = 800; // 设置最大高度
            let width = img.width;
            let height = img.height;

            if (width > height) {
              if (width > MAX_WIDTH) {
                height *= MAX_WIDTH / width;
                width = MAX_WIDTH;
              }
            } else {
              if (height > MAX_HEIGHT) {
                width *= MAX_HEIGHT / height;
                height = MAX_HEIGHT;
              }
            }

            canvas.width = width;
            canvas.height = height;
            const ctx = canvas.getContext('2d');
            ctx.drawImage(img, 0, 0, width, height);

            canvas.toBlob((blob) => {
              resolve(blob);
            }, file.type, 0.8); // 0.8 是压缩质量
          };
          img.onerror = reject;
          img.src = event.target.result;
        };
        reader.onerror = reject;
        reader.readAsDataURL(file);
      });
    };

    return {
      fileList,
      handleRemove,
      handlePreview,
      handleChange,
      submitUpload,
      isImage
    };
  }
};
</script>

<style scoped>
.upload-dragger {
  width: 600px;
  margin: 0 auto;
}
</style>

3. 后端 Spring Boot 接收并解压文件

创建一个 Spring Boot 项目来接收并解压上传的文件。

3.1 添加依赖

pom.xml 中添加必要的依赖:

xml

XML 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-compress</artifactId>
        <version>1.21</version>
    </dependency>
</dependencies>
3.2 创建文件上传控制器

创建一个控制器来处理文件上传和解压。

java

java 复制代码
package com.example.demo.controller;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Enumeration;

@RestController
public class FileUploadController {

    @PostMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            // 创建临时文件存储上传的压缩文件
            File tempFile = File.createTempFile("uploaded", ".zip");
            file.transferTo(tempFile);

            // 解压文件
            ZipFile zipFile = new ZipFile(tempFile);
            Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();

            while (entries.hasMoreElements()) {
                ZipArchiveEntry entry = entries.nextElement();
                if (!entry.isDirectory()) {
                    File entryFile = new File("uploads/" + entry.getName());
                    entryFile.getParentFile().mkdirs();
                    try (InputStream inputStream = zipFile.getInputStream(entry);
                         FileOutputStream outputStream = new FileOutputStream(entryFile)) {
                        byte[] buffer = new byte[1024];
                        int length;
                        while ((length = inputStream.read(buffer)) > 0) {
                            outputStream.write(buffer, 0, length);
                        }
                    }
                }
            }

            // 删除临时文件
            tempFile.delete();

            return "文件上传并解压成功";
        } catch (Exception e) {
            e.printStackTrace();
            return "文件上传或解压失败";
        }
    }
}
3.3 配置文件上传大小限制

application.properties 中配置文件上传大小限制:

properties

java 复制代码
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
3.4 创建上传目录

确保项目中有一个 uploads 目录来存储解压后的文件。你可以在项目根目录下创建这个目录,或者在代码中动态创建。

4. 运行项目

  1. 启动 Spring Boot 项目

    bash

bash 复制代码
mvn spring-boot:run

2.启动 Vue 项目

bash

bash 复制代码
npm run serve

5. 测试上传功能

  1. 打开浏览器,访问 Vue 项目(通常是 http://localhost:8080)。
  2. 使用拖拽上传组件上传图片文件。
  3. 点击"上传到服务器"按钮,图片将被等比压缩并上传到 Spring Boot 后端。
  4. 后端接收文件并解压到 uploads 目录中。

通过以上步骤,你可以在前端实现图片等比压缩并在后端 Spring Boot 架构中接收文件。

文件的拖拉拽上传

在前端实现文件压缩并在后端 Spring Boot 架构中接收文件,可以分为以下几个步骤:

  1. 前端实现文件压缩 :使用 JavaScript 库(如 jszip)来压缩文件。
  2. 前端上传压缩后的文件 :使用 el-upload 组件上传压缩后的文件。
  3. 后端接收并解压文件:在 Spring Boot 中接收上传的压缩文件并解压。

下面是一个详细的实现示例。

1. 前端实现文件压缩

首先,安装 jszipfile-saver 库来处理文件压缩和保存。

bash

bash 复制代码
npm install jszip file-saver

2. 创建拖拽上传组件

修改 DragUpload.vue 组件以支持文件压缩和上传。

vue

html 复制代码
<template>
  <div>
    <el-upload
      class="upload-dragger"
      drag
      action="http://localhost:8080/upload"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :file-list="fileList"
      :on-change="handleChange"
      :auto-upload="false"
      multiple>
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
      <template #tip>
        <div class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
      </template>
    </el-upload>
    <el-button style="margin-top: 20px;" type="success" @click="submitUpload">上传到服务器</el-button>
    <div v-if="fileList.length > 0">
      <h3>已上传文件列表:</h3>
      <ul>
        <li v-for="(file, index) in fileList" :key="index">
          {{ file.name }}
          <img v-if="isImage(file)" :src="file.url" alt="Uploaded file" style="max-width: 100px; margin-left: 10px;" />
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import { ref } from 'vue';
import JSZip from 'jszip';
import { saveAs } from 'file-saver';

export default {
  setup() {
    const fileList = ref([]);

    const handleRemove = (file, fileList) => {
      console.log(file, fileList);
    };

    const handlePreview = (file) => {
      console.log(file);
    };

    const handleChange = (file, fileList) => {
      fileList = fileList.slice(-3); // 限制最多上传3个文件
      fileList.forEach((file) => {
        if (file.raw) {
          file.url = URL.createObjectURL(file.raw);
        }
      });
      fileList.value = fileList;
    };

    const submitUpload = async () => {
      const zip = new JSZip();
      fileList.value.forEach((file) => {
        zip.file(file.name, file.raw);
      });

      const content = await zip.generateAsync({ type: 'blob' });
      const formData = new FormData();
      formData.append('file', content, 'files.zip');

      const response = await fetch('http://localhost:8080/upload', {
        method: 'POST',
        body: formData
      });

      if (response.ok) {
        console.log('文件上传成功');
      } else {
        console.error('文件上传失败');
      }
    };

    const isImage = (file) => {
      const imageTypes = ['image/jpeg', 'image/png'];
      return imageTypes.includes(file.raw.type);
    };

    return {
      fileList,
      handleRemove,
      handlePreview,
      handleChange,
      submitUpload,
      isImage
    };
  }
};
</script>

<style scoped>
.upload-dragger {
  width: 600px;
  margin: 0 auto;
}
</style>

3. 后端 Spring Boot 接收并解压文件

创建一个 Spring Boot 项目来接收并解压上传的文件。

3.1 添加依赖

pom.xml 中添加必要的依赖:

xml

XML 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-compress</artifactId>
        <version>1.21</version>
    </dependency>
</dependencies>
3.2 创建文件上传控制器

创建一个控制器来处理文件上传和解压。

java

java 复制代码
package com.example.demo.controller;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Enumeration;

@RestController
public class FileUploadController {

    @PostMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            // 创建临时文件存储上传的压缩文件
            File tempFile = File.createTempFile("uploaded", ".zip");
            file.transferTo(tempFile);

            // 解压文件
            ZipFile zipFile = new ZipFile(tempFile);
            Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();

            while (entries.hasMoreElements()) {
                ZipArchiveEntry entry = entries.nextElement();
                if (!entry.isDirectory()) {
                    File entryFile = new File("uploads/" + entry.getName());
                    entryFile.getParentFile().mkdirs();
                    try (InputStream inputStream = zipFile.getInputStream(entry);
                         FileOutputStream outputStream = new FileOutputStream(entryFile)) {
                        byte[] buffer = new byte[1024];
                        int length;
                        while ((length = inputStream.read(buffer)) > 0) {
                            outputStream.write(buffer, 0, length);
                        }
                    }
                }
            }

            // 删除临时文件
            tempFile.delete();

            return "文件上传并解压成功";
        } catch (Exception e) {
            e.printStackTrace();
            return "文件上传或解压失败";
        }
    }
}
3.3 配置文件上传大小限制

application.properties 中配置文件上传大小限制:

properties

java 复制代码
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
3.4 创建上传目录

确保项目中有一个 uploads 目录来存储解压后的文件。你可以在项目根目录下创建这个目录,或者在代码中动态创建。

4. 运行项目

  1. 启动 Spring Boot 项目

    bash

bash 复制代码
mvn spring-boot:run

2.启动 Vue 项目

bash

bash 复制代码
npm run serve

5. 测试上传功能

  1. 打开浏览器,访问 Vue 项目(通常是 http://localhost:8080)。
  2. 使用拖拽上传组件上传文件或图片。
  3. 点击"上传到服务器"按钮,文件将被压缩并上传到 Spring Boot 后端。
  4. 后端接收文件并解压到 uploads 目录中。

通过以上步骤,你可以在前端实现文件压缩并在后端 Spring Boot 架构中接收文件。

相关推荐
前端小小王11 分钟前
React Hooks
前端·javascript·react.js
苹果醋315 分钟前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
迷途小码农零零发20 分钟前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
娃哈哈哈哈呀42 分钟前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
盛派网络小助手1 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
旭东怪1 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
荆州克莱2 小时前
mysql中局部变量_MySQL中变量的总结
spring boot·spring·spring cloud·css3·技术
ekskef_sef3 小时前
32岁前端干了8年,是继续做前端开发,还是转其它工作
前端
武昌库里写JAVA3 小时前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计
sunshine6413 小时前
【CSS】实现tag选中对钩样式
前端·css·css3