From 15a0662da5daef254a55155c1e962a95c841f420 Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 19 Mar 2022 11:13:33 +0800 Subject: [PATCH] fix code --- CHANGELOG.md | 3 +- .../cn/hutool/poi/excel/BigExcelWriter.java | 34 +++++++-- .../java/cn/hutool/poi/excel/ExcelBase.java | 75 ++++++++++++++++++- .../java/cn/hutool/poi/excel/ExcelReader.java | 64 +++------------- .../java/cn/hutool/poi/excel/ExcelWriter.java | 58 ++++---------- .../cn/hutool/poi/excel/WorkbookUtil.java | 42 +++++++---- .../poi/excel/reader/AbstractSheetReader.java | 14 +++- .../cn/hutool/poi/excel/ExcelUtilTest.java | 14 +--- 8 files changed, 165 insertions(+), 139 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 527edba76..d0b30fdd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.7.23 (2022-03-17) +# 5.7.23 (2022-03-19) ### 🐣新特性 * 【http 】 HttpRequest.form采用TableMap方式(issue#I4W427@Gitee) @@ -20,6 +20,7 @@ * 【core 】 Dict增加setFields方法(pr#578@Gitee) * 【db 】 新加db.meta的索引相关接口(pr#563@Gitee) * 【db 】 Oracle中Column#typeName后的长度去掉(pr#563@Gitee) +* 【poi 】 优化ExcelReader,采用只读模式(pr#2204@Gitee) * ### 🐞Bug修复 * 【core 】 修复ObjectUtil.hasNull传入null返回true的问题(pr#555@Gitee) diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/BigExcelWriter.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/BigExcelWriter.java index 6edd7c0bf..a51342934 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/BigExcelWriter.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/BigExcelWriter.java @@ -10,7 +10,9 @@ import java.io.File; import java.io.OutputStream; /** - * 大数据量Excel写出 + * 大数据量Excel写出,只支持XLSX(Excel07版本)
+ * 通过封装{@link SXSSFWorkbook},限制对滑动窗口中的行的访问来实现其低内存使用。
+ * 注意如果写出数据大于滑动窗口大小,就会写出到临时文件,此时写出的数据无法访问和编辑。 * * @author looly * @since 4.1.13 @@ -25,6 +27,7 @@ public class BigExcelWriter extends ExcelWriter { private boolean isFlushed; // -------------------------------------------------------------------------- Constructor start + /** * 构造,默认生成xlsx格式的Excel文件
* 此构造不传入写出的Excel文件路径,只能调用{@link #flush(java.io.OutputStream)}方法写出到流
@@ -45,6 +48,21 @@ public class BigExcelWriter extends ExcelWriter { this(WorkbookUtil.createSXSSFBook(rowAccessWindowSize), null); } + /** + * 构造
+ * 此构造不传入写出的Excel文件路径,只能调用{@link #flush(java.io.OutputStream)}方法写出到流
+ * 若写出到文件,需要调用{@link #flush(File)} 写出到文件 + * + * @param rowAccessWindowSize 在内存中的行数,-1表示不限制,此时需要手动刷出 + * @param compressTmpFiles 是否使用Gzip压缩临时文件 + * @param useSharedStringsTable 是否使用共享字符串表,一般大量重复字符串时开启可节省内存 + * @param sheetName 写出的sheet名称 + * @since 5.7.23 + */ + public BigExcelWriter(int rowAccessWindowSize, boolean compressTmpFiles, boolean useSharedStringsTable, String sheetName) { + this(WorkbookUtil.createSXSSFBook(rowAccessWindowSize, compressTmpFiles, useSharedStringsTable), sheetName); + } + /** * 构造,默认写出到第一个sheet,第一个sheet名为sheet1 * @@ -60,7 +78,7 @@ public class BigExcelWriter extends ExcelWriter { * 若写出到文件,需要调用{@link #flush(File)} 写出到文件 * * @param rowAccessWindowSize 在内存中的行数 - * @param sheetName sheet名,第一个sheet名并写出到此sheet,例如sheet1 + * @param sheetName sheet名,第一个sheet名并写出到此sheet,例如sheet1 * @since 4.1.8 */ public BigExcelWriter(int rowAccessWindowSize, String sheetName) { @@ -71,7 +89,7 @@ public class BigExcelWriter extends ExcelWriter { * 构造 * * @param destFilePath 目标文件路径,可以不存在 - * @param sheetName sheet名,第一个sheet名并写出到此sheet,例如sheet1 + * @param sheetName sheet名,第一个sheet名并写出到此sheet,例如sheet1 */ public BigExcelWriter(String destFilePath, String sheetName) { this(FileUtil.file(destFilePath), sheetName); @@ -89,7 +107,7 @@ public class BigExcelWriter extends ExcelWriter { /** * 构造 * - * @param destFile 目标文件,可以不存在 + * @param destFile 目标文件,可以不存在 * @param sheetName sheet名,做为第一个sheet名并写出到此sheet,例如sheet1 */ public BigExcelWriter(File destFile, String sheetName) { @@ -102,7 +120,7 @@ public class BigExcelWriter extends ExcelWriter { * 此构造不传入写出的Excel文件路径,只能调用{@link #flush(java.io.OutputStream)}方法写出到流
* 若写出到文件,还需调用{@link #setDestFile(File)}方法自定义写出的文件,然后调用{@link #flush()}方法写出到文件 * - * @param workbook {@link SXSSFWorkbook} + * @param workbook {@link SXSSFWorkbook} * @param sheetName sheet名,做为第一个sheet名并写出到此sheet,例如sheet1 */ public BigExcelWriter(SXSSFWorkbook workbook, String sheetName) { @@ -125,7 +143,7 @@ public class BigExcelWriter extends ExcelWriter { @Override public BigExcelWriter autoSizeColumn(int columnIndex) { - final SXSSFSheet sheet = (SXSSFSheet)this.sheet; + final SXSSFSheet sheet = (SXSSFSheet) this.sheet; sheet.trackColumnForAutoSizing(columnIndex); super.autoSizeColumn(columnIndex); sheet.untrackColumnForAutoSizing(columnIndex); @@ -134,7 +152,7 @@ public class BigExcelWriter extends ExcelWriter { @Override public BigExcelWriter autoSizeColumnAll() { - final SXSSFSheet sheet = (SXSSFSheet)this.sheet; + final SXSSFSheet sheet = (SXSSFSheet) this.sheet; sheet.trackAllColumnsForAutoSizing(); super.autoSizeColumnAll(); sheet.untrackAllColumnsForAutoSizing(); @@ -143,7 +161,7 @@ public class BigExcelWriter extends ExcelWriter { @Override public ExcelWriter flush(OutputStream out, boolean isCloseOut) throws IORuntimeException { - if(false == isFlushed){ + if (false == isFlushed) { isFlushed = true; return super.flush(out, isCloseOut); } diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java index 0f11bac7c..0e0481b7e 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java @@ -17,8 +17,11 @@ import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.Closeable; +import java.io.File; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; /** * Excel基础类,用于抽象ExcelWriter和ExcelReader中共用部分的对象和方法 @@ -32,6 +35,10 @@ public class ExcelBase> implements Closeable { * 是否被关闭 */ protected boolean isClosed; + /** + * 目标文件,如果用户读取为流或自行创建的Workbook或Sheet,此参数为{@code null} + */ + protected File destFile; /** * 工作簿 */ @@ -40,6 +47,10 @@ public class ExcelBase> implements Closeable { * Excel中对应的Sheet */ protected Sheet sheet; + /** + * 标题行别名 + */ + protected Map headerAlias; /** * 构造 @@ -171,7 +182,6 @@ public class ExcelBase> implements Closeable { * @return this * @since 5.7.10 */ - @SuppressWarnings("unchecked") public T cloneSheet(int sheetIndex, String newSheetName, boolean setAsCurrentSheet) { Sheet sheet; if (this.workbook instanceof XSSFWorkbook) { @@ -184,6 +194,7 @@ public class ExcelBase> implements Closeable { if (setAsCurrentSheet) { this.sheet = sheet; } + //noinspection unchecked return (T) this; } @@ -499,4 +510,66 @@ public class ExcelBase> implements Closeable { this.workbook = null; this.isClosed = true; } + + /** + * 获得标题行的别名Map + * + * @return 别名Map + */ + public Map getHeaderAlias() { + return headerAlias; + } + + /** + * 设置标题行的别名Map + * + * @param headerAlias 别名Map + * @return this + */ + public T setHeaderAlias(Map headerAlias) { + this.headerAlias = headerAlias; + //noinspection unchecked + return (T) this; + } + + /** + * 增加标题别名 + * + * @param header 标题 + * @param alias 别名 + * @return this + */ + public T addHeaderAlias(String header, String alias) { + Map headerAlias = this.headerAlias; + if (null == headerAlias) { + headerAlias = new LinkedHashMap<>(); + } + this.headerAlias = headerAlias; + this.headerAlias.put(header, alias); + //noinspection unchecked + return (T) this; + } + + /** + * 去除标题别名 + * + * @param header 标题 + * @return this + */ + public T removeHeaderAlias(String header) { + this.headerAlias.remove(header); + //noinspection unchecked + return (T) this; + } + + /** + * 清空标题别名,key为Map中的key,value为别名 + * + * @return this + */ + public T clearHeaderAlias() { + this.headerAlias = null; + //noinspection unchecked + return (T) this; + } } diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelReader.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelReader.java index 505ddbc78..bac3a4caa 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelReader.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelReader.java @@ -18,7 +18,6 @@ import org.apache.poi.ss.usermodel.Workbook; import java.io.File; import java.io.InputStream; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -39,11 +38,6 @@ public class ExcelReader extends ExcelBase { * 单元格值处理接口 */ private CellEditor cellEditor; - /** - * 标题别名 - */ - private Map headerAlias = new HashMap<>(); - // ------------------------------------------------------------------------------------------------------- Constructor start /** @@ -57,27 +51,29 @@ public class ExcelReader extends ExcelBase { } /** - * 构造 + * 构造(读写方式读取) * * @param bookFile Excel文件 * @param sheetIndex sheet序号,0表示第一个sheet */ public ExcelReader(File bookFile, int sheetIndex) { this(WorkbookUtil.createBook(bookFile, true), sheetIndex); + this.destFile = bookFile; } /** - * 构造 + * 构造(读写方式读取) * * @param bookFile Excel文件 * @param sheetName sheet名,第一个默认是sheet1 */ public ExcelReader(File bookFile, String sheetName) { this(WorkbookUtil.createBook(bookFile, true), sheetName); + this.destFile = bookFile; } /** - * 构造 + * 构造(只读方式读取) * * @param bookStream Excel文件的流 * @param sheetIndex sheet序号,0表示第一个sheet @@ -87,7 +83,7 @@ public class ExcelReader extends ExcelBase { } /** - * 构造 + * 构造(只读方式读取) * * @param bookStream Excel文件的流 * @param sheetName sheet名,第一个默认是sheet1 @@ -159,49 +155,6 @@ public class ExcelReader extends ExcelBase { this.cellEditor = cellEditor; return this; } - - /** - * 获得标题行的别名Map - * - * @return 别名Map - */ - public Map getHeaderAlias() { - return headerAlias; - } - - /** - * 设置标题行的别名Map - * - * @param headerAlias 别名Map - * @return this - */ - public ExcelReader setHeaderAlias(Map headerAlias) { - this.headerAlias = headerAlias; - return this; - } - - /** - * 增加标题别名 - * - * @param header 标题 - * @param alias 别名 - * @return this - */ - public ExcelReader addHeaderAlias(String header, String alias) { - this.headerAlias.put(header, alias); - return this; - } - - /** - * 去除标题别名 - * - * @param header 标题 - * @return this - */ - public ExcelReader removeHeaderAlias(String header) { - this.headerAlias.remove(header); - return this; - } // ------------------------------------------------------------------------------------------------------- Getters and Setters end /** @@ -452,13 +405,14 @@ public class ExcelReader extends ExcelBase { /** * 获取Excel写出器
- * 在读取Excel并做一定编辑后,获取写出器写出 + * 在读取Excel并做一定编辑后,获取写出器写出
+ * 注意,只读方式下,此方法无效 * * @return {@link ExcelWriter} * @since 4.0.6 */ public ExcelWriter getWriter() { - return new ExcelWriter(this.sheet); + return ExcelUtil.getWriter(this.destFile, this.sheet.getSheetName()); } // ------------------------------------------------------------------------------------------------------- Private methods start diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelWriter.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelWriter.java index 2b25f2420..cb7578b5e 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelWriter.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelWriter.java @@ -59,18 +59,10 @@ import java.util.concurrent.atomic.AtomicInteger; */ public class ExcelWriter extends ExcelBase { - /** - * 目标文件 - */ - protected File destFile; /** * 当前行 */ private AtomicInteger currentRow = new AtomicInteger(0); - /** - * 标题行别名 - */ - private Map headerAlias; /** * 是否只保留别名对应的字段 */ @@ -462,31 +454,26 @@ public class ExcelWriter extends ExcelBase { return this; } - /** - * 设置标题别名,key为Map中的key,value为别名 - * - * @param headerAlias 标题别名 - * @return this - * @since 3.2.1 - */ + //region header alias + @Override public ExcelWriter setHeaderAlias(Map headerAlias) { - this.headerAlias = headerAlias; // 新增别名时清除比较器缓存 this.aliasComparator = null; - return this; + return super.setHeaderAlias(headerAlias); } - /** - * 清空标题别名,key为Map中的key,value为别名 - * - * @return this - * @since 4.5.4 - */ + @Override public ExcelWriter clearHeaderAlias() { - this.headerAlias = null; // 清空别名时清除比较器缓存 this.aliasComparator = null; - return this; + return super.clearHeaderAlias(); + } + + @Override + public ExcelWriter addHeaderAlias(String name, String alias) { + // 新增别名时清除比较器缓存 + this.aliasComparator = null; + return super.addHeaderAlias(name, alias); } /** @@ -500,26 +487,7 @@ public class ExcelWriter extends ExcelBase { this.onlyAlias = isOnlyAlias; return this; } - - /** - * 增加标题别名 - * - * @param name 原标题 - * @param alias 别名 - * @return this - * @since 4.1.5 - */ - public ExcelWriter addHeaderAlias(String name, String alias) { - Map headerAlias = this.headerAlias; - if (null == headerAlias) { - headerAlias = new LinkedHashMap<>(); - } - this.headerAlias = headerAlias; - headerAlias.put(name, alias); - // 新增别名时清除比较器缓存 - this.aliasComparator = null; - return this; - } + //endregion /** * 设置窗口冻结,之前冻结的窗口会被覆盖,如果rowSplit为0表示取消冻结 diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/WorkbookUtil.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/WorkbookUtil.java index f693dc935..d76624458 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/WorkbookUtil.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/WorkbookUtil.java @@ -71,7 +71,7 @@ public class WorkbookUtil { } /** - * 创建工作簿,用于Excel写出 + * 创建工作簿,用于Excel写出(读写模式) * *
 	 * 1. excelFile为null时直接返回一个空的工作簿,默认xlsx格式
@@ -113,6 +113,7 @@ public class WorkbookUtil {
 	 * @param password  Excel工作簿密码,如果无密码传{@code null}
 	 * @param readOnly  是否只读模式打开,true:是(不可编辑),false:否(可编辑)
 	 * @return {@link Workbook}
+	 * @since 5.7.23
 	 */
 	public static Workbook createBook(File excelFile, String password, boolean readOnly) {
 		try {
@@ -123,7 +124,7 @@ public class WorkbookUtil {
 	}
 
 	/**
-	 * 创建或加载工作簿
+	 * 创建或加载工作簿(只读模式)
 	 *
 	 * @param in Excel输入流
 	 * @return {@link Workbook}
@@ -133,7 +134,7 @@ public class WorkbookUtil {
 	}
 
 	/**
-	 * 创建或加载工作簿
+	 * 创建或加载工作簿(只读模式)
 	 *
 	 * @param in       Excel输入流,使用完毕自动关闭流
 	 * @param password 密码
@@ -151,7 +152,7 @@ public class WorkbookUtil {
 	}
 
 	/**
-	 * 根据文件类型创建新的工作簿,文件路径
+	 * 创建新的空白Excel工作簿
 	 *
 	 * @param isXlsx 是否为xlsx格式的Excel
 	 * @return {@link Workbook}
@@ -184,7 +185,7 @@ public class WorkbookUtil {
 	 * @param excelFilePath Excel文件路径,绝对路径或相对于ClassPath路径
 	 * @param readOnly      是否只读模式打开,true:是(不可编辑),false:否(可编辑)
 	 * @return {@link SXSSFWorkbook}
-	 * @since 4.1.13
+	 * @since 5.7.23
 	 */
 	public static SXSSFWorkbook createSXSSFBook(String excelFilePath, boolean readOnly) {
 		return createSXSSFBook(FileUtil.file(excelFilePath), null, readOnly);
@@ -207,7 +208,7 @@ public class WorkbookUtil {
 	 * @param excelFile Excel文件
 	 * @param readOnly  是否只读模式打开,true:是(不可编辑),false:否(可编辑)
 	 * @return {@link SXSSFWorkbook}
-	 * @since 4.1.13
+	 * @since 5.7.23
 	 */
 	public static SXSSFWorkbook createSXSSFBook(File excelFile, boolean readOnly) {
 		return createSXSSFBook(excelFile, null, readOnly);
@@ -228,20 +229,20 @@ public class WorkbookUtil {
 
 
 	/**
-	 * 创建或加载SXSSFWorkbook工作簿
+	 * 创建或加载{@link SXSSFWorkbook}工作簿
 	 *
 	 * @param excelFile Excel文件
 	 * @param password  Excel工作簿密码,如果无密码传{@code null}
 	 * @param readOnly  是否只读模式打开,true:是(不可编辑),false:否(可编辑)
 	 * @return {@link SXSSFWorkbook}
-	 * @since 4.1.13
+	 * @since 5.7.23
 	 */
 	public static SXSSFWorkbook createSXSSFBook(File excelFile, String password, boolean readOnly) {
 		return toSXSSFBook(createBook(excelFile, password, readOnly));
 	}
 
 	/**
-	 * 创建或加载SXSSFWorkbook工作簿
+	 * 创建或加载{@link SXSSFWorkbook}工作簿(只读模式)
 	 *
 	 * @param in Excel输入流
 	 * @return {@link SXSSFWorkbook}
@@ -252,7 +253,7 @@ public class WorkbookUtil {
 	}
 
 	/**
-	 * 创建或加载SXSSFWorkbook工作簿
+	 * 创建或加载{@link SXSSFWorkbook}工作簿(只读模式)
 	 *
 	 * @param in       Excel输入流
 	 * @param password 密码
@@ -264,7 +265,7 @@ public class WorkbookUtil {
 	}
 
 	/**
-	 * 创建SXSSFWorkbook,用于大批量数据写出
+	 * 创建空的{@link SXSSFWorkbook},用于大批量数据写出
 	 *
 	 * @return {@link SXSSFWorkbook}
 	 * @since 4.1.13
@@ -274,16 +275,29 @@ public class WorkbookUtil {
 	}
 
 	/**
-	 * 创建SXSSFWorkbook,用于大批量数据写出
+	 * 创建空的{@link SXSSFWorkbook},用于大批量数据写出
 	 *
-	 * @param rowAccessWindowSize 在内存中的行数
-	 * @return {@link Workbook}
+	 * @param rowAccessWindowSize 在内存中的行数,-1表示不限制,此时需要手动刷出
+	 * @return {@link SXSSFWorkbook}
 	 * @since 4.1.13
 	 */
 	public static SXSSFWorkbook createSXSSFBook(int rowAccessWindowSize) {
 		return new SXSSFWorkbook(rowAccessWindowSize);
 	}
 
+	/**
+	 * 创建空的{@link SXSSFWorkbook},用于大批量数据写出
+	 *
+	 * @param rowAccessWindowSize 在内存中的行数,-1表示不限制,此时需要手动刷出
+	 * @param compressTmpFiles     是否使用Gzip压缩临时文件
+	 * @param useSharedStringsTable 是否使用共享字符串表,一般大量重复字符串时开启可节省内存
+	 * @return {@link SXSSFWorkbook}
+	 * @since 5.7.23
+	 */
+	public static SXSSFWorkbook createSXSSFBook(int rowAccessWindowSize, boolean compressTmpFiles, boolean useSharedStringsTable) {
+		return new SXSSFWorkbook(null, rowAccessWindowSize, compressTmpFiles, useSharedStringsTable);
+	}
+
 	/**
 	 * 将Excel Workbook刷出到输出流,不关闭流
 	 *
diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/reader/AbstractSheetReader.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/reader/AbstractSheetReader.java
index 9c03dc771..6a19331c9 100644
--- a/hutool-poi/src/main/java/cn/hutool/poi/excel/reader/AbstractSheetReader.java
+++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/reader/AbstractSheetReader.java
@@ -8,7 +8,7 @@ import cn.hutool.poi.excel.cell.CellEditor;
 import org.apache.poi.ss.usermodel.Sheet;
 
 import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -40,7 +40,7 @@ public abstract class AbstractSheetReader implements SheetReader {
 	/**
 	 * 标题别名
 	 */
-	private Map headerAlias = new HashMap<>();
+	private Map headerAlias;
 
 	/**
 	 * 构造
@@ -88,6 +88,11 @@ public abstract class AbstractSheetReader implements SheetReader {
 	 * @param alias  别名
 	 */
 	public void addHeaderAlias(String header, String alias) {
+		Map headerAlias = this.headerAlias;
+		if (null == headerAlias) {
+			headerAlias = new LinkedHashMap<>();
+		}
+		this.headerAlias = headerAlias;
 		this.headerAlias.put(header, alias);
 	}
 
@@ -124,7 +129,10 @@ public abstract class AbstractSheetReader implements SheetReader {
 		}
 
 		final String header = headerObj.toString();
-		return ObjectUtil.defaultIfNull(this.headerAlias.get(header), header);
+		if(null != this.headerAlias){
+			return ObjectUtil.defaultIfNull(this.headerAlias.get(header), header);
+		}
+		return header;
 	}
 
 	/**
diff --git a/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelUtilTest.java b/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelUtilTest.java
index 3d34cdeae..0be195739 100644
--- a/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelUtilTest.java
+++ b/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelUtilTest.java
@@ -3,10 +3,6 @@ package cn.hutool.poi.excel;
 import cn.hutool.poi.excel.cell.CellLocation;
 import org.junit.Assert;
 import org.junit.Test;
-import org.junit.Ignore;
-
-import java.util.List;
-import java.util.Map;
 
 public class ExcelUtilTest {
 
@@ -48,16 +44,10 @@ public class ExcelUtilTest {
 	}
 
 	@Test
-	@Ignore
 	public void readAndWriteTest() {
-		String filepath = "d:\\test/select.xls";
-		ExcelWriter writer = ExcelUtil.getWriter(filepath);
+		ExcelReader reader = ExcelUtil.getReader("aaa.xlsx");
+		ExcelWriter writer = reader.getWriter();
 		writer.writeCellValue(1, 2, "设置值");
 		writer.close();
-		ExcelReader reader = ExcelUtil.getReader(filepath);
-		List> map = reader.readAll();
-		reader.close();
-		Assert.assertNotNull(map);
-		Assert.assertFalse(map.isEmpty());
 	}
 }