使用EasyPoi导入导出Excel

2023-11-10

easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员
就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板
语言(熟悉的表达式语法),完成以前复杂的写法

**

这个服务即将关闭,文档迁移到 http://www.wupaas.com/ 请大家访问最新网站
**
不如poi那么自定义,不如jxl那么多标签,但是我们就是写的少,写的少

EasyPoi的主要特点

1.设计精巧,使用简单
2.接口丰富,扩展简单
3.默认值多,write less do more
4.spring mvc支持,web导出可以简单明了
功能

Excel自适应xls和xlsx两种格式,word只支持docx模式

1.Excel导入

注解导入
Map导入
大数据量导入sax模式
导入文件保存
文件校验
字段校验
2.Excel导出

注解导出
模板导出
html导出
3.Excel转html

4.word导出

5.pdf导出

1.2 Easypoi介绍
Easypoi 为谁而开发

不太熟悉poi的
不想写太多重复太多的
只是简单的导入导出的
喜欢使用模板的
都可以使用easypoi

Easypoi的目标是什么
Easypoi的目标不是替代poi,而是让一个不懂导入导出的快速使用poi完成Excel和word的各种操作,而不是看很多api才可以完成这样工作

为什么会写Easypoi

以前的以前(岁月真TMD的快)我虽然写了不少代码但还是很少写poi,然后跳到一家公司之后就和业务人员聊上了,来这个需要个报表,这个报表样式是这样的,这个表头是这样的,就这样我写了大量的poi代码,每次都是大量的篇幅,copy to copy,无聊的一逼,然后加入了jeecg,jeecg中有一个小的工具类,虽然我也不知道是谁写的,然是可以用注解搞定最简单的导出,突然豁然开朗,我可以完善,让我从报表的苦海当中脱离出来,这样我花了一周的时间做了第一个版本支持导入导出放到了jeecg,发现还是不错的,慢慢的用的人越来越多,我就把这块独立出来了,再然后有人提出了模板,然后就加入了模板功能,提出了word的需求,加入了word的功能,后来工作忙了虽然没再参与jeecg,但还是一直维持这easypoi的更新,根据见识的增长也不断的重构这代码,直到现在

独特的功能

基于注解的导入导出,修改注解就可以修改Excel
支持常用的样式自定义
基于map可以灵活定义的表头字段
支持一堆多的导出,导入
支持模板的导出,一些常见的标签,自定义标签
支持HTML/Excel转换,如果模板还不能满足用户的变态需求,请用这个功能
支持word的导出,支持图片,Excel
小白如何开始

下载demo运行看看,基本上常见的用用法都在里面easypoi-test
查看几个*Util的用法,Easypoi的主要输出就是这个
看看注解的意思
看看模板的标签用法
可以出师了

导入导出Excel 注解版(其他的小编还没试过)

目录

 - 可能存在的小坑
 - 先写model
 - 再写controller
 - 最后写service

可能存在的小坑

缓存问题
缓存问题好像是很多童鞋都遇到的问题,可能是我设计的逻辑问题,但是一直没有好的解决,
但是我也给了一个无奈的解决方案,大家可以自己实现接口IFileLoader

public interface IFileLoader {
/**
* 可以自定义KEY的作用
* @param key
* @return
*/
public byte[] getFile(String key);

}
来自己获取自己的文件,用来解决文件获取不到的问题
设置提供了两种方案,都是POICacheManager 的静态方法

public static void setFileLoder(IFileLoader fileLoder) {
    POICacheManager.fileLoder = fileLoder;
}

/**
 * 一次线程有效
 * @param fileLoder
 */
public static void setFileLoderOnce(IFileLoader fileLoder) {
    if (fileLoder != null) {
        LOCAL_FILELOADER.set(fileLoder);
    }
}

第一个是全局替换,可以在项目启动的时候,设置下就可以了,第一个是当前线程有效,希望可以帮助大家解决问题,我再研究下更通用的文件获取,或者那位朋友提供下自己的通用方案。

这是我自学时看的网站可能点不进去你试试吧

Gitte 官网搜索Easypoi全是使用教程)

接下来先讲一下注解吧!

