当前位置:   article > 正文

Java项目硅谷课堂学习笔记-P6整合腾讯云对象存储和课程分类管理_腾讯云文件存储整合java

腾讯云文件存储整合java

1.整合腾讯云存储

1.1进入腾讯云

在这里插入图片描述

1.2创建Bucket

 	 	在这里插入图片描述

1.3创建完成Bucket,在控制台完成上传测试

在这里插入图片描述

1.5 创建当前腾讯云账号的秘钥

1.6腾讯云文档代码编写

1.6.1 引入依赖

<dependency>
       <groupId>com.qcloud</groupId>
       <artifactId>cos_api</artifactId>
       <version>5.6.89</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

1.6.3进行配置,完成上传功能

需要自己配置的参数

  • tmpSecretId

  • tmpSecretKey
    在这里插入图片描述

  • COS_REGION
    在这里插入图片描述

  • localFilePath:要上传的文件所在磁盘路径

  • bucketName
    在这里插入图片描述

  • exampleobject:上传到腾讯云 哪个文件夹下以及上传文件的名称 如 “/图片/5.jpg”

import com.alibaba.fastjson.JSON;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;

import java.io.File;
public class TestCos {
    public static void main(String[] args) {
		// 1 传入获取到的临时密钥 (tmpSecretId, tmpSecretKey, sessionToken)
		String tmpSecretId = "SECRETID";
		String tmpSecretKey = "SECRETKEY";
		String sessionToken = "TOKEN";
		BasicSessionCredentials cred = new BasicSessionCredentials(tmpSecretId, tmpSecretKey, sessionToken);
		// 2 设置 bucket 的地域, COS 地域的简称请参阅 https://cloud.tencent.com/document/product/436/6224
		// clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参阅源码或者常见问题 Java SDK 部分
		Region region = new Region("COS_REGION");
		ClientConfig clientConfig = new ClientConfig(region);
		// 3 生成 cos 客户端
		COSClient cosClient = new COSClient(cred, clientConfig);

			// 指定要上传的文件
		File localFile = new File(localFilePath);
		// 指定文件将要存放的存储桶
		String bucketName = "examplebucket-1250000000";
		// 指定文件上传到 COS 上的路径,即对象键。例如对象键为folder/picture.jpg,则表示将文件 picture.jpg 上传到 folder 路径下
		String key = "exampleobject";
		PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile);
		PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);

		}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

1.7讲师头像上传-后端代码

1.7.1 在配置文件中,添加腾讯云存储的相关配置

spring.servlet.multipart.max-file-size=1024MB
spring.servlet.multipart.max-request-size=1024MB

#不同的服务器,地址不同
tencent.cos.file.region=ap-beijing
tencent.cos.file.secretid=你的id
tencent.cos.file.secretkey=你的key
#bucket可以在控制台创建,也可以使用java代码创建
tencent.cos.file.bucketname=你的bucketName
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

1.7.2创建工具 类

