当前位置: 首页 > news >正文

easyexcel读和写excel

请直接看原文:

JAVA使用easyexcel操作Excel-CSDN博客

-------------------------------------------------------------------------------------------------------------------------------- 

之前写过一篇《JAVA操作Excel》,介绍了jxlpoi读写Excel的实现,今天为大家介绍一下使用easyexcel对Excel进行读写,项目主页地址:GitHub - alibaba/easyexcel: 快速、简洁、解决大文件内存溢出的java处理Excel工具

作者对easyexcel的介绍是:

Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到KB级别,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。在上层做了模型转换的封装,让使用者更加简单方便

使用easyexcel,首先我们需要添加maven依赖:

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>1.0.1</version>
</dependency>

一.写入excle无表头

首先,我们先来看看如何写Excel,写入Excel,我们可以通过com.alibaba.excel.ExcelWriter类实现,下面我们来看一下最简单的无表头的实现

package test;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;import org.junit.Test;import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;public class ExcelWriteTest {/*** 每行数据是List<String>无表头* * @throws IOException*/@Testpublic void writeWithoutHead() throws IOException {try (OutputStream out = new FileOutputStream("withoutHead.xlsx");) {ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX, false);Sheet sheet1 = new Sheet(1, 0);sheet1.setSheetName("sheet1");List<List<String>> data = new ArrayList<>();for (int i = 0; i < 100; i++) {List<String> item = new ArrayList<>();item.add("item0" + i);item.add("item1" + i);item.add("item2" + i);data.add(item);}writer.write0(data, sheet1);writer.finish();}}
}

生成的Excel样式如下:
这里写图片描述

二.写入excle有表头

很多时候,我们在生成Excel的时候都是需要添加表头的,使用easyexcel可以很容易的实现,我们可以对上面的例子进行简单的改造,为其添加表头

package test;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;import org.junit.Test;import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.Table;
import com.alibaba.excel.support.ExcelTypeEnum;public class ExcelWriteTest {@Testpublic void writeWithoutHead() throws IOException {try (OutputStream out = new FileOutputStream("withHead.xlsx");) {ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);Sheet sheet1 = new Sheet(1, 0);sheet1.setSheetName("sheet1");List<List<String>> data = new ArrayList<>();for (int i = 0; i < 100; i++) {List<String> item = new ArrayList<>();item.add("item0" + i);item.add("item1" + i);item.add("item2" + i);data.add(item);}List<List<String>> head = new ArrayList<List<String>>();List<String> headCoulumn1 = new ArrayList<String>();List<String> headCoulumn2 = new ArrayList<String>();List<String> headCoulumn3 = new ArrayList<String>();headCoulumn1.add("第一列");headCoulumn2.add("第二列");headCoulumn3.add("第三列");head.add(headCoulumn1);head.add(headCoulumn2);head.add(headCoulumn3);Table table = new Table(1);table.setHead(head);writer.write0(data, sheet1, table);writer.finish();}}
}

效果如下:

这里写图片描述

三.实体类写入excle有表头 

除了上面添加表头的方式,我们还可以使用实体类,为其添加com.alibaba.excel.annotation.ExcelProperty注解来生成表头,实体类数据作为Excel数据

package test;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;import org.junit.Test;import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.Table;
import com.alibaba.excel.support.ExcelTypeEnum;public class ExcelWriteTest {@Testpublic void writeWithHead() throws IOException {try (OutputStream out = new FileOutputStream("withHead.xlsx");) {ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);Sheet sheet1 = new Sheet(1, 0, ExcelPropertyIndexModel.class);sheet1.setSheetName("sheet1");List<ExcelPropertyIndexModel> data = new ArrayList<>();for (int i = 0; i < 100; i++) {ExcelPropertyIndexModel item = new ExcelPropertyIndexModel();item.name = "name" + i;item.age = "age" + i;item.email = "email" + i;item.address = "address" + i;item.sax = "sax" + i;item.heigh = "heigh" + i;item.last = "last" + i;data.add(item);}writer.write(data, sheet1);writer.finish();}}public static class ExcelPropertyIndexModel extends BaseRowModel {@ExcelProperty(value = "姓名", index = 0)private String name;@ExcelProperty(value = "年龄", index = 1)private String age;@ExcelProperty(value = "邮箱", index = 2)private String email;@ExcelProperty(value = "地址", index = 3)private String address;@ExcelProperty(value = "性别", index = 4)private String sax;@ExcelProperty(value = "高度", index = 5)private String heigh;@ExcelProperty(value = "备注", index = 6)private String last;}
}

效果如下:
这里写图片描述

