EasyExcel-读

依赖:

    <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.39</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.6</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.10</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>

编写导出的实体类:字段和顺序需要和表格一一对应:实体类的属性位置就是表格从左到右的属性
@Data@AllArgsConstructor@NoArgsConstructorpublic class Student {

/*** 学生姓名*/
private String name;
/*** 学生出生日期*/
private Date birthday;
/*** 学生性别*/
private String gender;/*** id*/
private String id;}

读取Excel文件:
/**

    • 最简单的读
    • 1. 创建excel对应的实体对象

    • 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,

    • 3. 直接读即可

*/public class ExcelTest {

private static final Logger LOGGER = LoggerFactory.getLogger(ExcelTest.class);/*** 工作簿:bookwork* 工作表:sheet*/
@Test
public void test01() {// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去//获得工作簿对象/*EasyExcel.read()参数:pathName         文件路径;"d:\\学员信息表.xlsx"head          每行数据对应的实体;Student.classreadListener  读监听器,每读一样就会调用一次该监听器的invoke方法*/ExcelReaderBuilder excelReaderBuilder = EasyExcel.read("学员信息表.xlsx", Student.class, new StudentReadListener());//获取一个工作表ExcelReaderSheetBuilder sheet = excelReaderBuilder.sheet();//读取工作表内容:sheet方法参数:工作表的顺序号(从0开始)或者工作表的名字,不传默认为0sheet.doRead();}}

读取Excel的监听器,用于处理读取产生的数据
/**

  • 在读的时候,每读一行,就会自动调用监听器的invoke方法,并且把读取的内容自动封装成了一个对象

  • @author JUNSHI 405773808@qq.com

  • @create 2020-08-27 22:55
    */public class StudentReadListener extends AnalysisEventListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(StudentReadListener.class);

    /**

    • 每读一样会自动调用这个方法
    • @param student 读取的内容自动封装成了一个对象
    • @param context
      */
      @Override
      public void invoke(Student student, AnalysisContext context) {
      LOGGER.info(“解析到一条数据:{}”, JSON.toJSONString(student));
      System.out.println("student = " + student);
      }
      // 全部读完之后,会调用该方法
      @Override
      public void doAfterAllAnalysed(AnalysisContext context) {

    }}
    运行结果:
    2020-08-28 19:47:54.165 = [main] = [INFO ] = c.c.l.StudentReadListener - [invoke,26] - 解析到一条数据:{“birthday”:1584288000000,“gender”:“男”,“name”:“学号00”}student = Student(name=学号00, birthday=Mon Mar 16 00:00:00 CST 2020, gender=男, id=null)2020-08-28 19:47:54.173 = [main] = [INFO ] = c.c.l.StudentReadListener - [invoke,26] - 解析到一条数据:{“birthday”:1584288000000,“gender”:“男”,“name”:“学号01”}student = Student(name=学号01, birthday=Mon Mar 16 00:00:00 CST 2020, gender=男, id=null)2020-08-28 19:47:54.175 = [main] = [INFO ] = c.c.l.StudentReadListener - [invoke,26] - 解析到一条数据:{“birthday”:1584288000000,“gender”:“男”,“name”:“学号02”}student = Student(name=学号02, birthday=Mon Mar 16 00:00:00 CST 2020, gender=男, id=null)2020-08-28 19:47:54.176 = [main] = [INFO ] = c.c.l.StudentReadListener - [invoke,26] - 解析到一条数据:{“birthday”:1584288000000,“gender”:“男”,“name”:“学号03”}student = Student(name=学号03, birthday=Mon Mar 16 00:00:00 CST 2020, gender=男, id=null)2020-08-28 19:47:54.177 = [main] = [INFO ] = c.c.l.StudentReadListener - [invoke,26] - 解析到一条数据:{“birthday”:1584288000000,“gender”:“男”,“name”:“学号04”}student = Student(name=学号04, birthday=Mon Mar 16 00:00:00 CST 2020, gender=男, id=null)2020-08-28 19:47:54.178 = [main] = [INFO ] = c.c.l.StudentReadListener - [invoke,26] - 解析到一条数据:{“birthday”:1584288000000,“gender”:“男”,“name”:“学号05”}student = Student(name=学号05, birthday=Mon Mar 16 00:00:00 CST 2020, gender=男, id=null)2020-08-28 19:47:54.179 = [main] = [INFO ] = c.c.l.StudentReadListener - [invoke,26] - 解析到一条数据:{“birthday”:1584288000000,“gender”:“男”,“name”:“学号06”}student = Student(name=学号06, birthday=Mon Mar 16 00:00:00 CST 2020, gender=男, id=null)2020-08-28 19:47:54.181 = [main] = [INFO ] = c.c.l.StudentReadListener - [invoke,26] - 解析到一条数据:{“birthday”:1584288000000,“gender”:“男”,“name”:“学号07”}student = Student(name=学号07, birthday=Mon Mar 16 00:00:00 CST 2020, gender=男, id=null)2020-08-28 19:47:54.182 = [main] = [INFO ] = c.c.l.StudentReadListener - [invoke,26] - 解析到一条数据:{“birthday”:1584288000000,“gender”:“男”,“name”:“学号08”}student = Student(name=学号08, birthday=Mon Mar 16 00:00:00 CST 2020, gender=男, id=null)2020-08-28 19:47:54.184 = [main] = [INFO ] = c.c.l.StudentReadListener - [invoke,26] - 解析到一条数据:{“birthday”:1584288000000,“gender”:“男”,“name”:“学号09”}student = Student(name=学号09, birthday=Mon Mar 16 00:00:00 CST 2020, gender=男, id=null)
    EasyExcel-写

    /**

    • 需求:单实体导出
    • 导出多个学生对象到Excel表格
    • 包含如下列:姓名、性别、出生日期
    • 写不需要监听器
      /
      @Test
      public void test02(){
      /

      • 工作簿对象
      • @param pathName 文件路径名称
      • @param head 封装写出的数据实体的类型
      • @return 写出工作表对象
        /
        ExcelWriterBuilder write = EasyExcel.write(“学员信息表-write.xlsx”, Student.class);
        //工作表对象
        ExcelWriterSheetBuilder sheet = write.sheet();
        //需要写出的数据:
        List students = initData();
        //写出
        sheet.doWrite(students);
        }
        /
        *
    • 初始好数据
      */
      private static List initData() {
      ArrayList students = new ArrayList();
      Student data = new Student();
      for (int i = 0; i < 10; i++) {
      data.setName(“学号0” + i);
      data.setBirthday(new Date());
      data.setGender(“男”);
      students.add(data);
      }
      return students;
      }
      实体类:
      @Data@AllArgsConstructor@NoArgsConstructor//@ColumnWidth(20) //列宽//@HeadRowHeight(30) //列头行高//@ContentRowHeight 内容行高public class Student {

    /**

    • id
      /
      @ExcelProperty(value = “学生编号”)
      private String id;
      /
      *
    • 学生姓名
      */
      //@ExcelProperty(value = “学生姓名”,index = 3) index是表格的索引地址
      private String name;

    /**

    • 学生出生日期
      /
      //@ColumnWidth(20)
      //@DateTimeFormat(“yyyy-MM-dd”) 设置日期格式
      @ExcelProperty(value = “出生日期”, index = 1)
      @ColumnWidth(20) //列宽
      private Date birthday;
      /
      *
    • 学生性别
      */
      private String gender;

    /**

    • 忽略这个字段
      */
      @ExcelIgnore
      private String ignore;}
      EasyExcel-web