package com.jq.vod.utils;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class ConstantPropertiesUtil implements InitializingBean {

    @Value("${tencent.cos.file.region}") //读取配置文件的值
    private String region;

    @Value("${tencent.cos.file.secretid}")
    private String secretId;

    @Value("${tencent.cos.file.secretkey}")
    private String secretKey;

    @Value("${tencent.cos.file.bucketname}")
    private String bucketName;


    public static String END_POINT;
    public static String ACCESS_KEY_ID;
    public static String ACCESS_KEY_SECRET;
    public static String BUCKET_NAME;

    @Override
    public void afterPropertiesSet() throws Exception {
        END_POINT=region;
        ACCESS_KEY_ID = secretId;
        ACCESS_KEY_SECRET = secretKey;
        BUCKET_NAME = bucketName;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

1.7.3Controller层-上传头像

package com.jq.vod.controller;

import com.jq.result.Result;
import com.jq.vod.service.FileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@Api(tags = "文件上传接口")
@RestController
@RequestMapping("/admin/vod/file")
@CrossOrigin
public class FileUploadController {


    @Autowired
    private FileService fileService;

    @ApiOperation("文件上传")
    @PostMapping("upload")
    public Result uploadFile(MultipartFile file){
        String url=fileService.upload(file);
        return Result.ok(url).message("上传文件成功");
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

1.7.4Service层-上传头像

package com.jq.vod.service;

import org.springframework.web.multipart.MultipartFile;

public interface FileService {
    //文件上传
    String upload(MultipartFile file);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

1.7.5ServiceIml实现层上传文件到腾讯云

package com.jq.vod.service.impl;

import com.jq.vod.service.FileService;
import com.jq.vod.utils.ConstantPropertiesUtil;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.model.UploadResult;
import com.qcloud.cos.region.Region;
import com.qcloud.cos.transfer.Upload;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.UUID;

@Service
public class FileServiceImpl implements FileService {
    @Override
    public String upload(MultipartFile file) {
        // 1 初始化用户身份信息(secretId, secretKey)。
        // SECRETID和SECRETKEY请登录访问管理控制台 https://console.cloud.tencent.com/cam/capi 进行查看和管理
        String secretId = ConstantPropertiesUtil.ACCESS_KEY_ID;
        String secretKey = ConstantPropertiesUtil.ACCESS_KEY_SECRET;
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        // 2 设置 bucket 的地域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
        // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
        Region region = new Region(ConstantPropertiesUtil.END_POINT);
        ClientConfig clientConfig = new ClientConfig(region);
        // 这里建议设置使用 https 协议
        // 从 5.6.54 版本开始,默认使用了 https
        clientConfig.setHttpProtocol(HttpProtocol.https);
        // 3 生成 cos 客户端。
        COSClient cosClient = new COSClient(cred, clientConfig);


        // 存储桶的命名格式为 BucketName-APPID,此处填写的存储桶名称必须为此格式
        String bucketName = ConstantPropertiesUtil.BUCKET_NAME;
        // 对象键(Key)是对象在存储桶中的唯一标识。

        //在文件名称的前面,添加uuid值保证,上传的文件名称不一样
        String key = UUID.randomUUID().toString().replaceAll("-","")
                +file.getOriginalFilename();

        //对上传文件分组,根据当前日期
        String dateTime = new DateTime().toString("yyyy/MM/dd");
        key=dateTime+"/"+key;

        try {
            //获取上传文件的输入流
            InputStream inputStream = file.getInputStream();
            ObjectMetadata objectMetadata = new ObjectMetadata();
            PutObjectRequest putObjectRequest = new PutObjectRequest(
                    bucketName,
                    key,
                    inputStream,
                    objectMetadata);

            // 高级接口会返回一个异步结果Upload

            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);

            //返回上传文件路径
            //https://ggkt-1313198864.cos.ap-beijing.myqcloud.com/image/ggkt/HELP.md
            String url="https://"+bucketName+"."+"cos"+"."+ConstantPropertiesUtil.END_POINT+".myqcloud.com"+"/image/ggkt/"+key;
            return url;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83

1.8讲师头像上传-前端代码开发

1.8.1form.vue 添加组件

<!-- 讲师头像 -->
<el-form-item label="讲师头像">
  <el-upload
    :show-file-list="false"
    :on-success="handleAvatarSuccess"
    :before-upload="beforeAvatarUpload"
    :on-error="handleAvatarError"
    :action="BASE_API+'/admin/vod/file/upload?module=avatar'"
    class="avatar-uploader">
    <img v-if="teacher.avatar" :src="teacher.avatar">
    <i v-else class="el-icon-plus avatar-uploader-icon"/>
  </el-upload>
</el-form-item>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

1.8.2三个方法

// 上传成功回调
handleAvatarSuccess(res, file) {
  // console.log(res)
  if (res.code==200) {
    // console.log(res)
    this.teacher.avatar = res.data
    // 强制重新渲染
    this.$forceUpdate()
  } else {
    this.$message.error('上传失败 (非0)')
  }
},

// 错误处理
handleAvatarError() {
  console.log('error')
  this.$message.error('上传失败(http失败)')
},

// 上传校验
beforeAvatarUpload(file) {
  const isJPG = file.type === 'image/jpeg'
  const isLt2M = file.size / 1024 / 1024 < 2

  if (!isJPG) {
    this.$message.error('上传头像图片只能是 JPG 格式!')
  }
  if (!isLt2M) {
    this.$message.error('上传头像图片大小不能超过 2MB!')
  }
  return isJPG && isLt2M
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

2.课堂分类管理

请添加图片描述

  • parentID :0 表示顶层
  • 下一层parentID与上一层id相等

2.1课程列表分类

在这里插入图片描述
基于element-ui组件来进行

2.1.0前端

  1. router.index文件
  //课程分类列表
  {
    path: '/subject',
    component: Layout,
    redirect: '/subject/list',
    name: '课程分类管理',
    alwaysShow: true,
    meta: { title: '课程分类管理', icon: 'example' },
    children: [
      {
        path: 'list',
        name: '课程分类列表',
        component: () => import('@/views/vod/subject/list'),
        meta: { title: '课程分类列表', icon: 'table' }
      }
    ]
  },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  1. 页面文件 views subject/list.vue
<template>
    <div  class="app-container">
    <el-table
        :data="list"
        style="width: 100%"
        row-key="id"
        border
        lazy
        :load="load"
        :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
        <el-table-column
        prop="title"
        label="名称"
        width="150">
        </el-table-column>
        <el-table-column
        prop="createTime"
        label="创建时间">
        </el-table-column>
    </el-table>
    </div>
</template>

<script>
import subjectApi from '@/api/vod/subject'
export default {
    data() {
        return {
            list:[] //数据字典列表数组
        }
    },
    created() {
        this.getSubList(0)
    },
    methods: {
        //数据字典列表
        getSubList(id) {
            subjectApi.getChildList(id)
                .then(response => {
                    this.list = response.data
                })
        },
        load(tree, treeNode, resolve) {
            subjectApi.getChildList(tree.id).then(response => {
                resolve(response.data)
            })
      }
    }
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  1. api 下 subject.js文件
    与后端接口的路径相对应
    import request from '@/utils/request'
    
    const api_name = '/admin/vod/subject'
    
    export default {
        //课程分类的列表接口
      getChildList(id) {
        return request({
          url: `${api_name}/getChildSubject/${id}`,
          method: 'get'
        })
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

2.1.1controller层

课程分类采用树形展示,使用“树形数据与懒加载”的方式展现数据列表,,页面搜索:树形数据与懒加载

package com.jq.vod.controller;


import com.jq.model.vod.Subject;
import com.jq.result.Result;
import com.jq.vod.service.SubjectService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * <p>
 * 课程科目 前端控制器
 * </p>
 *
 * @author CJQ
 * @since 2022-08-05
 */
@Api(tags = "课程分类管理接口")
@RestController
@RequestMapping("/admin/vod/subject")
@CrossOrigin

public class SubjectController {

    @Autowired
    public SubjectService subjectService;

    //课程分类列表
    //懒加载,每次只查询的事一层数据
    @ApiOperation("课程分类列表")
    @GetMapping("getChildSubject/{id}")
    public Result getChildSubject(@PathVariable Long id){
        List<Subject> list= subjectService.selectSubjectList(id);
        return Result.ok(list);


    }

}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

2.1.2mapper层

package com.jq.vod.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jq.model.vod.Subject;

/**
 * <p>
 * 课程科目 Mapper 接口
 * </p>
 *
 * @author CJQ
 * @since 2022-08-05
 */
public interface SubjectMapper extends BaseMapper<Subject> {

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2.1.3service层

package com.jq.vod.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.jq.model.vod.Subject;

import java.util.List;

/**
 * <p>
 * 课程科目 服务类
 * </p>
 *
 * @author CJQ
 * @since 2022-08-05
 */
public interface SubjectService extends IService<Subject> {
    //课程分类列表
    //懒加载,每次只查询的事一层数据
    List<Subject> selectSubjectList(Long id);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

2.1.4serviceImpl层

package com.jq.vod.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jq.model.vod.Subject;
import com.jq.vod.mapper.SubjectMapper;
import com.jq.vod.service.SubjectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 课程科目 服务实现类
 * </p>
 *
 * @author CJQ
 * @since 2022-08-05
 */
@Service
public class SubjectServiceImpl extends ServiceImpl<SubjectMapper, Subject> implements SubjectService {
    //课程分类列表
    //懒加载,每次只查询的事一层数据
    @Override
    public List<Subject> selectSubjectList(Long id) {
        //SELECT * FROM SUBJECT WHERE parent_id=0
        QueryWrapper<Subject>wrapper =new QueryWrapper<>();
        wrapper.eq("parent_id",id);
        List<Subject> subjectList = baseMapper.selectList(wrapper);
        //subjectList遍历,得到每个subject对象,判断是否有下一层数据,有hasChildren =true
        for (Subject subject:subjectList) {
            //获取subject的id值
            Long subjectId = subject.getId();
            //查询
            boolean isChild=this.isChilden(subjectId);
            //封装到对象中
            subject.setHasChildren(isChild);
        }

        return subjectList;
    }
    //判断是否有下一层的数据
    private boolean isChilden(Long subjectId){
        QueryWrapper<Subject> wrapper=new QueryWrapper<>();
        wrapper.eq("parent_id",subjectId);
        Integer count = baseMapper.selectCount(wrapper);
        return count>0;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

2.3课程分类导出

导出是从前端页面查询的数据,导出到Excel中
在这里插入图片描述

2.3.0前端

list.vue添加导出按钮组件

<div class="el-toolbar">
    <div class="el-toolbar-body" style="justify-content: flex-start;">
      <el-button type="text" @click="exportData"><i class="fa fa-plus"/> 导出</el-button>
    </div>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5

添加方法

exportData() {
    window.open("http://localhost:8301/admin/vod/subject/exportData")
},
  • 1
  • 2
  • 3

2.3.1对应实体类

@Data
public class SubjectEeVo {

	@ExcelProperty(value = "id" ,index = 0)
	private Long id;

	@ExcelProperty(value = "课程分类名称" ,index = 1)
	private String title;

	@ExcelProperty(value = "上级id" ,index = 2)
	private Long parentId;

	@ExcelProperty(value = "排序" ,index = 3)
	private Integer sort;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

2.3.2controller层

    /**
     * 课程分类导出
     * @param response
     */
    @ApiOperation("课程分类导出")
    @GetMapping("exportData")
    public void exportData(HttpServletResponse response){
        subjectService.exportData(response);

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2.3.3service层

package com.jq.vod.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.jq.model.vod.Subject;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * <p>
 * 课程科目 服务类
 * </p>
 *
 * @author CJQ
 * @since 2022-08-05
 */
public interface SubjectService extends IService<Subject> {
    //课程分类列表
    //懒加载,每次只查询的事一层数据
    List<Subject> selectSubjectList(Long id);
    
    //课程分类导出
    void exportData(HttpServletResponse response);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

2.3.4serviceImpl层

    /**
     * 课程分类导出
     * @param response
     */
    @Override
    public void exportData(HttpServletResponse response) {
        try {
            // 设置下载信息
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("课程分类", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");

            //查询课程分类所有数据
            List<Subject> subjectList = baseMapper.selectList(null);
            
            //List<Subject> --->List<SubjectEeVo>
            List<SubjectEeVo> subjectEeVoList=new ArrayList<>();
            for (Subject subject:subjectList) {
                SubjectEeVo subjectEeVo =new SubjectEeVo();
                
//                subjectEeVo.setId(subject.getId());
//                subjectEeVo.setParentId(subject.getParentId());
                BeanUtils.copyProperties(subject,subjectEeVo);
                subjectEeVoList.add(subjectEeVo);
            }
            
            //EasyExcel写操作
            EasyExcel.write(response.getOutputStream(), SubjectEeVo.class)
                    .sheet("课程分类")
                    .doWrite(subjectEeVoList);
    
        }catch (Exception e){
            throw new GgktException(20001,"导出失败");
        }

    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

2.3.5导出结果

在这里插入图片描述

在这里插入图片描述

2.4课程分类导入

前端上传Excel表格,将数据导入到数据库中
在这里插入图片描述

2.4.0前端

  1. 导入按钮组件

    <el-button type="text" @click="importData"><i class="fa fa-plus"/> 导入</el-button>
    
    • 1

    对应方法

    importData() {
        this.dialogImportVisible = true
    },
    onUploadSuccess(response, file) {
        this.$message.info('上传成功')
        this.dialogImportVisible = false
        this.getSubList(0)
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  2. 导入文件,弹窗组件

    <el-dialog title="导入" :visible.sync="dialogImportVisible" width="480px">
        <el-form label-position="right" label-width="170px">
            <el-form-item label="文件">
                <el-upload
                           :multiple="false"
                           :on-success="onUploadSuccess"
                           :action="'http://localhost:8333/admin/vod/subject/importData'"
                           class="upload-demo">
                    <el-button size="small" type="primary">点击上传</el-button>
                    <div slot="tip" class="el-upload__tip">只能上传xls文件,且不超过500kb</div>
                </el-upload>
            </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
            <el-button @click="dialogImportVisible = false">取消</el-button>
        </div>
    </el-dialog>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    对用属性

    data() {
        return {
            dialogImportVisible: false,
            list:[] //数据字典列表数组
        }
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

2.4.1controller层

    /**
     * 课程分类导入
     * @param file
     */
    @ApiOperation("课程分类导入")
    @PostMapping("importData")
    public Result importData(MultipartFile file){
        subjectService.importData(file);
        return Result.ok(null);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2.4.2service层

package com.jq.vod.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.jq.model.vod.Subject;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * <p>
 * 课程科目 服务类
 * </p>
 *
 * @author CJQ
 * @since 2022-08-05
 */
public interface SubjectService extends IService<Subject> {
    //课程分类列表
    //懒加载,每次只查询的事一层数据
    List<Subject> selectSubjectList(Long id);

    //课程分类导出
    void exportData(HttpServletResponse response);
    
    //课程分类导入
    void importData(MultipartFile file);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

2.4.4EasyExcel监听器

package com.jq.vod.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.jq.model.vod.Subject;
import com.jq.vo.vod.SubjectEeVo;
import com.jq.vod.mapper.SubjectMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class SubjectListener extends AnalysisEventListener<SubjectEeVo> {

    @Autowired
    private SubjectMapper subjectMapper;
    
    
    /**
     * 一行一行的读取Excel的内容,把每行的内容封装到user对象
     * 从Excel第二行开始读取
     * @param subjectEeVo
     * @param analysisContext
     */

    @Override
    public void invoke(SubjectEeVo subjectEeVo, AnalysisContext analysisContext) {
        Subject subject=new Subject();
        //SubjectEeVo-->Subject
        BeanUtils.copyProperties(subjectEeVo,subject);
        //将数据添加到数据库
        subjectMapper.insert(subject);       
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

2.4.4serviceImpl层

 /**
     * 课程分类导入
     * @param file
     */
    @Override
    public void importData(MultipartFile file) {
        try {
            EasyExcel.read(file.getInputStream(),SubjectEeVo.class,subjectListener)
                    .sheet().doRead();
        } catch (IOException e) {
            throw new GgktException(20001,"导入失败");
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

2.4.5结果展示

在这里插入图片描述在这里插入图片描述在这里插入图片描述

3.EasyExcel

请添加图片描述

3.1EasyExcel介绍

EasyExcel是阿里巴巴开源的一个excel处理框架以使用简单、节省内存著称
EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析

3.2EasyExcel特点

请添加图片描述

  • Java领域解析、生成Excel比较有名的框架有Apache poi、jxl等。但他们都存在一个严重的问题就是非常的耗内存。如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或者JVM频繁的full gc。
  • EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理(AnalysisEventListener)
  • EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。

3.3EasyExcel写操作

3.3.1pom中引入xml相关依赖

<dependencies>
    <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>2.1.1</version>
    </dependency>
</dependencies>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

3.3.2创建实体类

设置表头和添加的数据字段

package com.jq.excel;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

@Data
public class User {
    @ExcelProperty(value = "用户编号")
    private  int id;
    @ExcelProperty(value = "用户名称")
    private String name;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

3.3.3实现写操作

创建方法循环设置要添加到Excel的数据

package com.jq.excel;

import com.alibaba.excel.EasyExcel;

import java.util.ArrayList;
import java.util.List;

public class TestWrite {
    public static void main(String[] args) {
        //设置文件名称和路径
        String fileName="F:\\JavaCode\\agwtest.xlsx";
        //调用方法
        EasyExcel.write(fileName,User.class)
                .sheet("写操作")
                .doWrite(data());
    }
    //循环设置要添加的数据,最终封装到list集合中
    private static List<User> data() {
        List<User> list = new ArrayList<User>();
        for (int i = 0; i < 10; i++) {
            User data = new User();
            data.setId(i);
            data.setName("lucy"+i);
            list.add(data);
        }
        return list;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

在这里插入图片描述在这里插入图片描述

3.4EasyExcel读操作

3.4.1创建实体类

package com.jq.excel;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

@Data
public class User {
    @ExcelProperty(value = "用户编号",index = 0)
    private  int id;
    @ExcelProperty(value = "用户名称",index = 1)
    private String name;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

3.4.2创建读取操作的监听器

创建监听器,一行一行的读取

package com.jq.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;

import java.util.Map;

public class ExcelListener extends AnalysisEventListener<User> {
    /**
     * 一行一行的读取Excel的内容,把每行的内容封装到user对象
     * 从Excel第二行开始读取
     * @param user
     * @param analysisContext
     */
    @Override
    public void invoke(User user, AnalysisContext analysisContext) {
        System.out.println(user);
    }

    /**
     * 读取表头内容
     * @param headMap
     * @param context
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        System.out.println("表头"+headMap);
    }
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

3.4.3调用实现最终的读取

package com.jq.excel;

import com.alibaba.excel.EasyExcel;

public class TestRead {
    public static void main(String[] args) {
        //设置文件名称和路径
        String fileName="F:\\JavaCode\\agwtest.xlsx";
        //调用方法
        EasyExcel.read(fileName,User.class,new ExcelListener()).sheet().doRead();
        
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号