java easyexcel上传和下载数据

news2025/2/3 15:54:33

安装依赖

easyexcel官方文档

  <!--通过注解的方式导出excel-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.3.1</version>
        </dependency>

注意踩坑:easyexcel会和poi的依赖冲突poi必须升级 4.0以上版本都可以不然 填充模版的时候会报错

<dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>4.1.2</version>
            </dependency>
            <!--导出文件到Excel里面-->
            <!--Apache POI是一个开源的Java库,用于处理Microsoft Office文件格式,包括.doc、.docx、.xls、.xlsx等。
            poi-ooxml是这个库的一部分,专门用于处理Office Open XML格式的文件,如.docx和.xlsx。-->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>4.1.2</version>
            </dependency>

Student实体类加Excel注解

package com.sky.entity;

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


@Data
//@ContentRowHeight   //内容的行高
//@HeadRowHeight     //表头的行高
@ExcelIgnoreUnannotated   //没有注解的忽略不导出
public class Student {
    @ExcelProperty("ID")  //简单的头信息
    @ExcelIgnore   //不参与
    private String id;
   // @ExcelProperty(value={"学员信息表","学生姓名"})  //复杂的头信息
    @ExcelProperty("学生姓名")
    @ColumnWidth(20)    //列宽
    private String name;
   // @ExcelProperty(value={"学员信息表","学生性别"})  //复杂的头信息
    @ExcelProperty("学生性别")
    private String gender;
   // @ExcelProperty(value={"学员信息表","出生日期"})  //复杂的头信息  学员信息表第一个都是相同 会自动合并表头信息
    @ExcelProperty("出生日期")   //名称必须和Excel的文件表头一样 不然读取不到信息
    @ColumnWidth(20)    //列宽
    @DateTimeFormat("yyyy-MM-dd")
    private String birthday;

}

创建一个读取Student类的读取文档的监听器类StudentListener 继承AnalysisEventListener 重写方法

package com.sky.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.sky.entity.Student;
import com.sky.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.ArrayList;

/*
* 读取文档的监听器类
* @Component 是Spring框架中的一个核心注解,它表示一个组件,可以是一个普通的Java类。
* 当你在一个类上使用 @Component 注解时,Spring会将其视为一个Spring组件,并将其自动注册为一个Spring bean。
* 就可以自动导入其他类使用
* */
@Component
@Scope("prototype")   //多列 就可以交个容器  不需要new了
public class StudentListener extends AnalysisEventListener<Student> {
    @Autowired
    StudentService studentService;

    ArrayList<Student> students=new ArrayList<>();

    /*
     * 每读一行内容,都会调用一次该对象的invoke,在invoke可以操作使用读取到的数据
     * student  每次读取到的封装对象
     * */
    @Override
    public void invoke(Student student, AnalysisContext analysisContext) {
        //如果这里读取不到数据,看看Student类里面是否设置了复杂的头 信息
        //System.out.println("student="+student);
        students.add(student); //这里是一条一条的读取数据 添加到集合里面去
        //TODO 每读取5行数据  这里有个问题 少于5行的不读了 后续需要解决一下
        if(students.size() % 5 == 0){  //满足5条才执行
            studentService.readExcel(students);
            students.clear(); //清空集合
        }

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

    }


}

创建web接口上传和下载Excel文件

package com.sky.controller.admin;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.enums.WriteDirectionEnum;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.read.builder.ExcelReaderSheetBuilder;
import com.alibaba.excel.util.MapUtils;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.sky.entity.FillData;
import com.sky.entity.Student;
import com.sky.listener.StudentListener;
import com.sky.result.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
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;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;

@RestController
@RequestMapping("/admin/student")
@Api(tags = "学生类接口")
@Slf4j
public class StudentController {
    @Autowired
    StudentListener studentListener;


