EsayExcel文件导入导出

目录

准备工作

监听器类

导入测试

导出测试

上传Excel

下载Excel

混合导出+模板导出


headRowNumber(1):从第几行开始读

准备工作

导入依赖

<!--easyexcel-->
<dependency>
    <groupId>com.alibaba</groupId>x
    <artifactId>easyexcel</artifactId>
    <version>2.2.6</version>
</dependency>
<!--文件上传-->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

创建实体类

@HeadRowHeight():设置导出的Excle表格标题的行高

@ExcelProperty():对当前列的操作

value:设置列的名字

value = {"value1","value2"}:一级标题,二级标题

index = 2:这个字段放在第几列,默认从0开始

@ExcelIgnore:不导入导出这个字段

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
@HeadRowHeight(30)  // 标题行高
public class User {

    /**
     * @ExcelProperty
     *      value:列名称
     *      index:写:写内容到第几列,读:第几列的内容放到这个字段
     *      {}:给头在加一个头,所有都加,就会合并
     *
     * @ExcelIgnore
     *      导入或导出时候,不要这个字段
     *
     */
    @TableId(value = "id", type = IdType.AUTO)
    @ExcelProperty(value = {"用户信息表","ID"},index = 5)
    @ExcelIgnore
    private Integer id;

    @ExcelProperty(value = {"用户信息表","姓名"},index = 1)
    @ColumnWidth(20)
    private String name;

    @ExcelProperty(value = {"用户信息表","年龄"},index = 2)
    private Integer age;

    @ExcelProperty(value = {"用户信息表","性别"},index = 3)
    private Integer sex;

    @ExcelProperty(value = {"用户信息表","日期"},index = 4)
    @ColumnWidth(20)
    private Date dateTime;


}

第二个实体类

package com.zsh.esayexcel.domain.po;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserVO {
    private Integer sum;

    private Integer avg;
}

Mapper

package com.zsh.esayexcel.mapper;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author KaiLangJiaoJiao
 * @since 2024-02-12
 */
@Mapper
public interface UserMapper extends BaseMapper<User> {

}

Service

package com.zsh.esayexcel.service;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author KaiLangJiaoJiao
 * @since 2024-02-12
 */
public interface IUserService extends IService<User> {

}

ServiceImpl

package com.zsh.esayexcel.service.impl;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author KaiLangJiaoJiao
 * @since 2024-02-12
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

}

Controller

package com.zsh.esayexcel.controller;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author KaiLangJiaoJiao
 * @since 2024-02-12
 */
@RestController
@RequestMapping("/user")
public class UserController {


}

监听器类

创建listener包

UserListener

package com.zsh.esayexcel.listener;

/**
 * 读取文档的监听器类
 */
public class UserListener extends AnalysisEventListener<User> {

    /**
     * 读监听器,每读一行内容,都会调用一次该对象的invoke,在invoke可以操作使用读取到的数据
     * @param user
     * @param analysisContext
     */
    @Override
    public void invoke(User user, AnalysisContext analysisContext) {
        System.out.println("user = " + user);
    }

    /**
     * 读取完整个文档之后调用的方法
     * @param analysisContext
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }
}

WebUserListener

package com.zsh.esayexcel.listener;

@Scope("prototype") // 官方要求,这个类需要是多例对象,不能是单例
public class WebUserListener extends AnalysisEventListener<User> {

//    @Autowired
//    private IUserService userService;

    List<User> userList = new ArrayList<>();

    @Override
    public void invoke(User user, AnalysisContext analysisContext) {
        userList.add(user);
        // 判断条数为5时添加一次
        if (userList.size() % 5 == 0) {
            IUserService userService = new UserServiceImpl();
            // 添加
            userService.saveBatch(userList);
            // 添加完清空数组
            userList.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 剩下数据不足5条时添加
        if (userList.size() != 0) {
            IUserService userService = new UserServiceImpl();
            // 添加
            userService.saveBatch(userList);
            // 添加完清空数组
            userList.clear();
        }
    }
}

导入测试

这是一个Test测试类

package com.zsh.esayexcel;

@SpringBootTest
public class ExcelTest {

    /**
     * 读excel
     */
    @Test
    public void test(){
        /**
         * pathName:要读取的文件路径
         *
         * head:文件中每一行数据要存储到的实体类行的class
         *
         * readListener:读监听器,每读一行内容,都会调用一次该对象的invoke,在invoke可以操作使用读取到的数据
         */
        // 获得一个工作簿对象
        ExcelReaderBuilder readWorkBook = EasyExcel.read("C:\\Users\\开朗觉觉\\Desktop\\用户表.xlsx", User.class, new UserListener());

        // 获得工作簿对象
        ExcelReaderSheetBuilder sheet = readWorkBook.sheet();

        /**
         * headRowNumber()
         * 从第几行开始读,默认是1
         */
        // 读取工作表中内容
        sheet.headRowNumber(1).doRead();

    }

    
}