注解介绍
easypoi起因就是Excel的导入导出,最初的模板是实体和Excel的对应,model–row,filed–col 这样利用注解我们可以和容易做到excel到导入导出
经过一段时间发展,现在注解有5个类分别是

@Excel 作用到filed上面,是对Excel一列的一个描述
@ExcelCollection 表示一个集合,主要针对一对多的导出,比如一个老师对应多个科目,科目就可以用集合表示
@ExcelEntity 表示一个继续深入导出的实体,但他没有太多的实际意义,只是告诉系统这个对象里面同样有导出的字段
@ExcelIgnore 和名字一样表示这个字段被忽略跳过这个导导出
@ExcelTarget 这个是作用于最外层的对象,描述这个对象的id,以便支持一个对象可以针对不同导出做出不同处理
注解中的ID的用法
这个ID算是一个比较独特的例子,比如

@ExcelTarget(“teacherEntity”)
public class TeacherEntity implements java.io.Serializable {
/** name */
@Excel(name = “主讲老师_teacherEntity,代课老师_absent”, orderNum = “1”, mergeVertical = true,needMerge=true,isImportField = “true_major,true_absent”)
private String name;
这里的@ExcelTarget 表示使用teacherEntity这个对象是可以针对不同字段做不同处理
同样的ExcelEntity 和ExcelCollection 都支持这种方式
当导出这对象时,name这一列对应的是主讲老师,而不是代课老师还有很多字段都支持这种做法

@Excel
这个是必须使用的注解,如果需求简单只使用这一个注解也是可以的,涵盖了常用的Excel需求,需要大家熟悉这个功能,主要分为基础,图片处理,时间处理,合并处理几块,name_id是上面讲的id用法,这里就不累言了
请添加图片描述
请添加图片描述
请添加图片描述

在这之前先引入依赖

<!--        Excel导入导出-->
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>3.2.0</version>
        </dependency>
    </dependencies>

model层

@Data
@Slf4j
@NoArgsConstructor
@AllArgsConstructor
public class MonthlyReportDTO extends BaseDTO {
    /*type=> 导出类型 1 是文本 2 是图片,3 是函数,10 是数字 默认是文本*/
    @Excel(name = "项目名称",orderNum="1" )
    private String name;//项目名称
    @Excel(name = "项目所属单位",orderNum="2" )
    private String projectUnit;//项目所属单位
    @Excel(name = "总投资",type = 10,orderNum="3" )
    private Double totalnvestment;//总投资
    @Excel(name = "年度计划",type = 10,orderNum="4" )
    private Double yearPlan;//年度计划
    @Excel(name = "本月投资完成",type = 10,orderNum="5" )
    private Double theMonthInvestment;//本月投资完成
    @Excel(name = "本年累计投资完成",type = 10,orderNum="6" )
    private Double theYearTotalInvestment;//本年累计投资完成
    @Excel(name = "自开工累计投资完成",type = 10,orderNum="7" )
    private Double fromheadTotalInvestment;//自开工累计投资完成
    @Excel(name = "年计划完成率(%)",type = 10,orderNum="8" )
    private Double yearPlanCompletion;//年计划完成率(%)
    @Excel(name = "形象进度",orderNum="9" )
    private String imageProgress;//形象进度
    @Excel(name = "形象进度百分比",type = 10,orderNum="10" )
    private Integer imageProgressPercentage;//形象进度百分比
    @Excel(name = "附件",orderNum="11")
    private String file;//附件
    @Excel(name = "上月本年累计",type = 10,orderNum="12" )
    private Double lastMonthTheYearTotal;//上月本年累计
    @Excel(name = "上月开工累计",type = 10,orderNum="13" )
    private Double lastMonthstartsTotal;//上月开工累计
    @Excel(name = "备注",orderNum="14" )
    private String note;//备注

}
//你用哪个实体类装的数据就给谁加@Excel注解

Controller层

@RestController
@Slf4j
@RequestMapping(value = "Url映射地址")
public class 类名 extends UpdateController<实体类, 实体类DTO> {
    //Excel导入
    @PostMapping(value = "Url映射地址")
    public ResponseCode<String> excelImport(@RequestParam("file") MultipartFile file){
        ResponseCode<String> responseCode = ResponseCode.sucess();
        responseCode.setMsg(monthlyReportUpdateService.excelImport(file));
        return  responseCode;
    }
}
@RestController
@Slf4j
@RequestMapping(value = "monthlyReport/query")
public class MonthlyReportQuaryController extends QueryController<实体, 实体DTO> {
    //Excel导出
    @GetMapping(value = "excel/export")
    public void exportExcel(HttpServletResponse response){
     monthlyReportService.exportExcel(response);
    }
}

Service层

public interface MonthlyReportService extends QueryService<实体, 实体DTO> {
         String exportExcel(HttpServletResponse response);//导出表格数据
}
public interface MonthlyReportUpdateService extends UpdateService<MonthlyReport, MonthlyReportDTO> {
    String excelImport(MultipartFile file);//导入Excel
}

Service实现层

@Service
@Slf4j
public class MonthlyReportServiceImpl  extends QueryServiceImpl<实体, 实体DTO> implements MonthlyReportService{
//导出
    @Override
    public String exportExcel(HttpServletResponse response) {
        List<MonthlyReport> list = monthlyReportRespository.findAll();
        System.out.println(list);
        List<MonthlyReportDTO> dtoList=monthlyReportMapper.toMonthlyReportDTOList(list);
        String msg="";
        LocalDate localDate=LocalDate.now();
        String s=""+localDate;
        StringBuilder Month=new StringBuilder(s);
        s=Month.substring(6,7);

        try {
           ExportParams params = new ExportParams("信息化项目"+s+"月投资完成情况月报", "测试", ExcelType.XSSF);
//            Workbook workbook = ExcelExportUtil.exportExcel(params, MonthlyReportDTO.class, dtoList);
//            msg="H:/ideaProject/InvestmentJava/InvestmentSystem/HandleSystem-CardDev/AdministratorService/src/main/resources/excelFile/信息化项目"+s+"月投资完成情况月报.xlsx";
//            File file=new File(msg);
//            if(!file.exists()){
//             file.createNewFile();
//            }else{
//                file.delete();
//                file.createNewFile();
//            }
//            FileOutputStream fos = new FileOutputStream(file);
//            workbook.write(fos);
//           System.out.println("导出成功");
//            fos.close();
            String fileName = "信息化项目"+s+"月投资完成情况月报.xlsx";
            String sheetName = "月投资完成情况月报";
            response.setHeader("content-Type", "application/vnd.ms-excel");
            fileName = new String(fileName.getBytes(), "utf-8");
            response.setHeader("Content-Disposition", "attachment;filename="+ new String( fileName.getBytes("gb2312"), "ISO8859-1" ) );
            ServletOutputStream out = response.getOutputStream();
            Workbook workbooks = ExcelExportUtil.exportExcel(params, MonthlyReportDTO.class, dtoList);
            workbooks.write(out);
            msg="2";
        } catch (IOException e) {
            e.printStackTrace();
        }
        return msg;
    }

}

上面我注释的代码是在本地导出Excel的方法没注释掉的是显示在

Respons中的如下图

请添加图片描述
请添加图片描述

@Service
@Slf4j
public class MonthlyReportUpdateServiceImpl extends UpdateServiceImpl<MonthlyReport, MonthlyReportDTO> implements MonthlyReportUpdateService{
    @Autowired
    private MonthlyReportMapper monthlyReportMapper;
    @Autowired
    private MonthlyReportUpdateRespository monthlyReportUpdateRespository;
    public MonthlyReportUpdateServiceImpl(MonthlyReportUpdateRespository monthlyReportUpdateRespository) {
        super(monthlyReportUpdateRespository);
    }
//excel导入
    @Override
    public String excelImport(MultipartFile file) {
        int i=0;//成功条数
        int j=0;//失败条数
        String msg="";//返回信息
        ImportParams params = new ImportParams();
        params.setHeadRows(1);
        params.setTitleRows(2);
        params.setStartRows(1);
        params.setNeedVerfiy(true);
       try {
           List<MonthlyReportDTO> list = ExcelImportUtil.importExcel(file.getInputStream(), MonthlyReportDTO.class, params);
           //我也不知道为啥这上面导出来的数据中竟会有空数据的所以我就加了以下的判断
           //也希望你们能测试一下如果知道问题了有了更好的解决方法hua'nign
           for (MonthlyReportDTO l:list){
               MonthlyReportDTO monthlyReportDTO =l;
             if(monthlyReportDTO.getNote()!=null||
                monthlyReportDTO.getLastMonthstartsTotal()!=null||
             monthlyReportDTO.getLastMonthTheYearTotal()!=null||
             monthlyReportDTO.getFile()!=null||
             monthlyReportDTO.getImageProgressPercentage()!=null||
             monthlyReportDTO.getImageProgress()!=null||
             monthlyReportDTO.getYearPlanCompletion()!=null||
             monthlyReportDTO.getFromheadTotalInvestment()!=null||
             monthlyReportDTO.getTheYearTotalInvestment()!=null||
             monthlyReportDTO.getTheMonthInvestment()!=null||
             monthlyReportDTO.getYearPlan()!=null||
             monthlyReportDTO.getTotalnvestment()!=null||
             monthlyReportDTO.getProjectUnit()!=null||
             monthlyReportDTO.getName()!=null) {
                 j++;
                 MonthlyReport m=monthlyReportMapper.toMonthlyReport(monthlyReportDTO);
                 monthlyReportUpdateRespository.save(m);
             }else {
                 i++;
                 continue;
             }
           }
           return "成功了"+j+"条";
       }catch (Exception e){
           e.printStackTrace();
       }
       return null;
    }
}


上面的导出代码你视情况用,我的Conroller层是没有返回值的你们可以加上个返回值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用EasyPoi导入导出Excel 的相关文章

随机推荐

