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


    1.整合腾讯云存储

    1.1进入腾讯云

    在这里插入图片描述

    1.2创建Bucket

     	 	在这里插入图片描述

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

    在这里插入图片描述

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

    1.6腾讯云文档代码编写

    1.6.1 引入依赖

    >
           >com.qcloud>
           >cos_api>
           >5.6.89>
    >
    
    • 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;
    
    /**
     * 

    * 课程科目 前端控制器 *

    * * @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;
    
    /**
     * 

    * 课程科目 Mapper 接口 *

    * * @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;
    
    /**
     * 

    * 课程科目 服务类 *

    * * @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;
    
    /**
     * 

    * 课程科目 服务实现类 *

    * * @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;
    
    /**
     * 

    * 课程科目 服务类 *

    * * @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 --->List
                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;
    
    /**
     * 

    * 课程科目 服务类 *

    * * @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>
        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>easyexcelartifactId>
            <version>2.1.1version>
        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
  • 相关阅读:
    大数据之Hive(三)
    Golang gorm 一对一关系
    猜谜游戏、彩云词典爬虫、SOCKS5代理的 Go(Golang) 小实践,附带全代码解释
    Microsoft SQL Server manual
    DataX更新null值到ElasticSearch不生效的问题
    FineBI 新增字段后 更新缓慢问题
    Android 12(S) 图像显示系统 - 解读Gralloc架构及GraphicBuffer创建/传递/释放(十四)
    Linux进阶-Shell编程
    zookeeper源码(04)leader选举流程
    win下使用vscode+wsl2
  • 原文地址:https://blog.csdn.net/qq_45498432/article/details/126153116