文件上传:依赖

<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.39</version>
</dependency><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.6</version>
</dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.10</version>
</dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version>
</dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.5</version>
</dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions>
</dependency></dependencies>

student实体类:
@Data@AllArgsConstructor@NoArgsConstructorpublic class Student {

/*** id*/
@ExcelIgnore
private String id;
/*** 学生姓名*/
private String name;/*** 学生出生日期*/
private Date birthday;
/*** 学生性别*/
private String gender;}

service:

@Service(“studentService”)public class StudentServiceImpl implements StudentService {

private int i = 0;@Override
public void save(List<Student> students) {for (Student student : students) {System.out.println(i++ + "学生" + "号:" + student);}
}}

webListener:

@Component@Scope(“prototype”)public class WebStudentReadListener extends AnalysisEventListener {

private static final Logger LOGGER = LoggerFactory.getLogger(WebStudentReadListener.class);@Autowired
private StudentService studentService;private final int BATCH_SAVE_NUM = 5;
ArrayList<Student> students = new ArrayList<>();@Override
public void invoke(Student student, AnalysisContext context) {LOGGER.info("解析到一条数据:{}", JSON.toJSONString(student));students.add(student);if (students.size() % BATCH_SAVE_NUM == 0) {studentService.save(students);students.clear();}}@Override
public void doAfterAllAnalysed(AnalysisContext context) {}}

