From a2e372b81b46fcda4289fb1081950174d6500838 Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 22 Mar 2020 17:36:07 +0800 Subject: [PATCH] fix poi bug --- CHANGELOG.md | 1 + .../java/cn/hutool/poi/excel/ExcelWriter.java | 82 +++++++++++------ .../hutool/poi/excel/test/ExcelWriteTest.java | 87 ++++++++++++++----- 3 files changed, 122 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b4c49518..d31f80d42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ * 【poi 】 修复添加图片尺寸的单位问题(issue#I1C2ER@Gitee) * 【setting】 修复getStr中逻辑问题(pr#113@Gitee) * 【json 】 修复JSONUtil.toXml汉字被编码的问题(pr#795@Gitee) +* 【poi 】 修复导出的Map列表中每个map长度不同导致的对应不一致的问题(issue#793@Gitee) ------------------------------------------------------------------------------------------------------------- ## 5.2.3 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 bb0661a7d..fe5234f24 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 @@ -1,18 +1,20 @@ package cn.hutool.poi.excel; -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.Charset; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeMap; -import java.util.concurrent.atomic.AtomicInteger; - +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.comparator.IndexedComparator; +import cn.hutool.core.io.FileUtil; +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.util.CharsetUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.core.util.URLUtil; import cn.hutool.poi.excel.cell.CellLocation; +import cn.hutool.poi.excel.cell.CellUtil; +import cn.hutool.poi.excel.style.Align; import org.apache.poi.hssf.usermodel.DVConstraint; import org.apache.poi.hssf.usermodel.HSSFDataValidation; import org.apache.poi.ss.usermodel.Cell; @@ -28,20 +30,18 @@ import org.apache.poi.xssf.usermodel.XSSFDataValidationConstraint; import org.apache.poi.xssf.usermodel.XSSFDataValidationHelper; import org.apache.poi.xssf.usermodel.XSSFSheet; -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.comparator.IndexedComparator; -import cn.hutool.core.io.FileUtil; -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.util.CharsetUtil; -import cn.hutool.core.util.IdUtil; -import cn.hutool.core.util.StrUtil; -import cn.hutool.core.util.URLUtil; -import cn.hutool.poi.excel.cell.CellUtil; -import cn.hutool.poi.excel.style.Align; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.Charset; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; /** * Excel 写入器
@@ -69,6 +69,8 @@ public class ExcelWriter extends ExcelBase { private Comparator aliasComparator; /** 样式集,定义不同类型数据样式 */ private StyleSet styleSet; + /** 标题项对应列号缓存,每次写标题更新此缓存 */ + private Map headLocationCache; // -------------------------------------------------------------------------- Constructor start /** @@ -193,6 +195,7 @@ public class ExcelWriter extends ExcelBase { *
 	 * 1. 当前行游标归零
 	 * 2. 清空别名比较器
+	 * 3. 清除标题缓存
 	 * 
* * @return this @@ -200,6 +203,7 @@ public class ExcelWriter extends ExcelBase { public ExcelWriter reset() { resetRow(); this.aliasComparator = null; + this.headLocationCache = null; return this; } @@ -776,7 +780,16 @@ public class ExcelWriter extends ExcelBase { */ public ExcelWriter writeHeadRow(Iterable rowData) { Assert.isFalse(this.isClosed, "ExcelWriter has been closed!"); - RowUtil.writeRow(this.sheet.createRow(this.currentRow.getAndIncrement()), rowData, this.styleSet, true); + this.headLocationCache = new ConcurrentHashMap<>(); + final Row row = this.sheet.createRow(this.currentRow.getAndIncrement()); + int i = 0; + Cell cell; + for (Object value : rowData) { + cell = row.createCell(i); + CellUtil.setCellValue(cell, value, this.styleSet, true); + this.headLocationCache.put(StrUtil.toString(value), i); + i++; + } return this; } @@ -842,7 +855,20 @@ public class ExcelWriter extends ExcelBase { if (isWriteKeyAsHead) { writeHeadRow(aliasMap.keySet()); } - writeRow(aliasMap.values()); + + // 如果已经写出标题行,根据标题行找对应的值写入 + if(MapUtil.isNotEmpty(this.headLocationCache)){ + final Row row = RowUtil.getOrCreateRow(this.sheet, this.currentRow.getAndIncrement()); + Integer location; + for (Entry entry : aliasMap.entrySet()) { + location = this.headLocationCache.get(StrUtil.toString(entry.getKey())); + if(null != location){ + CellUtil.setCellValue(CellUtil.getOrCreateCell(row, location), entry.getValue(), this.styleSet, false); + } + } + } else{ + writeRow(aliasMap.values()); + } return this; } diff --git a/hutool-poi/src/test/java/cn/hutool/poi/excel/test/ExcelWriteTest.java b/hutool-poi/src/test/java/cn/hutool/poi/excel/test/ExcelWriteTest.java index 88015027c..48028a61c 100644 --- a/hutool-poi/src/test/java/cn/hutool/poi/excel/test/ExcelWriteTest.java +++ b/hutool-poi/src/test/java/cn/hutool/poi/excel/test/ExcelWriteTest.java @@ -1,28 +1,29 @@ 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; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.junit.Ignore; -import org.junit.Test; - import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelWriter; import cn.hutool.poi.excel.style.StyleUtil; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.junit.Ignore; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; /** * 写出Excel单元测试 @@ -75,7 +76,7 @@ public class ExcelWriteTest { rows.add(ObjectUtil.clone(row1)); } - String filePath = "f:/test/writeTest.xlsx"; + String filePath = "d:/test/writeTest.xlsx"; FileUtil.del(filePath); // 通过工具类创建writer ExcelWriter writer = ExcelUtil.getWriter(filePath); @@ -105,7 +106,7 @@ public class ExcelWriteTest { List> rows = CollUtil.newArrayList(row1, row2, row3, row4, row5); // 通过工具类创建writer - ExcelWriter writer = ExcelUtil.getWriter("e:/mergeTest.xlsx"); + ExcelWriter writer = ExcelUtil.getWriter("d:/test/mergeTest.xlsx"); CellStyle style = writer.getStyleSet().getHeadCellStyle(); StyleUtil.setColor(style, IndexedColors.RED, FillPatternType.SOLID_FOREGROUND); @@ -143,7 +144,7 @@ public class ExcelWriteTest { ArrayList> rows = CollUtil.newArrayList(row1, row2); // 通过工具类创建writer - ExcelWriter writer = ExcelUtil.getWriter("f:/test/writeMapTest.xlsx"); + ExcelWriter writer = ExcelUtil.getWriter("d:/test/writeMapTest.xlsx"); // 合并单元格后的标题行,使用默认标题样式 writer.merge(row1.size() - 1, "一班成绩单"); @@ -254,7 +255,7 @@ public class ExcelWriteTest { List> rows = CollUtil.newArrayList(row1, row2); // 通过工具类创建writer - String file = "e:/writeMapAlias.xlsx"; + String file = "d:/test/writeMapAlias.xlsx"; FileUtil.del(file); ExcelWriter writer = ExcelUtil.getWriter(file); // 自定义标题 @@ -411,12 +412,30 @@ public class ExcelWriteTest { @Ignore public void addSelectTest() { List row = CollUtil.newArrayList("姓名", "加班日期", "下班时间", "加班时长", "餐补", "车补次数", "车补", "总计"); - ExcelWriter overtimeWriter = ExcelUtil.getWriter("f:/excel/single_line.xlsx"); + ExcelWriter overtimeWriter = ExcelUtil.getWriter("d:/test/single_line.xlsx"); overtimeWriter.writeCellValue(3, 4, "AAAA"); overtimeWriter.addSelect(3, 4, row.toArray(new String[0])); overtimeWriter.close(); } + @Test + @Ignore + public void addSelectTest2() { + ExcelWriter writer = ExcelUtil.getWriter("d:/test/select.xlsx"); + writer.writeCellValue(0, 0, "请选择科目"); + int firstRow = 0; + int lastRow = 0; + int firstCol = 0; + int lastCol = 0; + CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol); + writer.addSelect(addressList, "1001", "1002", "1003"); + + List rows = new ArrayList<>(); + writer.write(rows, true); + + writer.close(); + } + @Test @Ignore public void writeMultiSheetTest(){ @@ -440,4 +459,32 @@ public class ExcelWriteTest { writer.autoSizeColumnAll(); writer.close(); } + + @Test + @Ignore + public void writeMapsTest(){ + List> rows = new ArrayList<>(); + + Map map1 = new HashMap<>(); + map1.put("a",1); + map1.put("b",2); + map1.put("c",3); + map1.put("d",4); + map1.put("e",5); + Map map2 = new HashMap<>(); + map2.put("c",3); + map2.put("d",4); + map2.put("e",5); + Map map3 = new HashMap<>(); + map3.put("d",4); + map3.put("e",5); + + rows.add(map1); + rows.add(map2); + rows.add(map3); + + final ExcelWriter writer = ExcelUtil.getWriter("d:/test/rows.xlsx"); + writer.write(rows); + writer.close(); + } }