操作Excel,除了使用POI你还会其他的?

简介: 操作Excel,除了使用POI你还会其他的?

文章标题

一: 使用场景

二: 技术选型

三: 常用API介绍

四: 测试

五: 总结


  温馨提示: 本文总共6334字,阅读完大概需要6-8分钟,希望您能耐心看完,倘若你对该知识点已经比较熟悉,你可以直接通过目录跳转到你感兴趣的地方,希望阅读本文能够对您有所帮助,如果阅读过程中有什么好的建议、看法,欢迎在文章下方留言或者私信我,您的意见对我非常宝贵,再次感谢你阅读本文。

image.png

一: 使用场景

image.png

image.png

二: 技术选型

image.png

image.png

image.png

image.png

三: 常用API介绍

image.png

image.png

image.png

image.png

image.png

四: 测试

(一):添加依赖

    // easyExcel坐标
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.1.7</version>
        </dependency>

(二): JAVA映射实体

package com.elvis.easyexcel.model;
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 lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Demo implements Serializable {
    private static final long serialVersionUID = -920481620956257604L;
    @ExcelIgnore
    @ExcelProperty(value = "姓名", index = 0)
    private String stringType;
    @ExcelProperty(value = "姓名2", index = 1)
    private Integer integerType;
    // 这里使用String类型接收才能格式化,如果使用Date类型则无法格式化
    @ExcelProperty(value = "姓名3", index = 2)
    @DateTimeFormat("yyyy-MM-dd HH:mm:ss")
    private String dateType;
    @ExcelProperty(value = "姓名4", index = 3)
    private Double doubleType;
    @ExcelProperty(value = "姓名5", index = 4)
    private Long longType;
    @ExcelProperty(value = "姓名6", index = 5)
    private Float floatType;
    @ExcelProperty(value = "姓名7", index = 6)
    private Boolean booleanType;
    @ExcelProperty(value = "姓名8", index = 7)
    private Short shortType;
}

(三): 添加监听器

package com.elvis.easyexcel.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Slf4j
public class ObjectListener extends AnalysisEventListener<Object> {
    // 读取到的数据
    private List<Object> readData = new ArrayList<>();
    /**
     *  解析数据进入的方法
     * @param o 本次读到的数据
     * @param analysisContext
     */
    @Override
    public void invoke(Object o, AnalysisContext analysisContext) {
        JSONObject jsonObject = new JSONObject(o);
        log.info("读取到的数据:{}", jsonObject.toString());
        if(Objects.nonNull(o)){
            readData.add(o);
        }
    }
    /**
     * 所有数据解析完成了 都会来调用
     * @param analysisContext
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        log.info("所有数据解析完成了 都会来调用");
    }
    /**
     * 在转换异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行。
     * 如果你的程序在读取解析时即使有异常也不想后面的解析失败的,在此处打出解析错误日志即可
     * 如果你的程序只有解析过程出错就解析解析的话,这在此处手动抛出异常即可
     * @param exception
     * @param context
     * @throws Exception
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) {
        log.error("解析失败,但是继续解析下一行:{}", exception.getMessage());
        // 如果是某一个单元格的转换异常 能获取到具体行号
        // 如果要获取头的信息 配合invokeHeadMap使用
        if (exception instanceof ExcelDataConvertException) {
            ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException)exception;
            log.error("第{}行,第{}列解析异常", excelDataConvertException.getRowIndex(),
                    excelDataConvertException.getColumnIndex());
        }
    }
    // 反馈解析完成的数据
    public List<Object> getReadData(){
        return readData;
    }
}

(四): 书写工具类(这个工具类可以直接使用,如果有需要的,直接复制就可以)

package com.elvis.easyexcel.utils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.elvis.easyexcel.listener.ObjectListener;
import com.elvis.easyexcel.model.Demo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.List;
@Slf4j
public class EasyExcelUtils {
    /**
     * @param in    读取的文件流
     * @param model 与excel文件数据对应的实体
     * @param type  通用的数据读取解析监听器
     * @return
     */
    public static List<Object> readExcelFile(InputStream in, Object model, ObjectListener type) {
        ExcelReader reader = null;
        try {
            reader = EasyExcel.read(in, model.getClass(), type).build();
            reader.readAll();
        } catch (Exception e) {
            log.error("读取excel文件错误:" + e.getMessage());
            return null;
        } finally {
            // 关闭流,读的时候会创建临时文件,不关闭到时磁盘会崩的
            if (reader != null) {
                reader.finish();
            }
        }
        return type.getReadData();
    }
    /**
     * 保存数据到excel文件
     *
     * @param data     数据(支持多个sheet写入,根据数据的个数写入对应个sheet,默认多个sheet写入的数据是同一个实体的)
     * @param savePath 保存的路径
     * @return 是否保存成功
     */
    public static Boolean writeExcelFileWithCommonEntity(List<List<Object>> data, String savePath) {
        if (CollectionUtils.isNotEmpty(data)) {
            ExcelWriter excelWriter = null;
            // 输出流放到try的小括号中,方法结束时会自动关闭流,这个是jdk1.8的新特性,对于经常忘记关流的小伙伴很友好哦
            try {
                // 获取到操作写入excel的操作对象,第二个参数是导出的excel文件的标题名对应的实体
                // 获取写入数据中的第一个元素的类类型
                excelWriter = EasyExcel.write(savePath).build();
                // 设置每个sheet的名称
                for (List<Object> objectList : data) {
                    Object item = objectList.get(0);
                    WriteSheet writeSheet = EasyExcel.writerSheet(1, "模板").head(item.getClass()).build();
                    excelWriter.write(objectList, writeSheet);
                }
            } catch (Exception e) {
                log.error("保存数据到excel错误:{}", e.getMessage());
                return false;
            } finally {
                if (excelWriter != null) {
                    excelWriter.finish();
                }
            }
        } else {
            return false;
        }
        return true;
    }
}