Controller:

@Controller@RestControllerpublic class WebUploadAndDownload {

@Autowired
private WebStudentReadListener webStudentReadListener;/*** 文件上传* 1. 编写excel中每一行对应的实体类* 2. 由于默认异步读取excel,所以需要逐行读取的回调监听器* 3. 开始读取Excel*/
@PostMapping("upload")
public String upload(MultipartFile multipartFile) throws IOException{ExcelReaderBuilder read = EasyExcel.read(multipartFile.getInputStream(), Student.class, webStudentReadListener);read.sheet().doRead();return "success";
}}

文件下载:controller:
@GetMapping(“download”)public void download(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");ExcelWriterBuilder write = EasyExcel.write(response.getOutputStream(), Student.class);
write.sheet("模板").doWrite(initData());}/**
  • 初始好数据
    */private static List initData() {
    ArrayList students = new ArrayList();
    Student data = new Student();
    for (int i = 0; i < 10; i++) {
    data.setName(“学号0” + i);
    data.setBirthday(new Date());
    data.setGender(“男”);
    students.add(data);
    }
    return students;}
    Excel填充

1、填充一组数据
1.1 准备模板

Excel表格中用{} 来表示包裹要填充的变量,如果单元格文本中本来就有{、}左右大括号,需要在括号前面使用斜杠转义\{、\}。代码中被填充数据的实体对象的成员变量名或被填充map集合的key需要和Excel中被{}包裹的变量名称一致。

1.2 封装数据

