ホームページ  >  記事  >  Java  >  SpringBoot が EasyExcel アプリケーションを統合する方法

SpringBoot が EasyExcel アプリケーションを統合する方法

WBOY
WBOY転載
2023-05-14 21:37:04810ブラウズ

1. はじめに

機能:

1. Java ドメイン分析や Excel 生成は、Apache poi、jxl などのより有名なフレームワークです。しかし、それらはすべて、大量のメモリを消費するという深刻な問題を抱えています。システムの同時実行数が大きくない場合は問題ないかもしれませんが、同時実行数が増加すると、確実に OOM または JVM のフル gc が頻繁に発生します。
2. EasyExcel は Alibaba のオープンソース Excel 処理フレームワークで、使いやすさとメモリの節約で有名です。 EasyExcel がメモリ使用量を大幅に削減できる主な理由は、Excel を解析するときにファイル データが一度にメモリに読み込まれるのではなく、データがディスクから 1 行ずつ読み込まれ、1 つずつ解析されるためです。
3. EasyExcel は行単位の解析モードを採用しており、オブザーバーモードで一行の解析結果を処理(AnalysisEventListener)に通知します。

2. アプリケーション シナリオ

1. データ インポート: 入力作業負荷の軽減
2. データ エクスポート: 統計情報のアーカイブ
3. データ送信:異種システム間のデータ送信

3. 達成される効果

sql