四.实体类写入excle有多行表头

如果单行表头表头还不满足需求,没关系,还可以使用多行复杂的表头

package test;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;import org.junit.Test;import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.Table;
import com.alibaba.excel.support.ExcelTypeEnum;public class ExcelWriteTest {@Testpublic void writeWithMultiHead() throws IOException {try (OutputStream out = new FileOutputStream("withMultiHead.xlsx");) {ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);Sheet sheet1 = new Sheet(1, 0, MultiLineHeadExcelModel.class);sheet1.setSheetName("sheet1");List<MultiLineHeadExcelModel> data = new ArrayList<>();for (int i = 0; i < 100; i++) {MultiLineHeadExcelModel item = new MultiLineHeadExcelModel();item.p1 = "p1" + i;item.p2 = "p2" + i;item.p3 = "p3" + i;item.p4 = "p4" + i;item.p5 = "p5" + i;item.p6 = "p6" + i;item.p7 = "p7" + i;item.p8 = "p8" + i;item.p9 = "p9" + i;data.add(item);}writer.write(data, sheet1);writer.finish();}}public static class MultiLineHeadExcelModel extends BaseRowModel {@ExcelProperty(value = { "表头1", "表头1", "表头31" }, index = 0)private String p1;@ExcelProperty(value = { "表头1", "表头1", "表头32" }, index = 1)private String p2;@ExcelProperty(value = { "表头3", "表头3", "表头3" }, index = 2)private String p3;@ExcelProperty(value = { "表头4", "表头4", "表头4" }, index = 3)private String p4;@ExcelProperty(value = { "表头5", "表头51", "表头52" }, index = 4)private String p5;@ExcelProperty(value = { "表头6", "表头61", "表头611" }, index = 5)private String p6;@ExcelProperty(value = { "表头6", "表头61", "表头612" }, index = 6)private String p7;@ExcelProperty(value = { "表头6", "表头62", "表头621" }, index = 7)private String p8;@ExcelProperty(value = { "表头6", "表头62", "表头622" }, index = 8)private String p9;}
}

效果如下:
这里写图片描述

五.写入excle一个sheet有多个表

怎么样,这些已经基本满足我们的日常需求了,easyexcel不仅支持上述几种形式,还支持在一个sheet中添加多个表

