ソースを参照

fix ExcelWriter bug

Looly 5 年 前
コミット
8fdc4af836

+ 1 - 0
CHANGELOG.md

@@ -11,6 +11,7 @@
 * 【setting】     修复Props.toBean方法null的问题
 * 【core   】     修复DataUtil.parseLocalDateTime无时间部分报错问题(issue#I1B18H@Gitee)
 * 【core   】     修复NetUtil.isUsableLocalPort()判断问题(issue#765@Github)
+* 【poi    】     修复ExcelWriter写出多个sheet错误的问题(issue#766@Github)
 
 -------------------------------------------------------------------------------------------------------------
 

+ 14 - 12
hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java

@@ -115,10 +115,8 @@ public class ExcelBase<T extends ExcelBase<T>> implements Closeable {
 	 * @return this
 	 * @since 4.0.10
 	 */
-	@SuppressWarnings("unchecked")
 	public T setSheet(String sheetName) {
-		WorkbookUtil.getOrCreateSheet(this.workbook, sheetName);
-		return (T) this;
+		return setSheet(WorkbookUtil.getOrCreateSheet(this.workbook, sheetName));
 	}
 
 	/**
@@ -129,16 +127,20 @@ public class ExcelBase<T extends ExcelBase<T>> implements Closeable {
 	 * @return this
 	 * @since 4.0.10
 	 */
-	@SuppressWarnings("unchecked")
 	public T setSheet(int sheetIndex) {
-		try {
-			this.sheet = this.workbook.getSheetAt(sheetIndex);
-		} catch (IllegalArgumentException e) {
-			this.sheet = this.workbook.createSheet();
-		}
-		if (null == this.sheet) {
-			this.sheet = this.workbook.createSheet();
-		}
+		return setSheet(WorkbookUtil.getOrCreateSheet(this.workbook, sheetIndex));
+	}
+
+	/**
+	 * 设置自定义Sheet
+	 *
+	 * @param sheet 自定义sheet,可以通过{@link WorkbookUtil#getOrCreateSheet(Workbook, String)} 创建
+	 * @return this
+	 * @since 5.2.1
+	 */
+	@SuppressWarnings("unchecked")
+	public T setSheet(Sheet sheet) {
+		this.sheet = sheet;
 		return (T) this;
 	}
 

+ 4 - 4
hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelWriter.java

@@ -804,7 +804,7 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
 		Map rowMap;
 		if (rowBean instanceof Map) {
 			if (MapUtil.isNotEmpty(this.headerAlias)) {
-				rowMap = MapUtil.newTreeMap((Map) rowBean, getInitedAliasComparator());
+				rowMap = MapUtil.newTreeMap((Map) rowBean, getCachedAliasComparator());
 			} else {
 				rowMap = (Map) rowBean;
 			}
@@ -813,7 +813,7 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
 				rowMap = BeanUtil.beanToMap(rowBean, new LinkedHashMap<>(), false, false);
 			} else {
 				// 别名存在情况下按照别名的添加顺序排序Bean数据
-				rowMap = BeanUtil.beanToMap(rowBean, new TreeMap<>(getInitedAliasComparator()), false, false);
+				rowMap = BeanUtil.beanToMap(rowBean, new TreeMap<>(getCachedAliasComparator()), false, false);
 			}
 		} else {
 			// 其它转为字符串默认输出
@@ -1047,7 +1047,7 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
 			return rowMap;
 		}
 
-		final Map<Object, Object> filteredMap = new LinkedHashMap<>();
+		final Map<Object, Object> filteredMap = MapUtil.newHashMap(rowMap.size(), true);
 		String aliasName;
 		for (Entry<?, ?> entry : rowMap.entrySet()) {
 			aliasName = this.headerAlias.get(StrUtil.toString(entry.getKey()));
@@ -1068,7 +1068,7 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
 	 * @return Comparator
 	 * @since 4.1.5
 	 */
-	private Comparator<String> getInitedAliasComparator() {
+	private Comparator<String> getCachedAliasComparator() {
 		if (MapUtil.isEmpty(this.headerAlias)) {
 			return null;
 		}

+ 23 - 0
hutool-poi/src/main/java/cn/hutool/poi/excel/WorkbookUtil.java

@@ -255,6 +255,29 @@ public class WorkbookUtil {
 	}
 
 	/**
+	 * 获取或者创建sheet表<br>
+	 * 自定义需要读取或写出的Sheet,如果给定的sheet不存在,创建之(命名为默认)<br>
+	 * 在读取中,此方法用于切换读取的sheet,在写出时,此方法用于新建或者切换sheet
+	 *
+	 * @param book 工作簿{@link Workbook}
+	 * @param sheetIndex 工作表序号
+	 * @return 工作表{@link Sheet}
+	 * @since 5.2.1
+	 */
+	public static Sheet getOrCreateSheet(Workbook book, int sheetIndex) {
+		Sheet sheet = null;
+		try {
+			sheet = book.getSheetAt(sheetIndex);
+		} catch (IllegalArgumentException ignore) {
+			//ignore
+		}
+		if (null == sheet) {
+			sheet = book.createSheet();
+		}
+		return sheet;
+	}
+
+	/**
 	 * 
 	 * sheet是否为空
 	 * 

+ 28 - 1
hutool-poi/src/test/java/cn/hutool/poi/excel/test/ExcelWriteTest.java

@@ -2,9 +2,12 @@ package cn.hutool.poi.excel.test;
 
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.TreeMap;
 
+import cn.hutool.core.util.IdUtil;
 import org.apache.poi.ss.usermodel.CellStyle;
 import org.apache.poi.ss.usermodel.FillPatternType;
 import org.apache.poi.ss.usermodel.Font;
@@ -410,7 +413,31 @@ public class ExcelWriteTest {
 		List<String> row = CollUtil.newArrayList("姓名", "加班日期", "下班时间", "加班时长", "餐补", "车补次数", "车补", "总计");
 		ExcelWriter overtimeWriter = ExcelUtil.getWriter("f:/excel/single_line.xlsx");
 		overtimeWriter.writeCellValue(3, 4, "AAAA");
-		overtimeWriter.addSelect(3, 4, row.toArray(new String[row.size()]));
+		overtimeWriter.addSelect(3, 4, row.toArray(new String[0]));
 		overtimeWriter.close();
 	}
+
+	@Test
+	@Ignore
+	public void writeMultiSheetTest(){
+		List<Map<String, Object>> rows = new LinkedList<>();
+		for (int i = 0; i < 10; i++) {
+			Map<String, Object> tempList = new TreeMap<>();
+			for (int j = 0; j < 10; j++) {
+				tempList.put(j + "", IdUtil.randomUUID());
+			}
+			rows.add(tempList);
+		}
+		ExcelWriter writer = ExcelUtil.getWriter("D:\\test\\multiSheet.xlsx", "正常数据");
+		writer.write(rows, true);
+		writer.autoSizeColumnAll();
+
+		writer.setSheet("当前重复数据");
+		writer.write(rows, true);
+		writer.autoSizeColumnAll();
+		writer.setSheet("历史重复数据");
+		writer.write(rows, true);
+		writer.autoSizeColumnAll();
+		writer.close();
+	}
 }