CREATE TABLE `edu_subject` (
  `id` char(19) NOT NULL COMMENT "课程类别ID",
  `title` varchar(10) NOT NULL COMMENT "类别名称",
  `parent_id` char(19) NOT NULL DEFAULT "0" COMMENT "父ID",
  `sort` int unsigned NOT NULL DEFAULT "0" COMMENT "排序字段",
  `gmt_create` datetime NOT NULL COMMENT "创建时间",
  `gmt_modified` datetime NOT NULL COMMENT "更新时间",
  PRIMARY KEY (`id`),
  KEY `idx_parent_id` (`parent_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=COMPACT COMMENT="课程科目";

SpringBoot が EasyExcel アプリケーションを統合する方法

変換先->

SpringBoot が EasyExcel アプリケーションを統合する方法

3.

3.1、pom 依存関係インポートを使用します

注意: 次のバージョンは置き換えることができず、次の場合は機能しない可能性があります。あなたがそれらを変更します

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.1.1</version>
        </dependency>
		<!--xls-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
		
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>

3.2、コントローラー

package com.zhz.serviceedu.controller;

import com.zhz.common.utils.R;
import com.zhz.serviceedu.service.EduSubjectService;
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;

/**
 * <p>
 * 课程科目 前端控制器
 * </p>
 *
 * @author zhz
 * @since 2021-07-03
 */
@RestController
@RequestMapping("/eduservice/subject")
@CrossOrigin
@Api(tags = "课程科目")
public class EduSubjectController {

    @Autowired
    private EduSubjectService eduSubjectService;

    /**
     * 添加课程分类,获取上传过来的文件,把文件内容读取出来
     */
    @PostMapping("/addSubject")
    @ApiOperation(value = "添加课程分类,获取上传过来的文件,把文件内容读取出来")
    public R addSubject(MultipartFile file){
        //上传过来的excel文件
        eduSubjectService.saveSubject(file,eduSubjectService);
        return R.ok();
    }
}

3.3、インターフェイス

package com.zhz.serviceedu.service;

import com.zhz.serviceedu.entity.EduSubject;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.multipart.MultipartFile;

/**
 * <p>
 * 课程科目 服务类
 * </p>
 *
 * @author zhz
 * @since 2021-07-03
 */
public interface EduSubjectService extends IService<EduSubject> {

    /**
     * 添加课程信息
     *
     * @author zhz
     * @date 2021/07/02 02:18
     * @param file 文件对象,用于获取excel文件
     * @param eduSubjectService 方便监听器部分引用
     */
    void saveSubject(MultipartFile file, EduSubjectService eduSubjectService);
}

3.4、impl

package com.zhz.serviceedu.service.impl;

import com.alibaba.excel.EasyExcel;
import com.zhz.serviceedu.entity.EduSubject;
import com.zhz.serviceedu.entity.excel.SubjectData;
import com.zhz.serviceedu.listener.SubjectExcelListener;
import com.zhz.serviceedu.mapper.EduSubjectMapper;
import com.zhz.serviceedu.service.EduSubjectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;

/**
 * <p>
 * 课程科目 服务实现类
 * </p>
 *
 * @author zhz
 * @since 2021-07-03
 */
@Service
public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements EduSubjectService {

    /**
     * 添加课程信息
     *
     * @param file 文件对象,用于获取excel文件
     * @param eduSubjectService
     * @author zhz
     * @date 2021/07/02 02:18
     */
    @Override
    public void saveSubject(MultipartFile file, EduSubjectService eduSubjectService) {
        try {
            //文件输入流
            InputStream in = file.getInputStream();
            //调用方法进行读取
            EasyExcel.read(in, SubjectData.class,new SubjectExcelListener(eduSubjectService)).sheet().doRead();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

3.5、リスナー

package com.zhz.serviceedu.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhz.servicebase.execptionhandler.GuliException;
import com.zhz.serviceedu.entity.EduSubject;
import com.zhz.serviceedu.entity.excel.SubjectData;
import com.zhz.serviceedu.service.EduSubjectService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

/**
 * @author zhouhengzhe
 * @Description: excel监听器
 * @date 2021/7/3上午2:28
 */
@Slf4j
public class SubjectExcelListener extends AnalysisEventListener<SubjectData> {

    /**
     * 创建有参数构造,传递subjectService用于操作数据库
     * 因为SubjectExcelListener不能交给spring去管理,所以需要自己new,不能注入对象
     * 此处一定要是public,不然永远获取不到对象
     */
    public EduSubjectService eduSubjectService;
    public SubjectExcelListener() {
    }
    public SubjectExcelListener(EduSubjectService eduSubjectService) {
        this.eduSubjectService = eduSubjectService;
    }

    /**
     * 读取excel内容,一行一行进行读取,此处全是业务处理
     * @param subjectData
     * @param analysisContext
     */
    @Override
    public void invoke(SubjectData subjectData, AnalysisContext analysisContext) {
        log.info("进入方法调用");
        if (StringUtils.isEmpty(subjectData)){
            throw new GuliException(20001,"文件数据为空");
        }
        //一行一行去读取excel内容,每次读取有两个值,第一个值为一级分类,第二个值为二级分类
        //判断一级分类是否重复
        EduSubject existOneSubject = this.existOneSubject(eduSubjectService, subjectData.getOneSubjectName());
        if (StringUtils.isEmpty(existOneSubject)){
            existOneSubject=new EduSubject();
            existOneSubject.setParentId("0");
            //一级分类名称
            existOneSubject.setTitle(subjectData.getOneSubjectName());
            eduSubjectService.save(existOneSubject);
        }
        //获取一级分类的pid值
        String pid=existOneSubject.getId();
        //添加二级分类
        // 判断二级分类是否重复
        EduSubject existTwoSubject = this.existTwoSubject(eduSubjectService, subjectData.getTwoSubjectName(), pid);
        if (StringUtils.isEmpty(existTwoSubject)){
            existTwoSubject=new EduSubject();
            existTwoSubject.setParentId(pid);
            //二级分类名称
            existTwoSubject.setTitle(subjectData.getTwoSubjectName());
            eduSubjectService.save(existTwoSubject);
        }

    }

    /**
     * 读取完成后执行
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }

    /**
     * 判断一级分类是否重复
     * 因为课程的的parent_id为0时,代表是一级分类,并且一级分类数据不重复
     * @param eduSubjectService
     * @param name
     * @return
     */
    private EduSubject existOneSubject(EduSubjectService eduSubjectService,String name){
        QueryWrapper<EduSubject> wrapper=new QueryWrapper<>();
        wrapper.eq("title",name);
        wrapper.eq("parent_id","0");
        EduSubject subject = eduSubjectService.getOne(wrapper);
        return subject;
    }
    /**
     * 判断二级分类是否重复
     *
     * @param eduSubjectService
     * @param name
     * @param pid
     * @return
     */
    private EduSubject existTwoSubject(EduSubjectService eduSubjectService,String name,String pid){
        QueryWrapper<EduSubject> wrapper=new QueryWrapper<>();
        wrapper.eq("title",name);
        wrapper.eq("parent_id",pid);
        EduSubject eduSubject = eduSubjectService.getOne(wrapper);
        return eduSubject;
    }
}

3.6、細かい詳細、​​エンティティ クラス pojo

mybatisplus によって生成されたエンティティ クラスの主キー生成戦略は IdType.ID_WORKER であるため、IdType.ID_WORKER_STR に変更する必要があります。そうしないと変換の問題が発生します

rreee

以上がSpringBoot が EasyExcel アプリケーションを統合する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。