导出测试

这是一个测试类

package com.zsh.esayexcel;

@SpringBootTest
public class ExcelTest {

    /**
     * 写excel
     */
    @Test
    public void test2(){
        // 工作簿对象
        // .xml会直接放到Module里
        ExcelWriterBuilder writeWorkBook = EasyExcel.write("学生表的写操作.xlsx", User.class);	

        // 工作表对象
        ExcelWriterSheetBuilder sheet = writeWorkBook.sheet();

        // 准备数据
        List<User> userList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            User user = new User(i,"张三"+i,10,2,new Date());
            userList.add(user);
        }
        // 写
        sheet.doWrite(userList);

    }


}

上传Excel

package com.zsh.esayexcel.controller;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author KaiLangJiaoJiao
 * @since 2024-02-12
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserService userService;

    /**
     * 测试
     * @return
     */
    @GetMapping("/test")
    private String test(){
        return "ok";
    }

    /**
     * Excel导入
     * @param uploadExcel
     * @return
     */
    @PostMapping("/read")
    public String readExcel(@RequestBody MultipartFile uploadExcel){
        try {
            // 工作簿
            ExcelReaderBuilder readWorkBook = EasyExcel.read(uploadExcel.getInputStream(), User.class, new WebUserListener());

            // 工作表
            ExcelReaderSheetBuilder sheet = readWorkBook.sheet();

            // 读
            sheet.doRead();

            return "success";
        } catch (IOException e) {
            e.printStackTrace();
            return "fail";
        }

    }
    

}

下载Excel

package com.zsh.esayexcel.controller;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author KaiLangJiaoJiao
 * @since 2024-02-12
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserService userService;

    /**
     * Excel导出
     * @param response
     */
    @GetMapping("/write")
    @ResponseBody
    public void writeExcel(HttpServletResponse response) throws IOException {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 防止中文乱码
        String fileName = URLEncoder.encode("学生表测试", "UTF-8");
        response.setHeader("Content-Disposition","attachment; filename*=UTF-8''" + fileName + ".xlsx");

        // 收集要写的数据装进一个工作簿中
        ServletOutputStream outputStream = response.getOutputStream();

        // 获取工作簿
        ExcelWriterBuilder writeWrokBook = EasyExcel.write(outputStream, User.class);

        // 获取工作表
        ExcelWriterSheetBuilder sheet = writeWrokBook.sheet();

        // 获取数据
        List<User> userList = userService.list(null);

        // 写
        sheet.doWrite(userList);
    }

}

混合导出+模板导出

模板设计

{.xxxx}:填充多行

{xxxx}:填充单行

代码开发

package com.zsh.esayexcel;

@SpringBootTest
public class ExcelTest {

    @Autowired
    private IUserService userService;