  • IDEA2022.3设置自动生成类的serialVersionUID

    打开IDEA 点击File settings Editor Inspections 搜索seria 把这两个选上 然后点击apply ok 使用 选中你要生成的类 Alt Enter键自动提示 这个时候就有创建提示了
  • 网络TCP建立连接为什么需要三次握手而结束要四次

    举个打电话的例子 A 你好我是A 你听得到我在说话吗 B 听到了 我是B 你听到我在说话吗 A 嗯 听到了 建立连接 开始聊天 TCP连接的释放 四次挥手 数据传输完毕后 双方都可释放连接 最开始的时候 客户端和服务器都是处于ESTABLI
  • 牛客网多组输入问题怎么办?EOF使用方法

    需要云服务器等云产品来学习Linux的同学可以移步 gt 腾讯云 lt gt 阿里云 lt gt 华为云 lt 官网 轻量型云服务器低至112元 年 新用户首次下单享超低折扣 目录 1 什么是EOF 2 while getchar EOF
  • cocos2dx使用TiledMap模拟3D地图场景----斜45度2D地图的靠墙直线移动

    基于cocos2dx引擎的第三人称射击游戏 角色使用3D模型 地图采用2 5D 定制地图编辑系统抛开不谈 这里最大可能的挖掘现有工具TiledMap的潜力 完成超2 5D地图的实现 使用2D地图高度模拟3D场景 主要有两个要点需要解决 1
  • 面试官:Vue3有了解过吗?能说说跟Vue2的区别吗?