编写封装填充数据的类或选用Map
/**

  • 使用实体类封装填充数据

  • 实体中成员变量名称需要和Excel表各种{}包裹的变量名匹配
    */@Datapublic class FillData {

    private String name;
    private int age;}
    /**

  • 生成多组数据代码

  • /
    private static List initFillData() {
    ArrayList fillDatas = new ArrayList();
    for (int i = 0; i < 10; i++) {
    FillData fillData = new FillData();
    fillData.setName(“0” + i);
    fillData.setAge(10 + i);
    fillDatas.add(fillData);
    }
    return fillDatas;
    }
    1.3 填充

准备数据并填充到文件
public static void main(String[] args) {
// 加载模板
InputStream templateFile = FillData.class.getClassLoader().getResourceAsStream(
“fill_data_template1” +
“.xlsx”);

// 写入文件
String targetFileName = "单组数据填充.xlsx";// 准备对象数据填充
FillData fillData = new FillData();
fillData.setName("");
fillData.setAge(10);// 生成工作簿对象
ExcelWriterBuilder workBookWriter = EasyExcel.write(targetFileName).withTemplate(templateFile);// 获取工作表并填充
//workBookWriter.sheet().doFill(fillData);// 使用Map数据填充
HashMap<String, String> mapFillData = new HashMap<>();
mapFillData.put("name", "Map");
mapFillData.put("age", "11");// 获取第一个工作表填充并自动关闭流
workBookWriter.sheet().doFill(mapFillData);}

1.4 效果

2、填充多组数据
2.1 准备模板

Excel表格中用{.}来表示包裹要填充的变量,如果单元格文本中本来就有{、}左右大括号,需要在括号前面使用斜杠转义{ 、}。

代码中被填充数据的实体对象的成员变量名或被填充map集合的key需要和Excel中被{}包裹的变量名称一致。

2.2 封装数据

编写封装填充数据的类或选用Map
2.3 填充

准备数据并填充到文件

public static void main(String[] args) {
// 加载模板
InputStream templateFile = FillData.class.getClassLoader().getResourceAsStream(
“fill_data_template2.xlsx”);

// 写入文件
String targetFileName = "多组数据填充.xlsx";List<FillData> fillDatas = initData();// 生成工作簿对象
ExcelWriterBuilder workBookWriter =EasyExcel.write(targetFileName).withTemplate(templateFile);// 获取第一个工作表填充并自动关闭流
workBookWriter.sheet().doFill(fillDatas);}

3、组合填充

3.1 准备模板

即有多组数据填充,又有单一数据填充,为了避免两者数据出现冲突覆盖的情况,在多组填充时需要通过FillConfig对象设置换行。
3.2 封装数据

编写封装填充数据的类或选用Map
3.3 填充

准备数据并填充到文件

public static void main(String[] args) {

// 加载模板
InputStream templateFile = FillData.class.getClassLoader().getResourceAsStream("fill_data_template3.xlsx");// 目标文件
String targetFileName = "组合数据填充.xlsx";List<FillData> fillDatas = initData();// 生成工作簿对象
ExcelWriter excelWriter = EasyExcel.write(targetFileName).withTemplate(templateFile).build();// 生成工作表对象
WriteSheet writeSheet = EasyExcel.writerSheet().build();// 组合填充时,因为多组填充的数据量不确定,需要在多组填充完之后另起一行
FillConfig fillConfig = FillConfig.builder().forceNewRow(true).build();// 填充并换行
excelWriter.fill(fillDatas, fillConfig, writeSheet);HashMap<String, String> otherData = new HashMap<>();
otherData.put("date", "2020-03-14");
otherData.put("total", "100");
excelWriter.fill(otherData, writeSheet);// 关闭
excelWriter.finish();}

4、水平填充

4.1 准备模板

水平填充和多组填充模板一样,不一样的地方在于,填充时需要通过FillConfig对象设置水平填充。
4.2 封装数据

编写封装填充数据的类或选用Map
4.3 填充

准备数据并填充到文件

public static void main(String[] args) {

// 加载模板
InputStream templateFile = FillData.class.getClassLoader().getResourceAsStream("fill_data_template4.xlsx");// 写入文件
String targetFileName = "easyExcelDemo\\水平数据填充.xlsx";List<FillData> fillDatas = initData();// 生成工作簿对象
ExcelWriter excelWriter = EasyExcel.write(targetFileName).withTemplate(templateFile).build();// 生成工作表对象
WriteSheet writeSheet = EasyExcel.writerSheet().build();// 组合填充时,因为多组填充的数据量不确定,需要在多组填充完之后另起一行
FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();// 填充
excelWriter.fill(fillDatas, fillConfig, writeSheet);HashMap<String, String> otherData = new HashMap<>();
otherData.put("date", "2020-03-14");
otherData.put("total", "100");
excelWriter.fill(otherData, writeSheet);// 关闭
excelWriter.finish();}

5、 注意事项
为了节省内存,所以没有采用把整个文档在内存中组织好之后再整体写入到文件的做法,而是采用的是一行一行写入的方式,不能实现删除和移动行,也不支持备注写入。多组数据写入的时候,如果需要新增行,只能在最后一行增加,不能在中间位置添加。

6、填充综合练习
见report_template.xlsx

/**

  • reprot综合练习
    */@Testpublic void test06() {

    InputStream templateInputStream = this.getClass().getClassLoader().getResourceAsStream(
    “report_template.xlsx”);

    // 目标文件
    String targetFile = “模板写入6-report.xlsx”;

    // 写入workbook对象

    ExcelWriter workBook =
    EasyExcel.write(targetFile, FillData.class).withTemplate(templateInputStream).build();

    WriteSheet sheet = EasyExcel.writerSheet().build();

    // 填充配置,开启组合填充换行
    //FillConfig fillConfig = FillConfig.builder().forceNewRow(true).build();

    // ****** 准备数据 *******
    // 日期
    HashMap<String, String> dateMap = new HashMap<String, String>();
    dateMap.put(“date”, “2020-03-16”);

    // 总会员数
    HashMap<String, String> totalCountMap = new HashMap<String, String>();
    dateMap.put(“totalCount”, “1000”);

    // 新增员数
    HashMap<String, String> increaseCountMap = new HashMap<String, String>();
    dateMap.put(“increaseCount”, “100”);

    // 本周新增会员数
    HashMap<String, String> increaseCountWeekMap = new HashMap<String, String>();
    dateMap.put(“increaseCountWeek”, “50”);

    // 本月新增会员数
    HashMap<String, String> increaseCountMonthMap = new HashMap<String, String>();
    dateMap.put(“increaseCountMonth”, “100”);

    // 新增会员数据
    List students = initData();
    // **** 准备数据结束****

    // 写入统计数据
    workBook.fill(dateMap, sheet);
    workBook.fill(totalCountMap, sheet);
    workBook.fill(increaseCountMap, sheet);
    workBook.fill(increaseCountWeekMap, sheet);
    workBook.fill(increaseCountMonthMap, sheet);
    // 写入新增会员
    workBook.fill(students, sheet);
    workBook.finish();}
    EasyExcel常用API