package test;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;import org.junit.Test;import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.Table;
import com.alibaba.excel.support.ExcelTypeEnum;public class ExcelWriteTest {@Testpublic void writeWithMultiTable() throws IOException {try (OutputStream out = new FileOutputStream("withMultiTable.xlsx");) {ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);Sheet sheet1 = new Sheet(1, 0);sheet1.setSheetName("sheet1");// 数据全是List<String> 无模型映射关系Table table1 = new Table(1);List<List<String>> data1 = new ArrayList<>();for (int i = 0; i < 5; i++) {List<String> item = new ArrayList<>();item.add("item0" + i);item.add("item1" + i);item.add("item2" + i);data1.add(item);}writer.write0(data1, sheet1, table1);// 模型上有表头的注解Table table2 = new Table(2);table2.setClazz(MultiLineHeadExcelModel.class);List<MultiLineHeadExcelModel> data2 = new ArrayList<>();for (int i = 0; i < 5; i++) {MultiLineHeadExcelModel item = new MultiLineHeadExcelModel();item.p1 = "p1" + i;item.p2 = "p2" + i;item.p3 = "p3" + i;item.p4 = "p4" + i;item.p5 = "p5" + i;item.p6 = "p6" + i;item.p7 = "p7" + i;item.p8 = "p8" + i;item.p9 = "p9" + i;data2.add(item);}writer.write(data2, sheet1, table2);// 模型上没有注解,表头数据动态传入,此情况下模型field顺序与excel现实顺序一致List<List<String>> head = new ArrayList<List<String>>();List<String> headCoulumn1 = new ArrayList<String>();List<String> headCoulumn2 = new ArrayList<String>();List<String> headCoulumn3 = new ArrayList<String>();headCoulumn1.add("第一列");headCoulumn2.add("第二列");headCoulumn3.add("第三列");head.add(headCoulumn1);head.add(headCoulumn2);head.add(headCoulumn3);Table table3 = new Table(3);table3.setHead(head);writer.write0(data1, sheet1, table3);writer.finish();}}public static class MultiLineHeadExcelModel extends BaseRowModel {@ExcelProperty(value = { "表头1", "表头1", "表头31" }, index = 0)private String p1;@ExcelProperty(value = { "表头1", "表头1", "表头32" }, index = 1)private String p2;@ExcelProperty(value = { "表头3", "表头3", "表头3" }, index = 2)private String p3;@ExcelProperty(value = { "表头4", "表头4", "表头4" }, index = 3)private String p4;@ExcelProperty(value = { "表头5", "表头51", "表头52" }, index = 4)private String p5;@ExcelProperty(value = { "表头6", "表头61", "表头611" }, index = 5)private String p6;@ExcelProperty(value = { "表头6", "表头61", "表头612" }, index = 6)private String p7;@ExcelProperty(value = { "表头6", "表头62", "表头621" }, index = 7)private String p8;@ExcelProperty(value = { "表头6", "表头62", "表头622" }, index = 8)private String p9;}
}

效果如下:
这里写图片描述

如果表头的样式不满足我们的需求,需要调整,我们可以使用com.alibaba.excel.metadata.TableStyle定义我们需要的样式,然后调用table对象的setTableStyle方法进行设置。

六.读取excel内容(不建议用下面的方法,自己百度一下easyexcel读的简单示例方法就够用了)

好了,到这里写入excel就基本介绍完了,下面我们就来看看如何读取excel,实际上现在的这个版本(1.0.1)在读取的时候是有BUG的,读取03版的.xls格式的excel正常,但是读取07版的.xlsx版的excel就会出异常,原因是在解析的时候sheet临时文件路径拼装有误,下面是我针对这个版本修复后的实现,大家可以替换掉原包中的实现

package com.alibaba.excel.read;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;import javax.xml.parsers.ParserConfigurationException;import com.alibaba.excel.read.v07.RowHandler;
import com.alibaba.excel.read.v07.XmlParserFactory;
import com.alibaba.excel.read.v07.XMLTempFile;
import com.alibaba.excel.read.context.AnalysisContext;
import com.alibaba.excel.read.exception.ExcelAnalysisException;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.util.FileUtil;import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;public class SaxAnalyserV07 extends BaseSaxAnalyser {private SharedStringsTable sharedStringsTable;private List<String> sharedStringList = new LinkedList<String>();private List<SheetSource> sheetSourceList = new ArrayList<SheetSource>();private boolean use1904WindowDate = false;private final String path;private File tmpFile;private String workBookXMLFilePath;private String sharedStringXMLFilePath;public SaxAnalyserV07(AnalysisContext analysisContext) throws Exception {this.analysisContext = analysisContext;this.path = XMLTempFile.createPath();this.tmpFile = new File(XMLTempFile.getTmpFilePath(path));this.workBookXMLFilePath = XMLTempFile.getWorkBookFilePath(path);this.sharedStringXMLFilePath = XMLTempFile.getSharedStringFilePath(path);start();}@Overrideprotected void execute() {try {Sheet sheet = analysisContext.getCurrentSheet();if (!isAnalysisAllSheets(sheet)) {if (this.sheetSourceList.size() < sheet.getSheetNo() || sheet.getSheetNo() == 0) {return;}InputStream sheetInputStream = this.sheetSourceList.get(sheet.getSheetNo() - 1).getInputStream();parseXmlSource(sheetInputStream);return;}int i = 0;for (SheetSource sheetSource : this.sheetSourceList) {i++;this.analysisContext.setCurrentSheet(new Sheet(i));parseXmlSource(sheetSource.getInputStream());}} catch (Exception e) {stop();throw new ExcelAnalysisException(e);} finally {}}private boolean isAnalysisAllSheets(Sheet sheet) {if (sheet == null) {return true;}if (sheet.getSheetNo() < 0) {return true;}return false;}public void stop() {FileUtil.deletefile(path);}private void parseXmlSource(InputStream inputStream) {try {ContentHandler handler = new RowHandler(this, this.sharedStringsTable, this.analysisContext,sharedStringList);XmlParserFactory.parse(inputStream, handler);inputStream.close();} catch (Exception e) {try {inputStream.close();} catch (IOException e1) {e1.printStackTrace();}throw new ExcelAnalysisException(e);}}public List<Sheet> getSheets() {List<Sheet> sheets = new ArrayList<Sheet>();try {int i = 1;for (SheetSource sheetSource : this.sheetSourceList) {Sheet sheet = new Sheet(i, 0);sheet.setSheetName(sheetSource.getSheetName());i++;sheets.add(sheet);}} catch (Exception e) {stop();throw new ExcelAnalysisException(e);} finally {}return sheets;}private void start() throws IOException, XmlException, ParserConfigurationException, SAXException {createTmpFile();unZipTempFile();initSharedStringsTable();initUse1904WindowDate();initSheetSourceList();}private void createTmpFile() throws FileNotFoundException {FileUtil.writeFile(tmpFile, analysisContext.getInputStream());}private void unZipTempFile() throws IOException {FileUtil.doUnZip(path, tmpFile);}private void initSheetSourceList() throws IOException, ParserConfigurationException, SAXException {this.sheetSourceList = new ArrayList<SheetSource>();InputStream workbookXml = new FileInputStream(this.workBookXMLFilePath);XmlParserFactory.parse(workbookXml, new DefaultHandler() {@Overridepublic void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {if (qName.toLowerCase(Locale.US).equals("sheet")) {String name = null;int id = 0;for (int i = 0; i < attrs.getLength(); i++) {if (attrs.getLocalName(i).toLowerCase(Locale.US).equals("name")) {name = attrs.getValue(i);}/** else if (attrs.getLocalName(i).toLowerCase(Locale.US).equals("r:id")) {id = Integer.parseInt(attrs.getValue(i).replaceAll("rId", ""));try {InputStream inputStream = new FileInputStream(XMLTempFile.getSheetFilePath(path, id));sheetSourceList.add(new SheetSource(id, name, inputStream));} catch (FileNotFoundException e) {e.printStackTrace();}} **///应该使用sheetId属性else if (attrs.getLocalName(i).toLowerCase(Locale.US).equals("sheetid")) {id = Integer.parseInt(attrs.getValue(i));try {InputStream inputStream = new FileInputStream(XMLTempFile.getSheetFilePath(path, id));sheetSourceList.add(new SheetSource(id, name, inputStream));} catch (FileNotFoundException e) {e.printStackTrace();}}}}}});workbookXml.close();// 排序后是倒序,不符合实际要求// Collections.sort(sheetSourceList);Collections.sort(sheetSourceList, new Comparator<SheetSource>() {@Overridepublic int compare(SheetSource o1, SheetSource o2) {return o1.id - o2.id;}});}private void initUse1904WindowDate() throws IOException, XmlException {InputStream workbookXml = new FileInputStream(workBookXMLFilePath);WorkbookDocument ctWorkbook = WorkbookDocument.Factory.parse(workbookXml);CTWorkbook wb = ctWorkbook.getWorkbook();CTWorkbookPr prefix = wb.getWorkbookPr();if (prefix != null) {this.use1904WindowDate = prefix.getDate1904();}this.analysisContext.setUse1904WindowDate(use1904WindowDate);workbookXml.close();}private void initSharedStringsTable() throws IOException, ParserConfigurationException, SAXException {//因为sharedStrings.xml文件不一定存在,所以在处理之前增加判断File sharedStringXMLFile = new File(this.sharedStringXMLFilePath);if (!sharedStringXMLFile.exists()) {return;}InputStream inputStream = new FileInputStream(this.sharedStringXMLFilePath);//this.sharedStringsTable = new SharedStringsTable();//this.sharedStringsTable.readFrom(inputStream);XmlParserFactory.parse(inputStream, new DefaultHandler() {@Overridepublic void characters(char[] ch, int start, int length) {sharedStringList.add(new String(ch, start, length));}});inputStream.close();}private class SheetSource implements Comparable<SheetSource> {private int id;private String sheetName;private InputStream inputStream;public SheetSource(int id, String sheetName, InputStream inputStream) {this.id = id;this.sheetName = sheetName;this.inputStream = inputStream;}public String getSheetName() {return sheetName;}public void setSheetName(String sheetName) {this.sheetName = sheetName;}public InputStream getInputStream() {return inputStream;}public void setInputStream(InputStream inputStream) {this.inputStream = inputStream;}public int getId() {return id;}public void setId(int id) {this.id = id;}public int compareTo(SheetSource o) {if (o.id == this.id) {return 0;} else if (o.id > this.id) {return 1;} else {return -1;}}}}

另外,使用easyexcel读取excel的时候需要设置excel的版本,但是有些时候我们无法预知excel的版本,所以个人感觉这样不是太好,所以模仿poi写了一个用于获取com.alibaba.excel.ExcelReader对象的工具类

package com.alibaba.excel.read;import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;import org.apache.poi.EmptyFileException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.poifs.filesystem.DocumentFactoryHelper;
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
import org.apache.poi.util.IOUtils;import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.context.AnalysisContext;
import com.alibaba.excel.read.event.AnalysisEventListener;
import com.alibaba.excel.support.ExcelTypeEnum;public class ExcelReaderFactory {/*** @param in*           文件输入流* @param customContent*           自定义模型可以在*           {@link AnalysisEventListener#invoke(Object, AnalysisContext) }*           AnalysisContext中获取用于监听者回调使用* @param eventListener*           用户监听* @throws IOException* @throws EmptyFileException* @throws InvalidFormatException*/public static ExcelReader getExcelReader(InputStream in, Object customContent,AnalysisEventListener<?> eventListener) throws EmptyFileException, IOException, InvalidFormatException {// 如果输入流不支持mark/reset,需要对其进行包裹if (!in.markSupported()) {in = new PushbackInputStream(in, 8);}// 确保至少有一些数据byte[] header8 = IOUtils.peekFirst8Bytes(in);ExcelTypeEnum excelTypeEnum = null;if (NPOIFSFileSystem.hasPOIFSHeader(header8)) {excelTypeEnum = ExcelTypeEnum.XLS;}if (DocumentFactoryHelper.hasOOXMLHeader(in)) {excelTypeEnum = ExcelTypeEnum.XLSX;}if (excelTypeEnum != null) {return new ExcelReader(in, excelTypeEnum, customContent, eventListener);}throw new InvalidFormatException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");}/*** @param in*           文件输入流* @param customContent*           自定义模型可以在*           {@link AnalysisEventListener#invoke(Object, AnalysisContext) }*           AnalysisContext中获取用于监听者回调使用* @param eventListener*           用户监听* @param trim*           是否对解析的String做trim()默认true,用于防止 excel中空格引起的装换报错。* @throws IOException* @throws EmptyFileException* @throws InvalidFormatException*/public static ExcelReader getExcelReader(InputStream in, Object customContent,AnalysisEventListener<?> eventListener, boolean trim)throws EmptyFileException, IOException, InvalidFormatException {// 如果输入流不支持mark/reset,需要对其进行包裹if (!in.markSupported()) {in = new PushbackInputStream(in, 8);}// 确保至少有一些数据byte[] header8 = IOUtils.peekFirst8Bytes(in);ExcelTypeEnum excelTypeEnum = null;if (NPOIFSFileSystem.hasPOIFSHeader(header8)) {excelTypeEnum = ExcelTypeEnum.XLS;}if (DocumentFactoryHelper.hasOOXMLHeader(in)) {excelTypeEnum = ExcelTypeEnum.XLSX;}if (excelTypeEnum != null) {return new ExcelReader(in, excelTypeEnum, customContent, eventListener, trim);}throw new InvalidFormatException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");}
}

下面我们就来写一个简单的读取Excel的示例:

package test;import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;import org.junit.Test;import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.read.ExcelReaderFactory;
import com.alibaba.excel.read.context.AnalysisContext;
import com.alibaba.excel.read.event.AnalysisEventListener;public class ExcelReadTest {@Testpublic void read() throws Exception {try (InputStream in = new FileInputStream("withoutHead.xlsx");) {AnalysisEventListener<List<String>> listener = new AnalysisEventListener<List<String>>() {@Overridepublic void invoke(List<String> object, AnalysisContext context) {System.err.println("Row:" + context.getCurrentRowNum() + " Data:" + object);}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {System.err.println("doAfterAllAnalysed...");}};ExcelReader excelReader = ExcelReaderFactory.getExcelReader(in, null, listener);excelReader.read();}}
}

正如写入Excel的时候可以使用数据模型一样,在读取Excel的时候也可以直接将数据映射为模型对象,区别在于要使用ExcelReader #read的重载方法。

package test;import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;import org.junit.Test;import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.read.ExcelReaderFactory;
import com.alibaba.excel.read.context.AnalysisContext;
import com.alibaba.excel.read.event.AnalysisEventListener;public class ExcelReadTest {@Testpublic void read() throws Exception {try (InputStream in = new FileInputStream("withHead.xlsx");) {AnalysisEventListener<ExcelPropertyIndexModel> listener = new AnalysisEventListener<ExcelPropertyIndexModel>() {@Overridepublic void invoke(ExcelPropertyIndexModel object, AnalysisContext context) {System.err.println("Row:" + context.getCurrentRowNum() + " Data:" + object);}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {System.err.println("doAfterAllAnalysed...");}};ExcelReader excelReader = ExcelReaderFactory.getExcelReader(in, null, listener);// 第二个参数为表头行数,按照实际设置excelReader.read(new Sheet(1, 1, ExcelPropertyIndexModel.class));}}public static class ExcelPropertyIndexModel extends BaseRowModel {@ExcelProperty(value = "姓名", index = 0)private String name;@ExcelProperty(value = "年龄", index = 1)private String age;@ExcelProperty(value = "邮箱", index = 2)private String email;@ExcelProperty(value = "地址", index = 3)private String address;@ExcelProperty(value = "性别", index = 4)private String sax;@ExcelProperty(value = "高度", index = 5)private String heigh;@ExcelProperty(value = "备注", index = 6)private String last;}
}

以上就是关于easyexcel的使用方法介绍,如有疑问,欢迎交流指正。

相关文章:

easyexcel读和写excel

请直接看原文: JAVA使用easyexcel操作Excel-CSDN博客 -------------------------------------------------------------------------------------------------------------------------------- 之前写过一篇《JAVA操作Excel》&#xff0c;介绍了jxl和poi读写Excel的实现&am…...

路由器级联

目录 一、实现功能二、实现步骤2.1 接线步骤 三、效果3.1 常规连接3.2 路由器级联 一、实现功能 主路由器&#xff1a;可有WiFi功能&#xff0c;LAN口下接各设备&#xff0c;并接一个辅路由器辅路由器&#xff1a;开启WiFi功能&#xff0c;有线或无线下接各设备功能&#xff1…...

CentOS7使用Docker部署.net Webapi

1 准备WebApi项目 对于已存在的WebApi项目&#xff0c;需要添加Docker支持&#xff1b; 编码时&#xff0c;先设置好项目需要的端口号&#xff1a;program.cs中&#xff0c;app.Run("http://*:8000");设置端口为&#xff1a;8000在VS中&#xff0c;选中项目&#xf…...

Windows程序员用MAC:初始设置(用起来像win一些)

初级代码游戏的专栏介绍与文章目录-CSDN博客 初用Mac会有很多不习惯&#xff0c;特别是鼠标滚轮的滚动方向和windows是反的&#xff0c;还好是通过设置改变的。下面是我自己的设置。 目录 一、显示器设置 二、屏保、时钟、触发角 三、程序坞与菜单栏 四、安全性与隐私 五…...

基于深度学习YOLOv8+Pyqt5的工地安全帽头盔佩戴检测识别系统(源码+跑通说明文件)

wx供重浩&#xff1a;创享日记 对话框发送&#xff1a;318安全帽 获取完整源码源文件7000张已标注的数据集训练好的模型配置说明文件 可有偿59yuan一对一远程操作配置环境跑通程序 效果展示&#xff08;图片检测批量检测视频检测摄像头检测&#xff09; 基于深度学习YOLOv8Pyqt…...

csv编辑器是干什么的?

csv编辑器是一种用于编写、编辑和管理文本文件的工具。适用于 JetBrains IDE 系列的 CSV 编辑器插件&#xff0c;此插件将 CSV&#xff08;逗号分隔值&#xff09;作为一种语言引入 Jetbrains IDE&#xff0c;其中包含语法定义、结构化语言元素和关联的文件类型 &#xff08;.c…...

计算机网络——物理层(奈氏准则和香农定理)

计算机网络——物理层&#xff08;奈氏准则和香农定理&#xff09; 失真码间串扰奈氏准则&#xff08;奈奎斯特定理&#xff09;极限数据率 噪声信噪比香农定理奈氏准则和香农定理的区别 前面我们已经了解一些数据通信的基本知识&#xff0c;没有看过上一篇得小伙伴可以点击这里…...

XML语言的学习记录3-解析

学习笔记&#xff1a; 一、 解析XML文档&#xff1a; 1.使用 XMLHttpRequest 对象&#xff0c;将xml文档放入XML DOM对象中&#xff1a; xmlhttpnew XMLHttpRequest(); xmlhttp.open("GET","books.xml",false); xmlhttp.send(); xmlDocxmlhttp.response…...

【Linux】cat vim 命令存在着什么区别?

Linux 中的 cat 命令和 vim 命令之间存在一些显著的区别&#xff01; cat 命令 首先&#xff0c;cat命令主要用于连接并显示文件的内容。它的原含义是“连接&#xff08;concatenate&#xff09;”&#xff0c;可以将多个文件的内容连接起来&#xff0c;并输出到标准输出流中&…...

MeterSphere和Jmeter使用总结

一、MeterSphere 介绍 MeterSphere 是⼀站式开源持续测试平台&#xff0c;涵盖测试跟踪、接⼝测试、UI 测试和性能测试等&#xff0c;全 ⾯兼容 JMeter、Selenium 等主流开源标准&#xff0c;能够有效助⼒开发和测试团队在线共享协作&#xff0c;实现端到 端的测试管理跟踪…...

学习笔记Day8:GEO数据挖掘-基因表达芯片

GEO数据挖掘 数据库&#xff1a;GEO、NHANCE、TCGA、ICGC、CCLE、SEER等 数据类型&#xff1a;基因表达芯片、转录组、单细胞、突变、甲基化、拷贝数变异等等 常见图表 表达矩阵 一行为一个基因&#xff0c;一列为一个样本&#xff0c;内容是基因表达量。 热图 输入数据…...

如何将大华dav视频转mp4?一键无损清晰转换~

Digital Audio Video&#xff08;DAV&#xff09;文件格式源于数字监控领域&#xff0c;旨在解决视频监控数据的存储和回放问题。随着数字监控技术的发展&#xff0c;DAV格式逐渐成为监控设备记录视频的标准格式&#xff0c;广泛应用于安防系统、摄像头监控等场景。 MP4文件格式…...

数字化转型导师坚鹏:人工智能在金融机构数字化转型中的应用

人工智能在金融机构数字化转型中的应用 课程背景&#xff1a; 金融机构数字化转型离不开人工智能&#xff0c;在金融机构数字化转型中&#xff0c;人工智能起到至关重要的作用&#xff0c;很多机构存在以下问题&#xff1a; 不清楚人工智能产业对我们有什么影响&#xff1f;…...

部署Zabbix Agents添加使能监测服务器_Windows平台_MSI/Archive模式

Windows平台 一、从MSI安装Windows代理,添加Windows Servers/PC 概述 可以从Windows MSI安装包(32位或64位) 安装Zabbix agent 32位包不能安装在64位Windows中 所有软件包都支持TLS,配置TLS可选 支持UI和命令行的安装。 1、下载Agent代理程序,使用Agent2升级版,官网链接如…...

十一 超级数据查看器 讲解稿 详情6 导出功能

十一 超级数据查看器 讲解稿 详情6 导出功能 点击此处 以新页面 打开B站 播放当前教学视频 app下载地址 百度手机助手 下载地址4 ​ 讲解稿全文&#xff1a; 导出功能讲解 这节课我们讲解一下导出功能&#xff0c; 导出功能&#xff0c;可以将当前查到的信息导出成E…...

java遍历文件目录去除中文文件名

文章目录 一、原始需求二、maven依赖三、核心代码四、运行结果 一、原始需求 需要遍历文件目录及其子目录&#xff0c;找出包含中文字符的文件名&#xff0c;将中文字符去除。 二、maven依赖 pom.xml <dependency><groupId>org.apache.commons</groupId>&…...

LeetCode Python - 61. 旋转链表

目录 题目描述解法运行结果 题目描述 给你一个链表的头节点 head &#xff0c;旋转链表&#xff0c;将链表每个节点向右移动 k 个位置。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], k 2 输出&#xff1a;[4,5,1,2,3] 示例 2&#xff1a; 输入&#xff1a;head…...

k8s client-java创建pod常见问题

1.配置Kubernetes连接&#xff1a; 使用Kubernetes的配置文件&#xff08;通常位于~/.kube/config&#xff09;或直接使用API服务器地址、认证信息等来配置客户端。 配置通常有两种模式&#xff0c;安全和不安全的配置模式&#xff0c;对认证要求严格就选用安全模式&#xff…...

C++——字符串、读写文件、结构体、枚举

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…...

vscode 运行 java 项目之解决“Build failed, do you want to continue”的问题

Visual Studio Code运行 java 起来似乎比 IDEA 更轻量、比 eclipse 更友好&#xff0c;是不可多得的现代编译法宝。 安装好官方推荐的 java 扩展包后&#xff0c;就可以运行 java 代码了。功能 比 code runner 强&#xff0c;支持 gradle、maven、普通java项目&#xff0c;运行…...

yocto编译测试

源码下载 git clone -b gatesgarth git://git.yoctoproject.org/poky lkmaolkmao-virtual-machine:~/yocto$ git clone -b gatesgarth git://git.yoctoproject.org/poky Cloning into poky... remote: Enumerating objects: 640690, done. remote: Counting objects: 100% (13…...

rsync+inotify-tools文件传输

目录 rsync rsync概述 rsync优缺点 rsync参数 rsync命令 rsync同步源 linux 安装rsync 安装rsync服务端 安装rsync客户端 windows 安装rsync rsync实践 inotify-tools inotify-tools概述 innotify-tools 命令、参数、事件 rsync客户端安装inotify-tools innotif…...

UGUI界面性能优化3-合理规划界面层级结构

在Unity中&#xff0c;UGUI&#xff08;Unity GUI&#xff09;是一种用于创建用户界面的工具。合理规划界面层级结构对于开发一个可维护和易于使用的界面非常重要。以下是一种合理的UGUI界面层级结构规划方式&#xff1a; Canvas&#xff08;画布&#xff09;&#xff1a;Canva…...

《论文阅读》EmpDG:多分辨率交互式移情对话生成 COLING 2020

《论文阅读》EmpDG:多分辨率交互式移情对话生成 COLING 2020 前言简介模型架构共情生成器交互鉴别器损失函数前言 亲身阅读感受分享,细节画图解释,再也不用担心看不懂论文啦~ 无抄袭,无复制,纯手工敲击键盘~ 今天为大家带来的是《EmpDG: Multi-resolution Interactive E…...

C语言calloc函数的特点,效率低。但是进行初始化操作

#define _CRT_SECURE_NO_WARNINGS 1 #include<stdlib.h> #include<string.h> #include<errno.h> #include<stdio.h> int main() { int *p (int *)calloc(10,sizeof(int)); //初始化&#xff0c;效率低&#xff0c;然而malloc函数相反&#xf…...

项目中遇到的sql问题记录

有一张表&#xff0c;表结构及数据如下&#xff1a; INSERT INTO test.test_approve(approve_no, tra_date, tablename, part_dt) VALUES (approve001, 2021-02-18 00:00:00, tableA, 2024-03-18); INSERT INTO test.test_approve(approve_no, tra_date, tablename, part_dt) …...

Python Web开发记录 Day13:Django part7 Ajax入门与案例(任务管理)

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 1、Ajax入门①简介②工作原理③优点④缺点⑤使用…...

寻找可能认识的人

给一个命名为&#xff1a;friend.txt的文件 其中每一行中给出两个名字&#xff0c;中间用空格分开。&#xff08;下图为文件内容&#xff09; 题目&#xff1a;《查找出可能认识的人 》 代码如下&#xff1a; RelationMapper&#xff1a; package com.fesco.friend;import or…...

机器学习----特征缩放

目录 一、什么是特征缩放&#xff1a; 二、为什么要进行特征缩放&#xff1f; 三、如何进行特征缩放&#xff1a; 1、归一化&#xff1a; 2、均值归一化&#xff1a; 3、标准化&#xff08;数据需要符合正态分布&#xff09;&#xff1a; 一、什么是特征缩放&#xff1a; 通…...

机器学习_正则化

文章目录 代价函数 如果我们有非常多的特征&#xff0c;我们通过学习得到的假设可能能够非常好地适应训练集&#xff08;代价函数可能几乎为 0&#xff09;&#xff0c;但是可能会不能推广到新的数据。 下图是一个回归问题的例子&#xff1a; 第一个模型是一个线性模型&#xf…...

网站建设客户会问的问题/搜狗收录批量查询

java如何创建不定长的数组&#xff1f;JAVA没法定义不定长的数组&#xff0c;要么声明为NULL&#xff0c;要么指定其长度。如果需要不定长的集合&#xff0c;我们可以采用ArrayList来解决。1、首先声明一个集合listArrayList list new ArrayList();2、然后就可以往里面添加数据…...

做app网站公司/云盘网页版登录

对于网络I/O模型的学习&#xff0c;在操作系统中是非常重要的一环&#xff0c;因为I/O也同样是我们系统设计中至关重要的一个方面和要考虑的因素&#xff0c;因此想利用一篇文章来解析一下&#xff0c;就目前而言&#xff0c;业界对五种网络I/O模型的分类&#xff0c;主要分为以…...

手机网站开发 c/关键词歌曲

http://www.blogjava.net/Alpha/archive/2007/01/02.html转载于:https://blog.51cto.com/495798/1329292...

常熟祥云平台网站建设/google权重查询

音标&#xff1a;英[kəˈnekt]美[kəˈnɛkt]vt.连接&#xff0c;联结&#xff1b;使…有联系&#xff1b;为…接通电话&#xff1b;插入插座vi.连接&#xff1b;建立关系&#xff1b;[体]成功击中网络联系&#xff1b;联络&#xff1b;毗连&#xff1b;贯通行业释义体育1.击中…...

怎么做ps4的视频网站/观看b站的广告网站平台

springboot中的redisTemplate封装了redis批处理数据的接口&#xff0c;我们使用redisTemplate可以直接进行批量数据的get和set。 package com.huateng.applacation.service;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans…...

成都网站建设求职简历/如何推广网站链接

Shiro入门视频课程&#xff08;适合初学者的教程&#xff09;—210人已学习 课程介绍 本课程以通俗易懂的方式讲解Shiro权限技术&#xff0c;内容包括&#xff1a;Shiro简介、第一个Shiro程序、Realm、认证策略、加密服务、授权、Spring整合Shiro等。 适合初学者的教程&…...