(五): 测试demo

package com.elvis;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.elvis.easyexcel.listener.ObjectListener;
import com.elvis.easyexcel.model.Demo;
import com.elvis.easyexcel.utils.EasyExcelUtils;
import org.json.JSONArray;
import org.junit.Test;
import javax.jws.Oneway;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class demo {
    @Test
    public void demo1() throws Exception{
        // 读取文件
        System.out.println("开始读取文件------------------------------------");
        String fileName = "E:\\newpath\\excelutils\\build\\classes\\小明.xlsx";
        InputStream in = new FileInputStream(new File(fileName));
        List<Object> objects = EasyExcelUtils.readExcelFile(in, new Demo(), new ObjectListener());
        JSONArray array = new JSONArray(objects);
        System.out.println(array);
        System.out.println("--------------------------------------------------------------");
        System.out.println("开始保存文件------------------------------------");
        String savePath = "E:\\newpath\\excelutils\\build\\classes\\保存文件测试.xlsx";
        List<List<Object>> data = new ArrayList<>();
        List<Object> item = new ArrayList<>();
        Demo abc = new Demo("abc",12,"2020-12-12 19:10:10",12.2,12l,12f,false,Short.parseShort("12"));
        item.add(abc);
        data.add(item);     EasyExcelUtils.writeExcelFileWithCommonEntity(data,savePath);
    }
}

(六): 效果展示

image.png

image.png

image.png

五: 总结

image.png


相关文章
|
2月前
|
Java Apache
EasyPOI操作Excel从零入门
我们不造轮子,只是轮子的搬运工。(其实最好是造轮子,造比别人好的轮子)开发中经常会遇到excel的处理,导入导出解析等等,java中比较流行的用poi,但是每次都要写大段工具类来搞定这事儿,此处推荐一个别人造好的轮子,EasyPOI封装了Apache的POI技术,实现了基本的Excel导入、导出从此不再为Excel操作头疼~
21 2
EasyPOI操作Excel从零入门
|
2月前
|
存储 数据处理 索引
Python操作Excel常用方法汇总
Python操作Excel常用方法汇总
38 0
|
2月前
|
easyexcel Java 测试技术
读取Excel还用POI?试试这款开源工具EasyExcel
读取Excel还用POI?试试这款开源工具EasyExcel
65 0
|
3月前
|
API
Poi 中文API文档 「40种操作 Excel文件的姿势」
Poi 中文API文档 「40种操作 Excel文件的姿势」
127 0
|
7天前
|
数据挖掘 数据库连接 数据处理
精通Excel意味着熟练掌握基础及进阶操作
精通Excel意味着熟练掌握基础及进阶操作,如数据透视表、VBA编程和自定义公式。提升效率的技巧包括善用快捷键、自动化重复任务、巧用公式与函数(如SUM和VLOOKUP)、利用数据透视表分析数据、设置条件格式、建立数据库连接、编写自定义函数、创建数据图表、使用模板和进行分组汇总。这些方法能有效提升数据分析和处理能力,优化工作效率。
17 2
|
10天前
【POI】常用excel操作方法
【POI】常用excel操作方法
12 1
|
27天前
|
JavaScript
【sgExcelGrid】自定义组件:简单模拟Excel表格拖拽、选中单元格、横行、纵列、拖拽圈选等操作
【sgExcelGrid】自定义组件:简单模拟Excel表格拖拽、选中单元格、横行、纵列、拖拽圈选等操作
【sgExcelGrid】自定义组件:简单模拟Excel表格拖拽、选中单元格、横行、纵列、拖拽圈选等操作
|
1月前
|
Python
补充python操作excel示例xlwings常用函数
补充python操作excel示例xlwings常用函数
|
1月前
|
Python
python使用tkinter库,封装操作excel为GUI程序
python使用tkinter库,封装操作excel为GUI程序
|
1月前
|
Unix API 网络架构
python操作excel示例(xlwings库)有实战例子(生成温度表)
python操作excel示例(xlwings库)有实战例子(生成温度表)