1、常用类

EasyExcel 入口类,用于构建各种对象、开始各种操作;

ExcelReaderBuilder 构建出一个ReadWorkbook对象,即一个工作簿对象,对应的是一个Excel文件;

ExcelWriterBuilder 构建出一个WriteWorkbook对象,即一个工作簿对象,对应的是一个Excel文件;

ExcelReaderSheetBuilder 构建出一个ReadSheet对象,即一个工作表的对象,对应的Excel中的每个sheet,一个工作簿可以有多个工作表;

ExcelWriterSheetBuilder 构建出一WriteSheet对象,即一个工作表的对象,对应的Excel中的每个sheet,一个工作簿可以有多个工作表;

ReadListener 在每一行读取完毕后都会调用ReadListener来处理数据,我们可以把调用service的代码可以写在其invoke方法内部;

WriteHandler 在每一个操作包括创建单元格、创建表格等都会调用WriteHandler来处理数据,对使用者透明不可见;

所有配置都是继承的 Workbook的配置会被Sheet继承。所以在用EasyExcel设置参数的时候,在EasyExcel…sheet()方法之前作用域是整个workBook的所有sheet,之后针对单个sheet。

EasyExcel注解

2、读取时的注解
@ExcelProperty
使用位置:标准作用在成员变量上 把实体类和Excel关联起来

可选属性:

属性名 含义 说明
index 对应Excel表中的列数 默认-1,建议指定时从0开始
value 对应Excel表中的列头
converter 成员变量转换器 自定义转换器需要实Converter接口
使用效果:index属性可以指定当前字段对应excel中的哪一列,可以根据列名value去匹配,也可以不写。

如果不使用@ExcelProperty注解,成员变量从上到下的顺序,对应表格中从左到右的顺序;

**使用建议:**要么全部不写,要么全部用index,要么全部用value去匹配,尽量不要三个混着用。

代码演示:

// 1. 修改成员变量顺序读取Excel表格// 2. 修改index属性值读取Excel表格// 3. 修改value属性值读取Excel表格
@ExcelIgnore
标注在成员变量上,默认所有字段都会和excel去匹配,加了这个注解会忽略该字段

代码演示:

// 4. 忽略id成员变量值读取Excel表格
@DateTimeFormat
标注在成员变量上,日期转换,代码中用String类型的成员变量去接收excel中日期格式的数据会调用这个注解。里面的value参照java.text.SimpleDateFormat

// 5. 按照指定的格式写入Excel内容
@NumberFormat
标注在成员变量上,数字转换,代码中用String类型的成员变量去接收excel数字格式的数据会调用这个注解。里面的value参照java.text.DecimalFormat

@ExcelIgnoreUnannotated
标注在类上。

不标注该注解时,默认类中所有成员变量都会参与读写,无论是否在成员变量上加了@ExcelProperty 的注解。

标注该注解后,类中的成员变量如果没有标注@ExcelProperty 注解将不会参与读写。

3、 读取时通用参数

ReadWorkbook,ReadSheet 都会有的参数,如果为空,默认使用上级。

converter 转换器,默认加载了很多转换器。也可以自定义。

readListener 监听器,在读取数据的过程中会不断的调用监听器。

headRowNumber 指定需要读表格的 列头行数。默认有一行头,也就是认为第二行开始起为数据。

head 与clazz二选一。读取文件头对应的列表,会根据列表匹配数据。建议使用class,就是文件中每一行数据对应的代码中的实体类型。