    一 Vue3介绍 关于vue3的重构背景 看看尤大怎么说 Vue 新版本的理念成型于 2018 年末 当时 Vue 2 的代码库已经有两岁半了 比起通用软件的生命周期来这好像也没那么久 但在这段时期 前端世界已经今昔非比了 在我们更新 和重
  • 用python画小花_用python的小海龟 Turtle 画一朵好看又有趣的小花-Go语言中文社区...

    1967年 Daniel G Bobrow Wally Feurzeig Seymour Papert 和 Cynthia Solomon 设计了LOGO编程语言 用一种直观的方式教孩子们学习编程 尽管该语言也可以解决复杂问题 但给大家留下
  • 关系代数内容学习(交、并、差、投影、选择、连接、重命名)

    关系代数 并 差 交 投影选择 笛卡尔积 连接 重命名 什么是关系代数 是一种抽象的数据查询语言 用对关系的运算来表达查询 关系运算符分类 传统的集合运算符 U N 把关系看成元组的集合 所有运算对象必须具有相同的结构 专门的关系运算符 选
  • AJAX学习笔记1发送Get请求

    传统请求有哪些方式 及缺点 传统请求有哪些 1 直接在浏览器地址栏上输入URL 2 点击超连接 a href 上下文 请求地址 超链接请求 a gt 相对路径 a href http www baidu com 超链接请求 a gt 绝对路
  • 进阶高级测试专项,Pytest自动化测试框架总结(三)

