【Spring Boot 28】Spring Boot整合easyExcel

x33g5p2x  于2021-11-09 转载在 Spring  
字(6.0k)|赞(0)|评价(0)|浏览(503)

一、什么是easyExcel

EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。

二、读取Excel插入数据

1、controller

@Autowired
private StudentService service;

@Description(desc = "easyExcel批量导入")
@RequestMapping(value = "/importByEasyExcel", method = RequestMethod.POST)
@ResponseBody
public String importByEasyExcel(@RequestPart(value = "file") MultipartFile file,
								  @RequestParam(value = "id") String id) {
	// easyExcel批量导入
	service.importByEasyExcel(file, service);
	return "导入成功";
}

2、service

// 批量导入
void importToExcel(MultipartFile file, StudentService service) throws Exception;

3、serviceImpl

/**
 * 批量导入
 */
@Override
public void importToExcel(MultipartFile file, StudentService service) throws Exception {
	InputStream in = file.getInputStream();
	EasyExcel.read(in, Student.class, new EasyExcelListener(service)).sheet().doRead();
}

4、EasyExcelListener 

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

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

/**
 * 批量导入监听器 easyExcel
 */
public class EasyExcelListener extends AnalysisEventListener<Student> {

    public static List<Student> list = new ArrayList<Student>();

    public StudentService studentService ;
    public EasyExcelListener(StudentService studentService) {
        this.studentService = studentService;
    }

    /**
     * 逐行处理
     */
    @Override
    public void invoke(Student student, AnalysisContext analysisContext) {
        list.add(student);
    }

    /**
     * 读取表头内容
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
    }

    /**
     * 批量入库
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        studentService.insertBatchStudent();
    }
}

5、mapper

@Override
public void insertBatchStudent() {
	mapper.insertBatchStudent(EasyExcelListener.list);
}
@Description(desc = "easyExcel 批量导入")
void insertBatchStudent(List<Student> list);

6、mapper.xml 

<!-- 通过easyExcel批量导入 -->
<insert id="insertBatchStudent" parameterType="list">
	begin
	<foreach collection="list" item="item" index="index" separator=";" >
		insert into STUDENT
		<trim prefix="(" suffix=")" suffixOverrides="," >
			id,
			name,
			nick_name
		</trim>
		values   (
		#{item.id,jdbcType=CHAR},
		#{item.name,jdbcType=VARCHAR},
		#{item.nick_name,jdbcType=VARCHAR}
		)
	</foreach>
	;end;
</insert>

7、实体类Student

import com.alibaba.excel.annotation.ExcelProperty;

public class Student {

    @ExcelProperty(value = {"编号"}, index = 0)
    private String id;

    @ExcelProperty(value = {"姓名"}, index = 1)
    private String name;

    @ExcelProperty(value = {"称号"}, index = 2)
    private String nick_name;
}

8、前端vue关键代码

request({
	url: '/nezha/importByEasyExcel',
	method: 'post',
	data: form
	}).then(response => {
	if (response.data === 'success') {
	  this.$message.success('excel导入成功!')
	} else {
	  this.$message.error(response.data)
	}
})

9、Excel

10、插入后效果

三、分批读取Excel

分批读取Excel是easyExcel最重要的功能,easyExcel未出现之前,读取Excel都是使用Apache 的POI,poi会将Excel的内容全部读取到内存中,如果数据量过大,很容易造成数据溢出的问题。

而easyExcel是逐行读取 Excel,可以设置一个理想的阈值,分批次读取,并插入数据库,间接的也缓解了数据库的压力。

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

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

/**
 * 批量导入监听器 easyExcel
 */
public class EasyExcelListener extends AnalysisEventListener<Student> {

	private static final Logger logger = LoggerFactory.getLogger(EasyExcelListener.class);

	/**
	 * 批处理阈值
	 */
	private static final int BATCH_COUNT = 1000;

    public static List<Student> list = new ArrayList<Student>(BATCH_COUNT);

    public StudentService studentService ;
    public EasyExcelListener(StudentService studentService) {
        this.studentService = studentService;
    }

    /**
     * 逐行处理
     */
    @Override
    public void invoke(Student student, AnalysisContext analysisContext) {
        list.add(student);
		if (list.size() >= BATCH_COUNT) {
			// 批量入库
			saveData();
			list.clear();
		}
    }

    /**
     * 读取表头内容
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
    }

    /**
     * 所有数据解析完成了 都会来调用
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
		// 批量入库
        saveData();
    }
	
	/**
	* 批量入库
	*/
	private void saveData() {
        logger.info("{}条数据,开始存储数据库!", list.size());
        studentService.insertBatchStudent();
        logger.info("存储数据库成功!");
    }
}

四、写入Excel

@Test
public void simpleWrite() {
    // 写法1
    String fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";
    // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
    // 如果这里想使用03 则 传入excelType参数即可
    EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());

    // 写法2
    fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";
    // 这里 需要指定写用哪个class去写
    ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build();
    WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
    excelWriter.write(data(), writeSheet);
    // 千万别忘记finish 会帮忙关闭流
    excelWriter.finish();
}

五、模板下载

1、controller

@Description(desc = "模板下载")
@RequestMapping(value = "/download_template", method = RequestMethod.POST)
@ResponseBody
public void downloadTempalate(HttpServletResponse response) throws IOException {
	ExcelUtil.downloadTempalate(response, EasyTemplate);
}

2、工具类

public static void downloadTempalate(HttpServletResponse response, String filepath) throws IOException {

	File path = new File(ResourceUtils.getURL("classpath:").getPath());

	InputStream input = null;
	OutputStream output = null;
	BufferedInputStream bis = null;
	BufferedOutputStream bos = null;

	input = new BufferedInputStream(new FileInputStream(path + filepath));

	// 得到文件大小
	int i = input.available();

	// 开辟内存空间,用来存放读取内容
	byte data[] = new byte[1024];

	// 下载处理
	bis = new BufferedInputStream(input);
	int bytes = 0;
	output = response.getOutputStream();
	bos = new BufferedOutputStream(output);
	while ((bytes = bis.read(data, 0, data.length)) != -1) {
		bos.write(data, 0, bytes);
	}
	bos.flush();
}

六、粉丝福利

1、Vue.js 3.0从入门到实战

2、SQL从入门到精通

3、手把手教你学Linux

4、Oracle数据库管理从入门到精通

本次活动送书规则:

1、社区积分榜前5名,随机抽取一名幸运者

2、社区积分榜6-15名,随机抽取一名幸运者

3、社区积分榜16-30名,随机抽取一名幸运者

【赚取积分方式】哪吒社区内发帖、点赞、评论都可赢取积分!
🍅 粉丝福利,限时抢购  领取九折优惠券

🍅 粉丝福利,限时抢购 《Java基础教程系列》限时九折

🍅 粉丝福利,限时抢购  《Spring Boot基础教程》限时九折

🍅 社区入口:双11劲爆来袭,哪吒微信群,图书共读活动火热进行中

上一篇:【Spring Boot 27】RabbitMQ基础知识总结

下一篇:SpringBoot学习路线总结,跟着路线走,不迷路(附思维导图)

添加微信,备注1024,赠送Java学习路线思维导图 

相关文章