From ca03fb3411997389a66f2bacc496c34fb715272d Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 24 Apr 2022 14:21:20 +0800 Subject: [PATCH] add test --- CHANGELOG.md | 3 +- .../java/cn/hutool/core/map/TableMap.java | 24 ++++++- .../cn/hutool/core/map/multi/RowKeyTable.java | 12 ++++ .../java/cn/hutool/core/map/multi/Table.java | 22 ++++++ .../java/cn/hutool/poi/excel/ExcelWriter.java | 5 +- .../cn/hutool/poi/excel/Issue2221Test.java | 70 ++++++++++++++++++- 6 files changed, 130 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bbbb54dfc..619887e0d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------------------- -# 5.8.0.M4 (2022-04-23) +# 5.8.0.M4 (2022-04-24) ### ❌不兼容特性 * 【json 】 【可能兼容问题】JSONArray删除部分构造 @@ -18,6 +18,7 @@ * 【json 】 添加ObjectMapper * 【core 】 CHINESE_NAME正则条件放宽(pr#599@Gitee) * 【extra 】 增加JakartaServletUtil(issue#2271@Github) +* 【poi 】 ExcelWriter支持重复别名的数据写出(issue#I53APY@Gitee) ### 🐞Bug修复 * 【core 】 修复StrUtil.firstNonX非static问题(issue#2257@Github) diff --git a/hutool-core/src/main/java/cn/hutool/core/map/TableMap.java b/hutool-core/src/main/java/cn/hutool/core/map/TableMap.java index f397b043a..326637a0a 100644 --- a/hutool-core/src/main/java/cn/hutool/core/map/TableMap.java +++ b/hutool-core/src/main/java/cn/hutool/core/map/TableMap.java @@ -27,9 +27,18 @@ import java.util.Set; public class TableMap implements Map, Iterable>, Serializable { private static final long serialVersionUID = 1L; + private static final int DEFAULT_CAPACITY = 10; + private final List keys; private final List values; + /** + * 构造 + */ + public TableMap() { + this(DEFAULT_CAPACITY); + } + /** * 构造 * @@ -85,11 +94,12 @@ public class TableMap implements Map, Iterable>, Ser /** * 根据value获得对应的key,只返回找到的第一个value对应的key值 + * * @param value 值 * @return 键 * @since 5.3.3 */ - public K getKey(V value){ + public K getKey(V value) { final int index = values.indexOf(value); if (index > -1 && index < keys.size()) { return keys.get(index); @@ -160,7 +170,17 @@ public class TableMap implements Map, Iterable>, Ser @Override public Set keySet() { - return new HashSet<>(keys); + return new HashSet<>(this.keys); + } + + /** + * 获取所有键,可重复,不可修改 + * + * @return 键列表 + * @since 5.8.0 + */ + public List keys() { + return Collections.unmodifiableList(this.keys); } @Override diff --git a/hutool-core/src/main/java/cn/hutool/core/map/multi/RowKeyTable.java b/hutool-core/src/main/java/cn/hutool/core/map/multi/RowKeyTable.java index 8c55c8c93..0b4bdda7e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/map/multi/RowKeyTable.java +++ b/hutool-core/src/main/java/cn/hutool/core/map/multi/RowKeyTable.java @@ -9,8 +9,11 @@ import cn.hutool.core.map.MapUtil; import java.util.AbstractMap; import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Set; @@ -198,6 +201,15 @@ public class RowKeyTable extends AbsTable { //endregion //region getColumn + @Override + public List columnKeys() { + final Collection> values = this.raw.values(); + final List result = new ArrayList<>(values.size() * 16); + for (Map map : values) { + map.forEach((key, value)->{result.add(key);}); + } + return result; + } @Override public Map getColumn(C columnKey) { diff --git a/hutool-core/src/main/java/cn/hutool/core/map/multi/Table.java b/hutool-core/src/main/java/cn/hutool/core/map/multi/Table.java index e0fb1c5f4..d60905e29 100644 --- a/hutool-core/src/main/java/cn/hutool/core/map/multi/Table.java +++ b/hutool-core/src/main/java/cn/hutool/core/map/multi/Table.java @@ -1,10 +1,13 @@ package cn.hutool.core.map.multi; +import cn.hutool.core.collection.ListUtil; import cn.hutool.core.lang.Opt; import cn.hutool.core.lang.func.Consumer3; import cn.hutool.core.map.MapUtil; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.Map; import java.util.Set; @@ -101,6 +104,25 @@ public interface Table extends Iterable> { return Opt.ofNullable(columnMap()).map(Map::keySet).get(); } + /** + * 返回所有列的key,列的key如果实现Map是可重复key,则返回对应不去重的List。 + * + * @return 列set + * @since 5.8.0 + */ + default List columnKeys() { + final Map> columnMap = columnMap(); + if(MapUtil.isEmpty(columnMap)){ + return ListUtil.empty(); + } + + final List result = new ArrayList<>(columnMap.size()); + for (Map.Entry> cMapEntry : columnMap.entrySet()) { + result.add(cMapEntry.getKey()); + } + return result; + } + /** * 返回列-行对应的map * 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 84bd7b77e..7087c14c0 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 @@ -8,6 +8,7 @@ import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IoUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.map.TableMap; import cn.hutool.core.map.multi.RowKeyTable; import cn.hutool.core.map.multi.Table; import cn.hutool.core.util.CharsetUtil; @@ -1049,7 +1050,7 @@ public class ExcelWriter extends ExcelBase { final Table aliasTable = aliasTable(rowMap); if (isWriteKeyAsHead) { // 写出标题行,并记录标题别名和列号的关系 - writeHeadRow(aliasTable.columnKeySet()); + writeHeadRow(aliasTable.columnKeys()); // 记录原数据key对应列号 int i = 0; for (Object key : aliasTable.rowKeySet()) { @@ -1341,7 +1342,7 @@ public class ExcelWriter extends ExcelBase { * @return 别名列表 */ private Table aliasTable(Map rowMap) { - final Table filteredTable = new RowKeyTable<>(new LinkedHashMap<>(), LinkedHashMap::new); + final Table filteredTable = new RowKeyTable<>(new LinkedHashMap<>(), TableMap::new); if (MapUtil.isEmpty(this.headerAlias)) { rowMap.forEach((key, value)-> filteredTable.put(key, key, value)); }else{ diff --git a/hutool-poi/src/test/java/cn/hutool/poi/excel/Issue2221Test.java b/hutool-poi/src/test/java/cn/hutool/poi/excel/Issue2221Test.java index 241cb3424..8b26a38eb 100644 --- a/hutool-poi/src/test/java/cn/hutool/poi/excel/Issue2221Test.java +++ b/hutool-poi/src/test/java/cn/hutool/poi/excel/Issue2221Test.java @@ -2,6 +2,10 @@ package cn.hutool.poi.excel; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.map.MapUtil; +import cn.hutool.poi.excel.style.StyleUtil; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.IndexedColors; import org.junit.Ignore; import org.junit.Test; @@ -10,9 +14,12 @@ import java.util.Map; public class Issue2221Test { + /** + * 设置重复别名的时候,通过原key获取写出位置 + */ @Test @Ignore - public void writeDuplicateHeaderAliasTest(){ + public void writeDuplicateHeaderAliasTest() { final ExcelWriter writer = ExcelUtil.getWriter("d:/test/duplicateAlias.xlsx"); // 设置别名 writer.addHeaderAlias("androidLc", "安卓"); @@ -28,4 +35,65 @@ public class Issue2221Test { writer.write(data, true); writer.close(); } + + @Test + @Ignore + public void writeDuplicateHeaderAliasTest2(){ + // 获取写Excel的流 + ExcelWriter writer = ExcelUtil.getBigWriter("d:/test/duplicateAlias2.xlsx"); + + // 设置头部的背景颜色 + StyleUtil.setColor(writer.getHeadCellStyle(), IndexedColors.GREY_50_PERCENT, FillPatternType.SOLID_FOREGROUND); + + //设置全局字体 + Font font = writer.createFont(); + font.setFontName("Microsoft YaHei"); + writer.getStyleSet().setFont(font, false); + + // 设置头部的字体为白颜色 + Font headerFont = writer.createFont(); + headerFont.setColor(IndexedColors.WHITE.getIndex()); + writer.getHeadCellStyle().setFont(headerFont); + + // 跳过多少行 + writer.passRows(1); + + // 冻结多少行 + writer.setFreezePane(2); + + // 设置别名 + writer.addHeaderAlias("date", "日期"); + writer.addHeaderAlias("androidLc", "安卓"); + writer.addHeaderAlias("iosLc", "iOS"); + writer.addHeaderAlias("androidAc", " 安卓"); + writer.addHeaderAlias("iosAc", " iOS"); + writer.setOnlyAlias(true); + + // 设置合并的单元格 + writer.merge(0, 1, 0, 0, "日期", true); + writer.merge(0, 0, 1, 2, "运行次数", true); + writer.merge(0, 0, 3, 4, "新增人数", true); + + // 写入数据 + List> data = ListUtil.of( + MapUtil.ofEntries( + MapUtil.entry("date", "2022-01-01"), + MapUtil.entry("androidLc", "1次"), + MapUtil.entry("iosLc", "2次"), + MapUtil.entry("androidAc", "3次"), + MapUtil.entry("iosAc", "4人")), + MapUtil.ofEntries( + MapUtil.entry("date", "2022-01-02"), + MapUtil.entry("androidLc", "5次"), + MapUtil.entry("iosLc", "6次"), + MapUtil.entry("androidAc", "7次"), + MapUtil.entry("iosAc", "8人")) + ); + + // 自动尺寸 + writer.autoSizeColumnAll(); + + writer.write(data, true); + writer.close(); + } }