clazz 与head二选一。读取文件的头对应的class,也可以使用注解。如果两个都不指定,则会读取全部数据。

autoTrim 字符串、表头等数据自动trim

password 读的时候是否需要使用密码

4、ReadWorkbook(工作簿对象)参数

excelType 当前excel的类型,读取时会自动判断,无需设置。

inputStream 与file二选一。建议使用file。

file 与inputStream二选一。读取文件的文件。

autoCloseStream 自动关闭流。

readCache 默认小于5M用 内存,超过5M会使用 EhCache,不建议使用这个参数。

useDefaultListener @since 2.1.4 默认会加入ModelBuildEventListener 来帮忙转换成传入class的对象,设置成false后将不会协助转换对象,自定义的监听器会接收到Map<Integer,CellData>对象,如果还想继续接听到class对象,请调用readListener方法,加入自定义的beforeListener、 ModelBuildEventListener、 自定义的afterListener即可。

5、ReadSheet(工作表对象)参数

sheetNo 需要读取Sheet的编号,建议使用这个来指定读取哪个Sheet

sheetName 根据名字去匹配Sheet,excel 2003不支持根据名字去匹配

6、写入时的注解注解

@ExcelProperty
使用位置:标准作用在成员变量上

可选属性:

属性名 含义 说明
index 对应Excel表中的列数 默认-1,指定时建议从0开始
value 对应Excel表中的列头
converter 成员变量转换器 自定义转换器需要实Converter接口
使用效果:index 指定写到第几列,如果不指定则根据成员变量位置排序;

value指定写入的列头,如果不指定则使用成员变量的名字作为列头;

如果要设置复杂的头,可以为value指定多个值。

代码演示:

// 5. 为《学员表.xlsx》文件中学生信息设置一个统一的表头“学员信息表”

其他注解

基本和读取时一致

@ContentRowHeight() 标注在类上或属性上,指定内容行高

@HeadRowHeight() 标注在类上或属性上,指定列头行高

@ColumnWidth() 标注在类上或属性上,指定列宽