    @GetMapping("/list")
    @ApiOperation("学生导入列表")
    public Result list(){
        /**
        * pathName  要读的文件的路径
         * head 文件中每一行数据要存储到的实体类型的class
         * readListener 读取监听器,每读一行内容,都会调用一次该对象的invoke,在invoke可以操作使用读取到的数据
        * */
        /*获得一个工作簿对象*/
         ExcelReaderBuilder readWorkBook= EasyExcel.read("sky-server/src/main/resources/template/学生信息表.xlsx", Student.class,studentListener);
        /*获得一个工作表对象  默认读取第一个工作表对象*/
        ExcelReaderSheetBuilder sheet=readWorkBook.sheet();
        /*读取工作表中内容*/
        sheet.doRead();

        return Result.success();
    }
    @GetMapping("/list1")
    @ApiOperation("学生导出列表")
    public Result list1(){
        /**
         * pathName  要写的文件的路径
         * head 封装写入数据的实体类型
         *  写的工作簿对象
         * */
        /*获得一个工作簿对象*/
        ExcelWriterBuilder writeWorkBook= EasyExcel.write("sky-server/src/main/resources/template/学生信息表-writer.xlsx", Student.class);
        /*获得一个工作表对象*/
        ExcelWriterSheetBuilder sheet=writeWorkBook.sheet();
        /*
        * 准备数据
        * */
        List<Student> students=initData();
        /*写*/
        sheet.doWrite(students);

        return Result.success();
    }
    /*
    * 生成数据
     */
    private static List<Student> initData(){
        ArrayList<Student> students=new ArrayList<>();
        Student data=new Student();

        for (int i = 0; i <10 ; i++) {
            data.setName("学生编号010"+i);
            data.setBirthday("2012-03-04 12:12:12");
            data.setGender("女");
            data.setId("1");
            students.add(data);
        }
        return students;
    }
    /*
     * 生成数据
     */
    private static List<FillData> initFillData(){
        ArrayList<FillData> fillDatas=new ArrayList<FillData>();


        for (int i = 0; i <10 ; i++) {
            FillData fillData=new FillData();
            fillData.setName("学生编号10"+i);
            fillData.setAge(23);
            fillDatas.add(fillData);
        }
        return fillDatas;
    }
    /*
    * 上传的Excel文件  读取里面的内容存储到数据库
    * */
    @PostMapping("/list2")
    @ApiOperation("上传Excel")
    public Result uplond(MultipartFile uploadExcel) {
        log.info("文件上传:{}", uploadExcel);
        try {
            /*获得一个工作簿对象*/
            ExcelReaderBuilder readWorkBook=  EasyExcel.read(uploadExcel.getInputStream(),Student.class,studentListener);
            /*获得一个工作表对象  默认读取第一个工作表对象*/
            ExcelReaderSheetBuilder sheet=readWorkBook.sheet();
            /*读取工作表中内容*/
            sheet.doRead();


            return Result.success();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Result.error("上传错误");
    }
    /*
    * 下载数据
    * */
    @GetMapping("/list3")
    @ApiOperation("下载Excel")
    public void uplonddowond(HttpServletResponse response) {


        try {
            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");
            //3. 通过输出流将Excel文件下载到客户端浏览器
            ServletOutputStream outputStream = response.getOutputStream();
            /**
             * pathName  要写的文件的路径
             * head 封装写入数据的实体类型
             *  写的工作簿对象
             * */
            /*获得一个工作簿对象*/
            ExcelWriterBuilder writeWorkBook= EasyExcel.write(outputStream, Student.class);
            /*获得一个工作表对象*/
            ExcelWriterSheetBuilder sheet=writeWorkBook.sheet();
            /*
             * 准备数据
             * */
            List<Student> students=initData();
            /*写*/
            sheet.doWrite(students);
            //关闭资源
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }



    }

    /**
    * 按照规定的模块导入数据
     * 单组数据按照模版填充
    * */
    @GetMapping("/list4")
    @ApiOperation("单组数据按照模版填充")
    public Result filldatalist() {
        // 确定存储目录
        String projectDir = System.getProperty("user.dir"); //获取当前项目的根目录
        System.out.println(projectDir);
        //准备模版
        String templateName="sky-server/src/main/resources/template/templatedome1.xlsx";
        String fileName ="sky-server/src/main/resources/template/success-单组数据.xlsx";
        // 这里 会填充到第一个sheet, 然后文件流会自动关闭
//        FillData fillData = new FillData();
//        fillData.setName("张三");
//        fillData.setAge(5);
        //准备map数据
        Map<String,String> map = new HashMap<String, String>();
        map.put("name", "李四");
        map.put("age", "55");
        EasyExcel.write(fileName).withTemplate(templateName).sheet().doFill(map);
        return Result.success();
    }
    /**
     * 按照规定的模块导入数据
     * 多组数据按照模版填充
     * */
    @GetMapping("/list5")
    @ApiOperation("单组数据按照模版填充")
    public Result filldatalist5() {
        // 确定存储目录
        String projectDir = System.getProperty("user.dir"); //获取当前项目的根目录
        System.out.println(projectDir);
        //准备模版
        String templateName="sky-server/src/main/resources/template/templatedome2.xlsx";
        String fileName ="sky-server/src/main/resources/template/success-多组数据.xlsx";
        //准备数据
        List<FillData> fillDataList=initFillData();
       //填充数据,doXXX会在读写结束后自动关闭流
        EasyExcel.write(fileName).withTemplate(templateName).sheet().doFill(fillDataList);
        return Result.success();
    }
    /**
     * 按照规定的模块导入数据
     * 组合按照模版填充
     * */
    @GetMapping("/list6")
    @ApiOperation("单组数据按照模版填充")
    public Result filldatalist6() {
        // 确定存储目录
        String projectDir = System.getProperty("user.dir"); //获取当前项目的根目录
        System.out.println(projectDir);
        //准备模版
        String templateName="sky-server/src/main/resources/template/templatedome3.xlsx";
        String fileName ="sky-server/src/main/resources/template/success-组合数据.xlsx";
        //准备数据
        List<FillData> fillDataList=initFillData();
        //创建一个手动关闭流 build()
        ExcelWriter workBook=EasyExcel.write(fileName,FillData.class).withTemplate(templateName).build();
        //创建工作表对象
        WriteSheet sheet=EasyExcel.writerSheet().build();
        //换行,不然组合的会覆盖
        FillConfig fillConfig=FillConfig.builder().forceNewRow(true).build();

        HashMap<String,String> dateAndTotal=new HashMap<>();
        dateAndTotal.put("date","2023-12-12");
        dateAndTotal.put("total","20000");
        //多组填充
        workBook.fill(fillDataList,fillConfig,sheet);
        //单组填充
        workBook.fill(dateAndTotal,sheet);
        //关闭流
        workBook.finish();

        return Result.success();
    }
    /**
     * 按照规定的模块导入数据
     * 水平填充
     * */
    @GetMapping("/list7")
    @ApiOperation("单组数据按照模版填充")
    public Result filldatalist7() {
        // 确定存储目录
        String projectDir = System.getProperty("user.dir"); //获取当前项目的根目录
        System.out.println(projectDir);
        //准备模版
        String templateName="sky-server/src/main/resources/template/templatedome4.xlsx";
        String fileName ="sky-server/src/main/resources/template/success-水平填充.xlsx";
        //准备数据
        List<FillData> fillDataList=initFillData();
        //创建一个手动关闭流 build()
        ExcelWriter workBook=EasyExcel.write(fileName,FillData.class).withTemplate(templateName).build();
        //创建工作表对象
        WriteSheet sheet=EasyExcel.writerSheet().build();
        //换行,不然组合的会覆盖
        FillConfig fillConfig=FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();


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

        //关闭流
        workBook.finish();

        return Result.success();
    }
    /**
     * 按照规定的模块导入数据
     * 报表导出
     * */
    @GetMapping("/list8")
    @ApiOperation("报表导出")
    public Result filldatalist8() {
        // 确定存储目录
        String projectDir = System.getProperty("user.dir"); //获取当前项目的根目录
        System.out.println(projectDir);
        //准备模版
        String templateName="sky-server/src/main/resources/template/运营数据统计.xlsx";
        String fileName ="sky-server/src/main/resources/template/success-报表导出.xlsx";
        //准备数据
        List<Student> fillStudent=initData();
        //创建一个手动关闭流 build()
        ExcelWriter workBook=EasyExcel.write(fileName,Student.class).withTemplate(templateName).build();
        //创建工作表对象
        WriteSheet sheet=EasyExcel.writerSheet().build();

        HashMap<String,String> dateAndTotal=new HashMap<>();
        dateAndTotal.put("date","2023-12-12");
        dateAndTotal.put("increaseCount","200");
        dateAndTotal.put("totalCount","2000");
        dateAndTotal.put("increaseCountWeek","20000");
        dateAndTotal.put("increaseCountMonth","30000");


        //单组填充
        workBook.fill(dateAndTotal,sheet);
        //多组填充
        workBook.fill(fillStudent,sheet);

        //关闭流
        workBook.finish();

        return Result.success();
    }
}


在这里插入图片描述
模版1 templatedome1
在这里插入图片描述
模版2 templatedome2
在这里插入图片描述
模版3 templatedome3
在这里插入图片描述
模版4 templatedome4
在这里插入图片描述
报表模版
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vm 如何桥接模式

1、配置桥接模式 2、进入虚拟机配置 网卡 ip 根据自己的实际情况。 如果桥接的有限以太网外部连接了 路由器&#xff0c;可以直接选择 DHCP 自动分配。 如果 路由器没有帮你分配 ip 地址&#xff0c;建议设置 路由器&#xff0c; 或者直接手动配置 ip地址。 如果没有就自己手…

Go语言与HTTP/2协议的实践探索

随着互联网技术的发展&#xff0c;HTTP/2协议逐渐成为主流。Go语言作为一种高效、简洁的编程语言&#xff0c;与HTTP/2协议的结合具有很大的潜力。本文将探讨Go语言与HTTP/2协议的实践探索。 一、HTTP/2协议的优势 HTTP/2协议相比HTTP/1.1协议&#xff0c;具有以下优势&#…

Modbus-TCP数据帧

Modbus-TCP基于4种报文类型 MODBUS 请求是客户机在网络上发送用来启动事务处理的报文MODBUS 指示是服务端接收的请求报文MODBUS 响应是服务器发送的响应信息MODBUS 证实是在客户端接收的响应信息 Modbus-TCP报文: 报文头MBAP MBAP为报文头&#xff0c;长度为7字节&#xff0c…

DshanMCU-R128s2 ADC 按键配置方法

FreeRTOS平台上使用的按键为ADC-KEY&#xff0c;采用的ADC模块为GPADC。 按键功能驱动的实现是通过ADC分压&#xff0c;使每个按键检测的电压值不同&#xff0c;从而实现区分不同的按键。按下或者弹起中断之后&#xff0c;通过中断触发&#xff0c;主动检测当前电压识别出对应…

金蝶云星空执行部署包后业务对象会被标记上部署包的开发码

文章目录 金蝶云星空执行部署包后业务对象会被标记上部署包的开发码 金蝶云星空执行部署包后业务对象会被标记上部署包的开发码 会被标记成开发码的业务对象包括以下&#xff1a; 新增的业务对象&#xff0c;扩展的业务对象 --查询二开的元数据打包 FPACKAGEID不为空&#xff…

阻塞 IO(BIO)

文章目录 阻塞 IO(BIO)模型等待队列头init_waitqueue_headDECLARE_WAIT_QUEUE_HEAD 等待队列项使用方法驱动程序应用程序模块使用参考 阻塞 IO(BIO) 模型 等待队列是内核实现阻塞和唤醒的内核机制。 等待队列以循环链表为基础结构&#xff0c;链表头和链表项分别为等待队列头和…

loki-日志

一、loki Github ELK虽然功能丰富&#xff0c;但规模复杂&#xff0c;资源占用高&#xff0c;操作苦难&#xff0c;很多功能往往用不上&#xff0c;loki 受 prometheus 启发的水平可扩展、高可用、多租户日志聚合系统&#xff0c;它的设计非常经济高效且易于操作&#xff0c;…

Linux:动态链接

文章目录 动态链接共享库静态库的缺点共享库共享库是以两种不同的方式来“共享”第一种&#xff1a;共享这个so文件中的代码和数据第二种&#xff1a;共享库的.text 节的副本可以被不同的正在运行的进程共享 动态链接过程 动态链接的用武之地和使用场景分发软件构建高性能 Web …

初识Docker-什么是docker

Docker是一个快速交付应用、运行应用的技术 目录 一、Docker 二、运用场景 一、什么是Docker&#xff1f;它的作用是什么&#xff1f; Docker如何解决大型项目依赖关系复杂&#xff0c;不同组件依赖的兼容性问题? Docker允许开发中将应用、依赖、函数库、配置一起打包&…

服装店收银系统 一种私域运营的神器

私域运营是指通过建立和管理自己的客户数据库来实现精细化营销和客户关系管理。服装店收银系统是门店私域运营的神器之一&#xff0c;服装店收银系统可以帮助店主收集客户的购买信息、消费偏好等数据&#xff0c;从而更好地了解客户需求并进行个性化营销。 以下是一些服装店收银…

用Minikube 搭建一个单机k8s玩玩

Minikube 介绍 Minikube是一款单机搭建和管理Kubernetes集群的工具。与Kind 类似&#xff0c;但是个人认为比Kind 好用 Minikube 安装 mac如果安装了 Homebrew&#xff0c;直接执行以下命令安装minikube brew install minikubemac没有安装Homebrew,需要到官网下载选择系统配置…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之TextInput输入框组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之TextInput输入框组件 一、操作环境 操作系统: Windows 10 专业版 IDE:DevEco Studio 3.1 SDK:HarmonyOS 3.1 二、TextInput 接口 TextInput(value?:{placeholder?: ResourceStr, tex…

HackTheBox - Medium - Linux - Jupiter

Jupiter Jupiter 是一台中等难度的 Linux 机器&#xff0c;它有一个使用 PostgreSQL 数据库的 Grafana 实例&#xff0c;该数据库在权限上过度扩展&#xff0c;容易受到 SQL 注入的影响&#xff0c;因此容易受到远程代码执行的影响。一旦站稳脚跟&#xff0c;就会注意到一个名…

被有道云笔记成功劝退拥抱Joplin(Joplin使用过程遇到的问题)

本人职业程序员&#xff0c;培训讲师&#xff08;技术类&#xff09;、活动主持人&#xff0c;对多端阅读是有些需求的&#xff0c;平时习惯墨水平板、手机和笔记本电脑登录着有道云笔记。其实本人对内容比较重视&#xff0c;对有道云笔记提供的什么AI服务、PDF转Word等功能是没…

企业级“RAS”的数据平台如何炼成?

从“看报表”到“数据分析结果直接投入运营”&#xff0c;数字化正在深入企业经营&#xff0c;数据系统正在成为核心生产系统。相应的&#xff0c;企业对“作业挂了”、“系统崩了”、“算不出来”的容忍度越来越低——只有足够稳定、可靠、专业的数据系统&#xff0c;才能及时…

虾皮跨境电商物流:打造高效便捷的全球供应链解决方案

随着全球化的推进和电子商务的蓬勃发展&#xff0c;跨境电商物流成为了越来越多商家和消费者关注的焦点。虾皮&#xff08;Shopee&#xff09;作为一家领先的电商平台&#xff0c;不仅提供了丰富多样的商品选择&#xff0c;还致力于为卖家和消费者提供高效便捷的跨境电商物流服…

WiFi+蓝牙物联网定制方案——五大核心难点

WiFi蓝牙物联网定制方案可以根据具体需求进行定制&#xff1a; 1、设备连接方案&#xff1a;采用WiFi和蓝牙技术&#xff0c;将物联网设备与智能手机、平板电脑等设备进行连接&#xff0c;实现数据传输和远程控制。 2、数据传输方案&#xff1a;通过WiFi和蓝牙技术&#xff0c;…

Android平台RTMP推送|轻量级RTSP服务能力封装代码实现

好多开发者问我们&#xff0c;有没有针对Android平台RTMP直播推送、轻量级RTSP服务模块的进一步封装&#xff0c;可以更便捷的调用大牛直播SDK接口。 为此&#xff0c;我们分享下我们针对Android平台SmartPublisher做的二次封装代码&#xff1a; package com.daniulive.smartp…

OpenCV | 告别人工目检:深度学习技术引领工业品缺陷检测新时代

文章目录 机器视觉缺陷检测工业上常见缺陷检测方法内容简介作者简介目录读者对象如何阅读本书获取方式 机器视觉 机器视觉是使用各种工业相机&#xff0c;结合传感器跟电气信号实现替代传统人工&#xff0c;完成对象识别、计数、测量、缺陷检测、引导定位与抓取等任务。其中工…

用BEVformer来卷自动驾驶-1

之所以是-1,是因为大概率1篇文章写不完,但是又不知道应该用几篇来说事,先写着看 按照惯例,上论文地址:2203.17270v1.pdf (arxiv.org) 什么是BEV, Birds -Eye-View的意思,就是鸟瞰 比如稍微传统一些的自动驾驶,大部分的实现。如果靠纯CV的方案的话,那么基本…