    目录 导读 前言 一 Python编程入门到精通 二 接口自动化项目实战 三 Web自动化项目实战 四 App自动化项目实战 五 一线大厂简历 六 测试开发DevOps体系 七 常用自动化测试工具 八 JMeter性能测试 九 总结 尾部小
  • 电子信息毕设分享 STM32题目项目汇总 - 100例

    文章目录 1前言 2 STM32 毕设课题 3 如何选题 3 1 不要给自己挖坑 3 2 难度把控 3 3 如何命名题目 1前言 更新单片机嵌入式选题后 不少学弟学妹催学长更新STM32和C51选题系列 感谢大家的认可 来啦 以下是学长亲手
  • Pandas库常用函数和操作

    目录 1 DataFrame 处理缺失值 dropna 2 根据某维度计算重复的行 duplicated value counts 3 去重 drop duplicates 4 拼接 1 拼接列 merge 2 拼接行 5 找出在某一特定维
  • PCB Dk、Df和介质损耗

    介电常数Dk Dk即Dielectric constant的简称 中文名叫介电常数 又叫介质常数或介电系数 它是表示绝缘能力特性的一个系数 以字母 表示 在工程应用中 介电常数时常以相对介电常数的形式来表达 而不是绝对值 常见应用有计算阻抗
  • VS2010启动速度变慢和编译速度变慢的解决办法

    以前一直用VC6 0编写C 和MFC程序 速度非常快 后来因为要编64位程序 只能舍弃掉6 0 改VS2010 其实就功能来说 VC6 0真的够用了 VS2010的高级功能从来没用过 刚开始装VS2010的时候运行速度还算可以 但用了不到一
  • 跨线程的信号与槽

    跨线程的信号与槽 接着上面讨论的 我们如何应用驻足在其他线程里的QObject方法呢 Qt提供了一种非常友好而且干净的解决方案 向事件队列post一个事件 事件的处理将以调用我们所感兴趣的方法为主 当然这需要线程有一个正在运行的事件循环 而
  • 【云原生之Docker实战】使用docker部署Halo博客系统

    云原生之Docker实战 使用docker部署Halo博客系统 一 Halo介绍 1 Halo简介 2 Halo特点 3 本次实践说明 二 检查本地docker环境 1 检查docker版本 2 检查docker状态 3 检查docker
  • 面向对象设计原则——里氏代换原则

    里氏代换原则 Liskov Substitution Principle LSP 所有引用基类 父类 的地方必须能透明地使用其子类的对象 里氏代换原则告诉我们 在软件中将一个基类对象替换成它的子类对象 程序将不会产生任何错误和异常 反过来则
  • msvcp120.dll文件丢失如何解决?

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题 如果是新手第一时间会认为是软件或游戏出错了 其实并不是这样 其主要原因就是你电脑系统的该dll文件丢失了或者损坏了 这时你只需下载这个msvcp120 dll文件进行安装 前提是找到
  • InvalidIndexError: (slice(None, None, None), None)

    在对照书复现代码时 1 直接将X Y画图不会报错 2 引入线性回归模型 再用拟合的数据画图就报错 原因 需要转换数据格式 import pandas as pd import matplotlib pyplot as plt import
  • 规避【虚拟专线技术】使用风险实现业务系统安全

    本文为作者学习文章 按作者习惯写成 如有错误或需要追加内容请留言 不喜勿喷 本文为追加文章 后期慢慢追加 一 技战法描述 VPN是利用Internet等公共网络基础设施 通过隧道加密通信技 术 为用户提供安全的数据通信的专用网络 可以实现不
  • 使用EasyPoi导入导出Excel

    easypoi功能如同名字easy 主打的功能就是容易 让一个没见接触过poi的人员 就可以方便的写出Excel导出 Excel模板导出 Excel导入 Word模板导出 通过简单的注解和模板 语言 熟悉的表达式语法 完成以前复杂的写法 这