    /**
     * 混合导出
     */
    @Test
    public void test3(){
        // 准备模板
        String tempalte = "用户表模板.xlsx";

        /**
         * withTemplate()
         *      使用模板创建表
         */
        // 创建一个工作簿对象
        ExcelWriter workBook = EasyExcel.write("用户信息表.xlsx", User.class).withTemplate(tempalte).build();

        // 创建工作表对象
        WriteSheet sheet = EasyExcel.writerSheet().build();

        // 准备数据
//        IUserService userService = new UserServiceImpl();
        List<User> userList = userService.list(null);
        UserVO userVO = new UserVO();
        // 总人数
        userVO.setSum(userList.size());
        // 年龄总和
        Integer agesum = userList.stream()
                .map(user -> user.getAge())
                .reduce(0, (result, element) -> result + element);
        // 平均年龄
        userVO.setAvg(agesum / userList.size());

        // 数据填充
        FillConfig fillConfig = FillConfig.builder().forceNewRow(true).build();// 因为多组填充的数据不确定,需要在多组数据填充完之后另起一行

        // 多组填充
        workBook.fill(userList,fillConfig,sheet);

        // 单组填充
        workBook.fill(userVO,sheet);

        // 关闭流
        workBook.finish();

    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/387369.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JVM(4)原理篇

1 栈上的数据存储 在Java中有8大基本数据类型&#xff1a; 这里的内存占用&#xff0c;指的是堆上或者数组中内存分配的空间大小&#xff0c;栈上的实现更加复杂。 以基础篇的这段代码为例&#xff1a; Java中的8大数据类型在虚拟机中的实现&#xff1a; boolean、byte、char…

蓝桥杯电子类单片机提升一——超声波测距

前言 单片机资源数据包_2023 一、超声波测距原理 二、超声波测距的应用 1.超声波的发射 2.单片机知识补充&#xff1a;定时器 3.超声波的接收与计时 4.距离的计算 1&#xff09;定时器1为16位自动重载&#xff0b;1T11.0592MHz 2&#xff09;定时器1为16位自动重载&am…

拓扑排序入门

文章目录 写在前面一些概念算法步骤字典序最大/最小的拓扑序列&#xff1f;模板例题3704. 排队家谱树奖金P1983 [NOIP2013 普及组] 车站分级1639. 拓扑顺序 写在前面 昨晚cf div3的F就是一道基本上可以说板子的拓扑排序的题目&#xff0c;没有做出来感觉图论很早之前就看了&am…

ubuntu22.04@laptop OpenCV Get Started: 008_image_filtering_using_convolution

ubuntu22.04laptop OpenCV Get Started: 008_image_filtering_using_convolution 1. 源由2. convolution应用Demo2.1 C应用Demo2.2 Python应用Demo 3. 重点分析3.1 identity矩阵3.2 all ones 5x5矩阵3.3 blur 5x5矩阵3.4 GaussianBlur 5x5矩阵3.5 medianBlur 5x5矩阵3.6 Sharpe…

如何在极低成本硬件上落地人工智能算法 —— 分布式AI

一、背景 分布式AI的发展前景非常广阔&#xff0c;随着5G、6G等高速网络通信技术的普及和边缘计算能力的提升&#xff0c;以及AI算法和硬件的不断优化进步&#xff0c;分布式AI将在多个领域展现出强大的应用潜力和市场价值&#xff1a; 1. **物联网&#xff08;IoT&#xff0…

JVM(1)基础篇

1 初始JVM 1.1 什么是JVM JVM 全称是 Java Virtual Machine&#xff0c;中文译名 Java虚拟机。JVM 本质上是一个运行在计算机上的程序&#xff0c;他的职责是运行Java字节码文件。 Java源代码执行流程如下&#xff1a; 分为三个步骤&#xff1a; 编写Java源代码文件。 使用…

Swift Combine 使用 flatMap 和 catch错误处理 从入门到精通十三

Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二Swift Combine 管道 从入门到精通三Swift Combine 发布者publisher的生命周期 从入门到精通四Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五Swift Com…

什么是 Flet?

什么是 Flet&#xff1f; Flet 是一个框架&#xff0c;允许使用您喜欢的语言构建交互式多用户 Web、桌面和移动应用程序&#xff0c;而无需前端开发经验。 您可以使用基于 Google 的 Flutter 的 Flet 控件为程序构建 UI。Flet 不只是“包装”Flutter 小部件&#xff0c;而是…

为什么说技术进步很慢? —— 技术的先进性与其当下价值的不匹配

一、背景 技术进步是否缓慢是一个相对的概念&#xff0c;需要在不同的领域和时间段内进行分析。以下是一些不同领域中可能造成技术进步看似缓慢的原因&#xff1a; 1. **基础研究瓶颈**&#xff1a;许多先进技术的发展依赖于基础科学的突破&#xff0c;而这些突破往往需要长时…

MySQL-----函数篇

目录 ▶ 字符串函数 ▶ 数值函数 ▶ 日期函数 ▶ 流程函数 ▶ 简介 函数是指一段可以直接被另一段程序调用的程序或代码。 ▶ 字符串函数 函数描述实例ASCII(s)返回字符串 s 的第一个字符的 ASCII 码。 返回 CustomerName 字段第一个字母的 ASCII 码&#xff1a; S…

vuex中Actions详解,代码示例

Vuex 中的 Actions 是用于触发mutations 的一种方式&#xff0c;它可以包含异步操作&#xff0c;并通过提交(commit)mutations 来改变 store 的状态。以下是 Actions 的详细介绍、使用步骤和示例代码&#xff1a; Actions 的介绍&#xff1a; Actions 是 Vuex 中的一个重要概…

第一篇【传奇开心果系列】Python的pyttsx3库技术点案例示例:文本转换语言

传奇开心果短博文系列 系列短博文目录Python的pyttsx3库技术点案例示例系列 短博文目录前言一、pyttsx3主要特点和功能介绍二、pyttsx3文字转语音操作步骤介绍三、多平台支持介绍和示例代码四、多语言支持介绍和示例代码五、自定义语言引擎介绍和示例代码六、调整语速和音量介绍…

JavaWeb学习|i18n

学习材料声明 所有知识点都来自互联网&#xff0c;进行总结和梳理&#xff0c;侵权必删。 引用来源&#xff1a;尚硅谷最新版JavaWeb全套教程,java web零基础入门完整版 i18n 国际化&#xff08;Internationalization&#xff09;指的是同一个网站可以支持多种不同的语言&…

文心一言4.0 VS ChatGPT4.0哪家强?!每月60块的文心一言4.0值得开吗?

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

C++ Qt框架开发 | 基于Qt框架开发实时成绩显示排序系统(3) 保存表格数据

对上两篇篇的工作C Qt框架开发| 基于Qt框架开发实时成绩显示排序系统&#xff08;1&#xff09;-CSDN博客和C Qt框架开发 | 基于Qt框架开发实时成绩显示排序系统&#xff08;2&#xff09;折线图显示-CSDN博客继续优化&#xff0c;增加一个保存按钮&#xff0c;用于保存成绩数据…

【Java记】数据类型与变量

一、数据类型 在Java中数据类型主要分为两类&#xff1a;基本数据类型和引用数据类型。基本数据类型有四类八种&#xff1a; 四类&#xff1a;整型、浮点型、字符型以及布尔型八种&#xff1a; 数据类型 关键字 内存占用 范围 字节型 byte 1 字节 -128~ 127 短整型 …

基于GPT-4一键完成数据分析全流程的AI Agent: Streamline Analyst

大型语言模型&#xff08;LLM&#xff09;的兴起不仅为获取知识和解决问题开辟了新的可能性&#xff0c;而且催生了一些新型智能系统&#xff0c;例如旨在辅助用户完成特定任务的AI Copilot以及旨在自动化和自主执行复杂任务的AI Agent&#xff0c;使得编程、创作等任务变得高效…

AndroidStdio修改安卓模拟器的安装位置

AndroidStdio修改安卓模拟器的安装位置 1.删除原有的虚拟机 可以直接删除这个avd文件&#xff0c;放心大胆删除 在这个目录下可以看到.avd文件和.ini文件。.avd占了我10G.上图是我转移.avd后截的。发现这个.ini文件&#xff0c;.ini文件就是配置文件&#xff0c;就像mysql安装…

ElasticSearch快速开始

目录 全文检索 全文检索的原理 什么是倒排索引 ElasticSearch介绍 ElasticSearch应用场景 ElasticSearch下载安装&#xff08;windows&#xff09; 客户端Kibana安装 Elasticsearch安装分词插件 ElasticSearch快速开始 ElasticSearch索引操作 创建索引 查询索引 删…

蓝桥杯电子类单片机提升二——串口发送与接收

目录 单片机资源数据包_2023 一、串口收发数据的介绍 1.波特率&#xff08;Baud Rate&#xff09; 2.帧格式 3.SBUF寄存器&#xff08;Serial Buffer&#xff09; 4.中断处理 二、如何从stc-isp获取串口收发数据的代码 1.代码的获取 2.代码的修改 1&#xff09;第一步…