前言
在平時的業務系統開發中,少不了需要用到導出、導入excel功能,今天我們就一起來總結一下!
下面給大家介紹一下幾種常用方法:
一、Apache poi
大概在很久很久以前,微軟的電子表格軟件 Excel 以操作簡單、存儲數據直觀方便,還支持打印報表,在誕生之初,可謂深得辦公室里的白領青睞,極大的提升了工作的效率,不久之后,便成了辦公室里的必備工具。
隨著更多的新語言的崛起,例如我們所熟悉的 java,后來便有一些團隊開始開發一套能與 Excel 軟件無縫切換的操作工具!
當然,在java生態體系里面,能與Excel無縫銜接的第三方工具還有很多,在開始也給大家列出來三個,因為 apache poi 在業界使用的最廣泛,因此其他的工具不做過多介紹!
話不多說,直接開擼!
1.1 首先添加依賴
- <dependencies>
- <!--xls(03)-->
- <dependency>
- <groupId>org.apache.poi</groupId>
- <artifactId>poi</artifactId>
- <version>4.1.2</version>
- </dependency>
- <!--xlsx(07)-->
- <dependency>
- <groupId>org.apache.poi</groupId>
- <artifactId>poi-ooxml</artifactId>
- <version>4.1.2</version>
- </dependency>
- <!--時間格式化工具-->
- <dependency>
- <groupId>joda-time</groupId>
- <artifactId>joda-time</artifactId>
- <version>2.10.6</version>
- </dependency>
- </dependencies>
1.2 導出excel
導出操作,即使用 Java 寫出數據到 Excel 中,常見場景是將頁面上的數據導出,這些數據可能是財務數據,也可能是商品數據,生成 Excel 后返回給用戶下載文件。
在 poi 工具庫中,導出 api 可以分三種方式
- HSSF方式: 這種方式導出的文件格式為office 2003專用格式,即.xls,優點是導出數據速度快,但是 最多65536行 數據
- XSSF方式: 這種方式導出的文件格式為office 2007專用格式,即.xlsx,優點是導出的數據不受行數限制,缺點導出速度慢
- SXSSF方式: SXSSF 是 XSSF API的兼容流式擴展,主要解決當使用 XSSF 方式導出大數據量時,內存溢出的問題,支持導出大批量的excel數據
1.2.1 HSSF方式導出(.xls方式)
HSSF方式,最多只支持65536條數據導出,超過這個條數會報錯!
- package cn.tedu.excel.test;
- import org.apache.poi.hssf.usermodel.HSSFWorkbook;
- import org.apache.poi.ss.usermodel.Cell;
- import org.apache.poi.ss.usermodel.Row;
- import org.apache.poi.ss.usermodel.Sheet;
- import org.apache.poi.ss.usermodel.Workbook;
- import java.io.FileOutputStream;
- /**
- * HSSF方式導出:HSSF方式,最多只支持65536條數據導出,超過這個條數會報錯!
- * 就是.xls模式
- */
- public class ExcelWrite2003Test {
- private static String PATH = "/Users/lixin/Desktop/";//自己輸出的路徑
- public static void main(String[] args) throws Exception {
- //時間
- long begin = System.currentTimeMillis();
- //創建一個工作簿
- Workbook workbook = new HSSFWorkbook();
- //創建表
- Sheet sheet = workbook.createSheet();
- //寫入數據
- for (int rowNumber = 0; rowNumber < 65536; rowNumber++) {
- //創建行
- Row row = sheet.createRow(rowNumber);
- for (int cellNumber = 0; cellNumber < 10; cellNumber++) {
- //創建列
- Cell cell = row.createCell(cellNumber);
- cell.setCellValue(cellNumber);
- }
- }
- System.out.println("結束!");
- FileOutputStream fileOutputStream = new FileOutputStream(PATH + "用戶信息表-XLS.xls");
- workbook.write(fileOutputStream);
- fileOutputStream.close();
- long end = System.currentTimeMillis();
- System.out.println("時間為:"+(double) (end - begin) / 1000);//2.262s
- }
- }
1.2.2 XSSF方式導出(.xlsx)
XSSF方式支持大批量數據導出,所有的數據先寫入內存再導出,容易出現內存溢出!
- package cn.tedu.excel.test;
- import org.apache.poi.ss.usermodel.Cell;
- import org.apache.poi.ss.usermodel.Row;
- import org.apache.poi.ss.usermodel.Sheet;
- import org.apache.poi.ss.usermodel.Workbook;
- import org.apache.poi.xssf.usermodel.XSSFWorkbook;
- import java.io.FileOutputStream;
- /**
- * .xlsx方式
- */
- public class ExcelWrite2007Test {
- public static String PATH = "/Users/lixin/Desktop/";
- public static void main(String[] args) throws Exception {
- //時間
- long begin = System.currentTimeMillis();
- //創建一個工作簿
- Workbook workbook = new XSSFWorkbook();
- //創建表
- Sheet sheet = workbook.createSheet();
- //寫入數據
- for (int rowNumber = 0; rowNumber < 65537; rowNumber++) {
- Row row = sheet.createRow(rowNumber);
- for (int cellNumber = 0; cellNumber < 10; cellNumber++) {
- Cell cell = row.createCell(cellNumber);
- cell.setCellValue(cellNumber);
- }
- }
- System.out.println("結束");
- FileOutputStream fileOutputStream = new FileOutputStream(PATH + "用戶信息表-XLSX.xlsx");
- workbook.write(fileOutputStream);
- fileOutputStream.close();
- long end = System.currentTimeMillis();
- System.out.println((double) (end - begin) / 1000);//5.003s
- }
- }
1.2.3、SXSSF方式導出
SXSSF方式是XSSF方式的一種延伸,主要特性是低內存,導出的時候,先將數據寫入磁盤再導出,避免報內存不足,導致程序運行異常,缺點是運行很慢!
- package cn.tedu.excel.test;
- import org.apache.poi.ss.usermodel.Cell;
- import org.apache.poi.ss.usermodel.Row;
- import org.apache.poi.ss.usermodel.Sheet;
- import org.apache.poi.ss.usermodel.Workbook;
- import org.apache.poi.xssf.streaming.SXSSFWorkbook;
- import java.io.FileOutputStream;
- public class ExcelWriteSXSSFTest {
- public static String PATH = "/Users/lixin/Desktop/";
- public static void main(String[] args) throws Exception {
- //時間
- long begin = System.currentTimeMillis();
- //創建一個工作簿
- Workbook workbook = new SXSSFWorkbook();
- //創建表
- Sheet sheet = workbook.createSheet();
- //寫入數據
- for (int rowNumber = 0; rowNumber < 100000; rowNumber++) {
- Row row = sheet.createRow(rowNumber);
- for (int cellNumber = 0; cellNumber < 10; cellNumber++) {
- Cell cell = row.createCell(cellNumber);
- cell.setCellValue(cellNumber);
- }
- }
- System.out.println("over");
- FileOutputStream fileOutputStream = new FileOutputStream(PATH + "用戶信息表-SXSSF.xlsx");
- workbook.write(fileOutputStream);
- fileOutputStream.close();
- long end = System.currentTimeMillis();
- System.out.println((double) (end - begin) / 1000);//6.39s
- }
- }
1.3 導入excel
導入操作,即將 excel 中的數據采用java工具庫將其解析出來,進而將 excel 數據寫入數據庫!
同樣,在 poi 工具庫中,導入 api 也分三種方式,與上面的導出一一對應!
1.3.1 HSSF方式導入
- package cn.tedu.excel.test;
- import org.apache.poi.hssf.usermodel.HSSFDateUtil;
- import org.apache.poi.hssf.usermodel.HSSFWorkbook;
- import org.apache.poi.ss.usermodel.*;
- import org.joda.time.DateTime;
- import java.io.FileInputStream;
- import java.util.Date;
- public class ExcelRead2003Test {
- public static String PATH = "/Users/lixin/Desktop/";
- public static void main(String[] args) throws Exception {
- //獲取文件流
- FileInputStream inputStream = new FileInputStream(PATH + "用戶信息表2003read.xls");
- //1.創建工作簿,使用excel能操作的這邊都看看操作
- Workbook workbook = new HSSFWorkbook(inputStream);
- //2.得到表
- Sheet sheet = workbook.getSheetAt(0);
- //3.得到行
- Row row = sheet.getRow(0);
- //4.得到列
- Cell cell = row.getCell(0);
- getValue(cell);
- inputStream.close();
- }
- public static void getValue(Cell cell){
- //匹配類型數據
- if (cell != null) {
- CellType cellType = cell.getCellType();
- String cellValue = "";
- switch (cellType) {
- case STRING: //字符串
- System.out.print("[String類型]");
- cellValue = cell.getStringCellValue();
- break;
- case BOOLEAN: //布爾類型
- System.out.print("[boolean類型]");
- cellValue = String.valueOf(cell.getBooleanCellValue());
- break;
- case BLANK: //空
- System.out.print("[BLANK類型]");
- break;
- case NUMERIC: //數字(日期、普通數字)
- System.out.print("[NUMERIC類型]");
- if (HSSFDateUtil.isCellDateFormatted(cell)) { //日期
- System.out.print("[日期]");
- Date date = cell.getDateCellValue();
- cellValue = new DateTime(date).toString("yyyy-MM-dd");
- } else {
- //不是日期格式,防止數字過長
- System.out.print("[轉換為字符串輸出]");
- cell.setCellType(CellType.STRING);
- cellValue = cell.toString();
- }
- break;
- case ERROR:
- System.out.print("[數據類型錯誤]");
- break;
- }
- System.out.println(cellValue);
- }
- }
- }
輸出結果類似如圖所示:
1.3.2 XSSF方式導入
- package cn.tedu.excel.test;
- import org.apache.poi.hssf.usermodel.HSSFDateUtil;
- import org.apache.poi.ss.usermodel.*;
- import org.apache.poi.xssf.usermodel.XSSFWorkbook;
- import org.joda.time.DateTime;
- import java.io.FileInputStream;
- import java.util.Date;
- public class ExcelRead2007Test {
- public static String PATH = "/Users/lixin/Desktop/";
- public static void main(String[] args) throws Exception {
- //獲取文件流
- FileInputStream inputStream = new FileInputStream(PATH + "用戶信息表2007read.xlsx");
- //1.創建工作簿,使用excel能操作的這邊都看看操作
- Workbook workbook = new XSSFWorkbook(inputStream);
- //2.得到表
- Sheet sheet = workbook.getSheetAt(0);
- //3.得到行
- Row row = sheet.getRow(0);
- //4.得到列
- Cell cell = row.getCell(0);
- getValue(cell);
- inputStream.close();
- }
- public static void getValue(Cell cell){
- //匹配類型數據
- if (cell != null) {
- CellType cellType = cell.getCellType();
- String cellValue = "";
- switch (cellType) {
- case STRING: //字符串
- System.out.print("[String類型]");
- cellValue = cell.getStringCellValue();
- break;
- case BOOLEAN: //布爾類型
- System.out.print("[boolean類型]");
- cellValue = String.valueOf(cell.getBooleanCellValue());
- break;
- case BLANK: //空
- System.out.print("[BLANK類型]");
- break;
- case NUMERIC: //數字(日期、普通數字)
- System.out.print("[NUMERIC類型]");
- if (HSSFDateUtil.isCellDateFormatted(cell)) { //日期
- System.out.print("[日期]");
- Date date = cell.getDateCellValue();
- cellValue = new DateTime(date).toString("yyyy-MM-dd");
- } else {
- //不是日期格式,防止數字過長
- System.out.print("[轉換為字符串輸出]");
- cell.setCellType(CellType.STRING);
- cellValue = cell.toString();
- }
- break;
- case ERROR:
- System.out.print("[數據類型錯誤]");
- break;
- }
- System.out.println(cellValue);
- }
- }
- }
1.3.3 SXSSF方式導入
- package cn.tedu.excel.test;
- import org.apache.poi.ooxml.util.SAXHelper;
- import org.apache.poi.openxml4j.opc.OPCPackage;
- import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
- import org.apache.poi.xssf.eventusermodel.XSSFReader;
- import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
- import org.apache.poi.xssf.model.StylesTable;
- import org.apache.poi.xssf.usermodel.XSSFComment;
- import org.xml.sax.InputSource;
- import org.xml.sax.XMLReader;
- import java.io.InputStream;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import java.util.stream.Collectors;
- public class ExcelReadSXSSFTest {
- public static String PATH = "/Users/lixin/Desktop/";
- public static void main(String[] args) throws Exception {
- //獲取文件流
- //1.創建工作簿,使用excel能操作的這邊都看看操作
- OPCPackage opcPackage = OPCPackage.open(PATH + "用戶信息表2007read.xlsx");
- XSSFReader xssfReader = new XSSFReader(opcPackage);
- StylesTable stylesTable = xssfReader.getStylesTable();
- ReadOnlySharedStringsTable sharedStringsTable = new ReadOnlySharedStringsTable(opcPackage);
- // 創建XMLReader,設置ContentHandler
- XMLReader xmlReader = SAXHelper.newXMLReader();
- xmlReader.setContentHandler(new XSSFSheetXMLHandler(stylesTable, sharedStringsTable, new SimpleSheetContentsHandler(), false));
- // 解析每個Sheet數據
- Iterator<InputStream> sheetsData = xssfReader.getSheetsData();
- while (sheetsData.hasNext()) {
- try (InputStream inputStream = sheetsData.next();) {
- xmlReader.parse(new InputSource(inputStream));
- }
- }
- }
- /**
- * 內容處理器
- */
- public static class SimpleSheetContentsHandler implements XSSFSheetXMLHandler.SheetContentsHandler {
- protected List<String> row;
- @Override
- public void startRow(int rowNum) {
- row = new ArrayList<>();
- }
- @Override
- public void endRow(int rowNum) {
- if (row.isEmpty()) {
- return;
- }
- // 處理數據
- System.out.println(row.stream().collect(Collectors.joining(" ")));
- }
- @Override
- public void cell(String cellReference, String formattedValue, XSSFComment comment) {
- row.add(formattedValue);
- }
- @Override
- public void headerFooter(String text, boolean isHeader, String tagName) {
- }
- }
- }
二、Easypoi
以前的以前,有個大佬程序員,跳到一家公司之后就和業務人員聊上了,這些業務員對excel報表有著許許多多的要求,比如想要一個報表,他的表頭是一個多行表頭,過幾天之后,他想要給這些表頭添加樣式,比如關鍵的數據標紅,再過幾天,他想要再末尾添加一條合計的數據,等等!
起初還好,都是copy、copy,之后發現系統中出現大量的重復代碼,于是有一天真的忍受不了了,采用注解搞定來搞定這些定制化成程度高的邏輯,將公共化抽離出來,于是誕生了 easypoi!它的底層也是基于 apache poi 進行深度開發的,它主要的特點就是將更多重復的工作,全部簡單化,避免編寫重復的代碼!
下面,我們就一起來了解一下這款高大上的開源工具:easypoi
2.1 添加依賴包
- <dependencies>
- <dependency>
- <groupId>cn.afterturn</groupId>
- <artifactId>easypoi-base</artifactId>
- <version>4.1.0</version>
- </dependency>
- <dependency>
- <groupId>cn.afterturn</groupId>
- <artifactId>easypoi-web</artifactId>
- <version>4.1.0</version>
- </dependency>
- <dependency>
- <groupId>cn.afterturn</groupId>
- <artifactId>easypoi-annotation</artifactId>
- <version>4.1.0</version>
- </dependency>
- <dependency>
- <groupId>com.googlecode.json-simple</groupId>
- <artifactId>json-simple</artifactId>
- <version>1.1.1</version>
- </dependency>
- </dependencies>
2.2 采用注解導出導入
easypoi 最大的亮點就是基于注解實體類來導出、導入excel,使用起來非常簡單!
我們創建一個實體類UserEntity,其中@Excel注解表示導出文件的頭部信息。
添加Lombok插件,替代set和get方法
2.2.1 導出操作
- package cn.tedu.excel.easypoi;
- import cn.afterturn.easypoi.excel.ExcelExportUtil;
- import cn.afterturn.easypoi.excel.annotation.Excel;
- import cn.afterturn.easypoi.excel.entity.ExportParams;
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- import org.apache.poi.ss.usermodel.Workbook;
- import java.io.FileOutputStream;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.List;
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- public class UserEntity {
- @Excel(name = "姓名")
- private String name;
- @Excel(name = "年齡")
- private int age;
- @Excel(name = "操作時間",format="yyyy-MM-dd HH:mm:ss", width = 20.0)
- private Date time;
- public static void main(String[] args) throws Exception {
- List<UserEntity> dataList = new ArrayList<>();
- for (int i = 0; i < 10; i++) {
- UserEntity userEntity = new UserEntity();
- userEntity.setName("張三" + i);
- userEntity.setAge(20 + i);
- userEntity.setTime(new Date(System.currentTimeMillis() + i));
- dataList.add(userEntity);
- }
- //生成excel文檔
- Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("用戶","用戶信息"),
- UserEntity.class, dataList);
- FileOutputStream fos = new FileOutputStream("/Users/lixin/Desktop/easypoi-user.xls");
- workbook.write(fos);
- fos.close();
- }
- }
導出文件預覽圖如下:
2.2.2 導入操作
- package cn.tedu.excel.easypoi;
- import cn.afterturn.easypoi.excel.ExcelImportUtil;
- import cn.afterturn.easypoi.excel.annotation.Excel;
- import cn.afterturn.easypoi.excel.entity.ImportParams;
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- import java.io.File;
- import java.util.Date;
- import java.util.List;
- import org.json.simple.JSONArray;
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- public class StudentEntity {
- @Excel(name = "姓名")
- private String name;
- @Excel(name = "年齡")
- private int age;
- @Excel(name = "操作時間",format="yyyy-MM-dd HH:mm:ss", width = 20.0)
- private Date time;
- public static void main(String[] args) {
- ImportParams params = new ImportParams();
- params.setTitleRows(1);
- params.setHeadRows(1);
- long start = new Date().getTime();
- List<StudentEntity> list = ExcelImportUtil.importExcel(new File("/Users/lixin/Desktop/easypoi-user1.xls"),
- UserEntity.class, params);
- System.out.println(new Date().getTime() - start);
- System.out.println(JSONArray.toJSONString(list));
- }
- }
輸出結果為:
[UserEntity(name=張三0, age=20, time=Mon Mar 29 11:29:52 CST 2021),UserEntity(name=李四, age=21, time=Mon Mar 29 11:29:52 CST 2021),UserEntity(name=王武, age=22, time=Mon Mar 29 11:29:52 CST 2021),UserEntity(name=趙六, age=23, time=Mon Mar 29 11:29:52 CST 2021),UserEntity(name=null, age=0, time=null),UserEntity(name=null, age=0, time=null),UserEntity(name=null, age=0, time=null),UserEntity(name=null, age=0, time=null),UserEntity(name=null, age=0, time=null),UserEntity(name=null, age=0, time=null)]
2.3 自定義數據結構導出導入
easypoi 同樣也支持自定義數據結構導出導入excel。
自定義數據導出 excel
2.3.1 導出操作
- public static void main(String[] args) throws Exception {
- //封裝表頭
- List<ExcelExportEntity> entityList = new ArrayList<ExcelExportEntity>();
- entityList.add(new ExcelExportEntity("姓名", "name"));
- entityList.add(new ExcelExportEntity("年齡", "age"));
- ExcelExportEntity entityTime = new ExcelExportEntity("操作時間", "time");
- entityTime.setFormat("yyyy-MM-dd HH:mm:ss");
- entityTime.setWidth(20.0);
- entityList.add(entityTime);
- //封裝數據體
- List<Map<String, Object>> dataList = new ArrayList<>();
- for (int i = 0; i < 10; i++) {
- Map<String, Object> userEntityMap = new HashMap<>();
- userEntityMap.put("name", "張三" + i);
- userEntityMap.put("age", 20 + i);
- userEntityMap.put("time", new Date(System.currentTimeMillis() + i));
- dataList.add(userEntityMap);
- }
- //生成excel文檔
- Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("學生","用戶信息"), entityList, dataList);
- FileOutputStream fos = new FileOutputStream("/Users/lixin/Desktop/easypoi-user2.xls");
- workbook.write(fos);
- fos.close();
- }
2.3.2 導入操作
- public static void main(String[] args) {
- ImportParams params = new ImportParams();
- params.setTitleRows(1);
- params.setHeadRows(1);
- long start = new Date().getTime();
- List<Map<String, Object>> list = ExcelImportUtil.importExcel(new File("/Users/lixin/Desktop/easypoi-user2.xls"),
- Map.class, params);
- System.out.println(new Date().getTime() - start);
- System.out.println(JSONArray.toJSONString(list));
- }
更多的 api 操作可以訪問 Easypoi - 接口文檔
三、Easyexcel
easyexcel 是阿里巴巴開源的一款 excel 解析工具,底層邏輯也是基于 apache poi 進行二次開發的。不同的是,再讀寫數據的時候,采用 sax 模式一行一行解析,在并發量很大的情況下,依然能穩定運行!
下面,我們就一起來了解一下這款新起之秀!
3.1 添加依賴包
- <!-- EasyExcel -->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>easyexcel</artifactId>
- <version>2.2.6</version>
- </dependency>
- <!--常用工具庫-->
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>29.0-jre</version>
- </dependency>
3.2 采用注解導出導入
easyexcel 同樣也支持采用注解方式進行導出、導入!
首先,我們創建一個實體類UserEntity,其中@ExcelProperty注解表示導出文件的頭部信息。
3.2.1 導出操作
- package cn.tedu.excel.easyexcel;
- import com.alibaba.excel.EasyExcel;
- import com.alibaba.excel.annotation.ExcelProperty;
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- import org.springframework.format.annotation.DateTimeFormat;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.List;
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- public class UserEntity {
- @ExcelProperty(value = "姓名")
- private String name;
- @ExcelProperty(value = "年齡")
- private int age;
- @DateTimeFormat(fallbackPatterns = "yyyy-MM-dd HH:mm:ss")
- @ExcelProperty(value = "操作時間")
- private Date time;
- public static void main(String[] args) {
- List<UserEntity> dataList = new ArrayList<>();
- for (int i = 0; i < 10; i++) {
- UserEntity userEntity = new UserEntity();
- userEntity.setName("張三" + i);
- userEntity.setAge(20 + i);
- userEntity.setTime(new Date(System.currentTimeMillis() + i));
- dataList.add(userEntity);
- }
- EasyExcel.write("/Users/lixin/Desktop/easyexcel-user1.xls", UserEntity.class).sheet("用戶信息").doWrite(dataList);
- }
- }
導出預覽圖:
3.2.2 導入操作
- package cn.tedu.excel.easyexcel;
- import com.alibaba.excel.EasyExcel;
- import org.json.simple.JSONArray;
- import java.util.List;
- public class DemoData {
- public static void main(String[] args) {
- String filePath = "/Users/lixin/Desktop/easyexcel-user1.xls";
- List<DemoData> list = EasyExcel.read(filePath).head(UserEntity.class).sheet().doReadSync();
- System.out.println(JSONArray.toJSONString(list));
- }
- }
結果顯示:
[UserEntity(name=張三0, age=20, time=Mon Mar 29 16:42:20 CST 2021),UserEntity(name=張三1, age=21, time=Mon Mar 29 16:42:20 CST 2021),UserEntity(name=張三2, age=22, time=Mon Mar 29 16:42:20 CST 2021),UserEntity(name=張三3, age=23, time=Mon Mar 29 16:42:20 CST 2021),UserEntity(name=張三4, age=24, time=Mon Mar 29 16:42:20 CST 2021),UserEntity(name=張三5, age=25, time=Mon Mar 29 16:42:20 CST 2021),UserEntity(name=張三6, age=26, time=Mon Mar 29 16:42:20 CST 2021),UserEntity(name=張三7, age=27, time=Mon Mar 29 16:42:20 CST 2021),UserEntity(name=張三8, age=28, time=Mon Mar 29 16:42:20 CST 2021),UserEntity(name=張三9, age=29, time=Mon Mar 29 16:42:20 CST 2021)]
3.3 自定義數據結構導出導入
easyexcel 同樣也支持自定義數據結構導出導入excel。
3.3.1 導出操作
- public static void main(String[] args) {
- //表頭
- List<List<String>> headList = new ArrayList<>();
- headList.add(Lists.newArrayList("姓名"));
- headList.add(Lists.newArrayList("年齡"));
- headList.add(Lists.newArrayList("操作時間"));
- //數據體
- List<List<Object>> dataList = new ArrayList<>();
- for (int i = 0; i < 10; i++) {
- List<Object> data = new ArrayList<>();
- data.add("張三" + i);
- data.add(20 + i);
- data.add(new Date(System.currentTimeMillis() + i));
- dataList.add(data);
- }
- EasyExcel.write("/Users/hello/Documents/easyexcel-user2.xls").head(headList).sheet("用戶信息").doWrite(dataList);
- }
3.3.2 導入操作
- public static void main(String[] args) {
- String filePath = "/Users/panzhi/Documents/easyexcel-user2.xls";
- UserDataListener userDataListener = new UserDataListener();
- EasyExcel.read(filePath, userDataListener).sheet().doRead();
- System.out.println("表頭:" + JSONArray.toJSONString(userDataListener.getHeadList()));
- System.out.println("數據體:" + JSONArray.toJSONString(userDataListener.getDataList()));
- }
運行結果如圖所示:
表頭:[{0:"姓名",1:"年齡",2:"操作時間"}]
數據體:[{0:"張三0",1:"20",2:"2021-03-29 16:31:39"},{0:"張三1",1:"21",2:"2021-03-29 16:31:39"},{0:"張三2",1:"22",2:"2021-03-29 16:31:39"},{0:"張三3",1:"23",2:"2021-03-29 16:31:39"},{0:"張三4",1:"24",2:"2021-03-29 16:31:39"},{0:"張三5",1:"25",2:"2021-03-29 16:31:39"},{0:"張三6",1:"26",2:"2021-03-29 16:31:39"},{0:"張三7",1:"27",2:"2021-03-29 16:31:39"},{0:"張三8",1:"28",2:"2021-03-29 16:31:39"},{0:"張三9",1:"29",2:"2021-03-29 16:31:39"}]
更多的 api 操作可以訪問 easyexcel - 接口文檔!
四、總結
總體來說,Easypoi 和 Easyexcel 都是基于Apache poi進行二次開發的。
不同點在于:
- Easypoi 在讀寫數據的時候,優先是先將數據寫入內存,優點是讀寫性能非常高,但是當數據量很大的時候,會出現oom,當然它也提供了 sax 模式的讀寫方式,需要調用特定的方法實現。
- Easyexcel 基于sax模式進行讀寫數據,不會出現oom情況,程序有過高并發場景的驗證,因此程序運行比較穩定,相對于 Easypoi 來說,讀寫性能稍慢!
Easypoi 與 Easyexcel 還有一點區別在于,Easypoi 對定制化的導出支持非常的豐富,如果當前的項目需求,并發量不大、數據量也不大,但是需要導出 excel 的文件樣式千差萬別,那么我推薦你用 easypoi;反之,使用 easyexcel !
到此這篇關于Java操作excel的三種常見方法的文章就介紹到這了,更多相關Java操作excel內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/qq1808814025/article/details/115294105