ExcelIgnore` 默认所有字段都会写入excel,这个注解会忽略这个字段

DateTimeFormat 日期转换,将Date写到excel会调用这个注解。里面的value参照java.text.SimpleDateFormat

NumberFormat 数字转换,用Number写excel会调用这个注解。里面的value参照java.text.DecimalFormat

ExcelIgnoreUnannotated 默认不加 ExcelProperty 的注解的都会参与读写,加了不会参与

7、写入时通用参数

WriteWorkbook、WriteSheet都会有的参数,如果为空,默认使用上级。

converter 转换器,默认加载了很多转换器。也可以自定义。

writeHandler 写的处理器。可以实现WorkbookWriteHandler,SheetWriteHandler,RowWriteHandler,CellWriteHandler,在写入excel的不同阶段会调用,对使用者透明不可见。

relativeHeadRowIndex 距离多少行后开始。也就是开头空几行

needHead 是否导出头

head 与clazz二选一。写入文件的头列表,建议使用class。

clazz 与head二选一。写入文件的头对应的class,也可以使用注解。

autoTrim 字符串、表头等数据自动trim

8、WriteWorkbook(工作簿对象)参数

excelType 当前excel的类型,默认为xlsx

outputStream 与file二选一。写入文件的流

file 与outputStream二选一。写入的文件

templateInputStream 模板的文件流

templateFile 模板文件

autoCloseStream 自动关闭流。

password 写的时候是否需要使用密码

useDefaultStyle 写的时候是否是使用默认头

9、WriteSheet(工作表对象)参数

sheetNo 需要写入的编号。默认0

sheetName 需要些的Sheet名称,默认同sheetNo

Java 开发必备,EasyExcel 操作详解!相关推荐

  1. Java开发常见面试题详解(LockSupport,AQS,Spring循环依赖,Redis)_3

    Java开发常见面试题详解(LockSupport,AQS,Spring循环依赖,Redis)_3 总览 问题 详解 String.intern()的作用 link LeetCode的Two Sum题 ...

  2. Java开发常见面试题详解(JVM)_2

    Java开发常见面试题详解(JVM)_2 JVM 问题 详解 JVM垃圾回收的时候如何确定垃圾?是否知道什么是GC Roots link 你说你做过JVM调优和参数配置,请问如何盘点查看JVM系统默认 ...

  3. java对文件的操作详解_Java 对 Properties 文件的操作详解及简单实例

    Java 对 Properties 文件的操作详解及简单实例 发布于 2020-8-7| 复制链接 摘记: Java 对 Properties 文件的操作简介在 Java 中,我们常用 java.ut ...

  4. Java开发常见面试题详解(并发,JVM)

    预览 并发 问题 详解 请谈谈你对volatile的理解 link CAS你知道吗? link 原子类Atomiclnteger的ABA问题谈谈?原子更新引用知道吗? link 我们知道ArrayLi ...

  5. Java开发常见面试题详解(LockSupport,AQS,Spring循环依赖,Redis)

    总览 问题 详解 String.intern()的作用 link LeetCode的Two Sum题 link 什么是可重入锁? link 谈谈LockSupport link 谈谈AQS link ...

  6. Java 开发神器 Lombok 使用详解(转载)

    文章目录 什么是Lombok Lombok的安装 Lombok的使用 @Data @Setter @Getter @Log4j @AllArgsConstructor @NoArgsConstruct ...

  7. 怎样配置Java开发环境?步骤详解

    配置Java开发环境 先了解三个概念 JVM JVM(Java Virtual Machine,Java虚拟机)是一种具备计算机核心配置的计算环境,在实际的计算机上虚拟计算机各种运算功能,有自己完善的 ...

  8. java对文件的操作详解,java对各种文件的操作详解

    java中提供了io类库,可以轻松的用java实现对文件的各种操作.下面就来说一下如何用java来实现这些操作. 新建目录 //String URL = request.getRequestURI() ...

  9. Java开发环境配置过程详解(包括IDEA配置Java)

    Java开发环境配置 一.JDK下载安装 1. 官网下载JDK 2. 本地安装JDK 3. 配置环境变量 4. 验证是否安装成功 二.IDEA进行Java开发 1. 创建Java项目 2. 程序测试 ...

  10. Mybatis零基础教程,Java访问数据库核心操作,详解Spring-boot整合Mybatis持久层!

    1.前言 持久层是JavaEE中访问数据库的核心操作,Mybatis是一款优秀的持久层框架,诞生于2010年,2013年迁移至Github.它支持定制化 SQL.存储过程以及高级映射.MyBatis ...

最新文章

  1. 微软浏览器适配问题前端_「图」微软新贡献:修复Chromium浏览器的奇怪触控板手势问题...
  2. 【怎样写代码】参数化类型 -- 泛型(一):泛型概述
  3. grep -v、-e、-E
  4. 一个自定义类型的运算符重载的例子
  5. 如何对依赖ZooKeeper的代码写单元测试
  6. 7-7 念数字 (10 分)
  7. linux模块导出符号 EXPORT_SYMBOL_GPLEXPORT_SYMBOL(转)
  8. 获取日志的等级_进阶之路:Java 日志框架全画传(中)
  9. Windows7系统运行hadoop报Failed to locate the winutils binary in the hadoop binary path错误
  10. shared_ptr and
  11. 转:Android应用Icon大小在不同分辨率下定义
  12. FISCO BCOS 区块最大最长交易执行时间
  13. ASP.NET 2.0中合并 GridView 的表头单元格
  14. MacOS Aria2GUI配置
  15. 【自然语言处理】【多模态】Product1M:基于跨模态预训练的弱监督实例级产品检索
  16. 网页星号点号密码查看最简方法
  17. 页面导航-声明式/编程式导航
  18. arm-linux平台的锐捷认证工具Mentohust移植
  19. python使用百度OCR接口识别图片文字
  20. uni-app跨域解决方案

热门文章

  1. 补发《超级迷宫》站立会议八
  2. [置顶] ios 360度旋转效果demo
  3. asp.net的优化 服务器控件背后友好的Html和JS
  4. [学习笔记]--ASP.Net MVC
  5. Spring boot中的Http压缩配置
  6. 微信小程序启动过程分析
  7. 1996: [Hnoi2010]chorus 合唱队
  8. expect - linux远程执行命令
  9. 【原创】自己动手写控件----XSmartNote控件
  10. 利用反射生成SQL语句