Browse Source

support mergeCell

Looly 6 years ago
parent
commit
83d6428db8

+ 2 - 0
CHANGELOG.md

@@ -6,6 +6,8 @@
 ## 5.1.5
 
 ### 新特性
+* 【poi  】     Excel合并单元格读取同一个值,不再为空
+
 ### Bug修复
 
 -------------------------------------------------------------------------------------------------------------

+ 3 - 1
hutool-db/src/main/java/cn/hutool/db/dialect/DialectName.java

@@ -1,7 +1,9 @@
 package cn.hutool.db.dialect;
 
 /**
- * 方言名
+ * 方言名<br>
+ * 方言枚举列出了Hutool支持的所有数据库方言
+ *
  * @author Looly
  *
  */

+ 2 - 2
hutool-db/src/main/java/cn/hutool/db/sql/SqlBuilder.java

@@ -531,7 +531,7 @@ public class SqlBuilder implements Builder<String>{
 	 * @return 插入或更新的数据库字段列表
 	 */
 	public String[] getFieldArray() {
-		return this.fields.toArray(new String[this.fields.size()]);
+		return this.fields.toArray(new String[0]);
 	}
 
 	/**
@@ -558,7 +558,7 @@ public class SqlBuilder implements Builder<String>{
 	 * @return 占位符对应的值列表
 	 */
 	public Object[] getParamValueArray() {
-		return this.paramValues.toArray(new Object[this.paramValues.size()]);
+		return this.paramValues.toArray(new Object[0]);
 	}
 
 	/**

+ 1 - 1
hutool-poi/src/main/java/cn/hutool/poi/excel/RowUtil.java

@@ -49,7 +49,7 @@ public class RowUtil {
 		if (length < 0) {
 			return new ArrayList<>(0);
 		}
-		final List<Object> cellValues = new ArrayList<>((int) length);
+		final List<Object> cellValues = new ArrayList<>(length);
 		Object cellValue;
 		boolean isAllNull = true;
 		for (short i = 0; i < length; i++) {

+ 80 - 8
hutool-poi/src/main/java/cn/hutool/poi/excel/cell/CellUtil.java

@@ -2,6 +2,7 @@ package cn.hutool.poi.excel.cell;
 
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.poi.excel.ExcelUtil;
 import cn.hutool.poi.excel.StyleSet;
 import cn.hutool.poi.excel.editors.TrimEditor;
 import org.apache.poi.ss.usermodel.Cell;
@@ -102,6 +103,12 @@ public class CellUtil {
 			cellType = cell.getCellTypeEnum();
 		}
 
+		if(CellType.BLANK == cellType){
+			// 空白单元格可能为合并单元格
+			cell = getMergedRegionCell(cell);
+			cellType = cell.getCellType();
+		}
+
 		Object value;
 		switch (cellType) {
 			case NUMERIC:
@@ -239,17 +246,42 @@ public class CellUtil {
 	/**
 	 * 判断指定的单元格是否是合并单元格
 	 *
-	 * @param sheet  {@link Sheet}
-	 * @param row    行号
-	 * @param column 列号
+	 * @param sheet       {@link Sheet}
+	 * @param locationRef 单元格地址标识符,例如A11,B5
 	 * @return 是否是合并单元格
+	 * @since 5.1.5
 	 */
-	public static boolean isMergedRegion(Sheet sheet, int row, int column) {
+	public static boolean isMergedRegion(Sheet sheet, String locationRef) {
+		final CellLocation cellLocation = ExcelUtil.toLocation(locationRef);
+		return isMergedRegion(sheet, cellLocation.getX(), cellLocation.getY());
+	}
+
+	/**
+	 * 判断指定的单元格是否是合并单元格
+	 *
+	 * @param cell {@link Cell}
+	 * @return 是否是合并单元格
+	 * @since 5.1.5
+	 */
+	public static boolean isMergedRegion(Cell cell) {
+		return isMergedRegion(cell.getSheet(), cell.getColumnIndex(), cell.getRowIndex());
+	}
+
+	/**
+	 * 判断指定的单元格是否是合并单元格
+	 *
+	 * @param sheet {@link Sheet}
+	 * @param x     列号,从0开始
+	 * @param y     行号,从0开始
+	 * @return 是否是合并单元格
+	 */
+	public static boolean isMergedRegion(Sheet sheet, int x, int y) {
 		final int sheetMergeCount = sheet.getNumMergedRegions();
 		CellRangeAddress ca;
 		for (int i = 0; i < sheetMergeCount; i++) {
 			ca = sheet.getMergedRegion(i);
-			if (row >= ca.getFirstRow() && row <= ca.getLastRow() && column >= ca.getFirstColumn() && column <= ca.getLastColumn()) {
+			if (y >= ca.getFirstRow() && y <= ca.getLastRow()
+					&& x >= ca.getFirstColumn() && x <= ca.getLastColumn()) {
 				return true;
 			}
 		}
@@ -288,13 +320,53 @@ public class CellUtil {
 	 * 获取合并单元格的值<br>
 	 * 传入的x,y坐标(列行数)可以是合并单元格范围内的任意一个单元格
 	 *
+	 * @param sheet       {@link Sheet}
+	 * @param locationRef 单元格地址标识符,例如A11,B5
+	 * @return 合并单元格的值
+	 * @since 5.1.5
+	 */
+	public static Object getMergedRegionValue(Sheet sheet, String locationRef) {
+		final CellLocation cellLocation = ExcelUtil.toLocation(locationRef);
+		return getMergedRegionValue(sheet, cellLocation.getX(), cellLocation.getY());
+	}
+
+	/**
+	 * 获取合并单元格的值<br>
+	 * 传入的x,y坐标(列行数)可以是合并单元格范围内的任意一个单元格
+	 *
 	 * @param sheet {@link Sheet}
-	 * @param y     行号,从0开始,可以是合并单元格范围中的任意一行
 	 * @param x     列号,从0开始,可以是合并单元格范围中的任意一列
+	 * @param y     行号,从0开始,可以是合并单元格范围中的任意一行
 	 * @return 合并单元格的值
 	 * @since 4.6.3
 	 */
 	public static Object getMergedRegionValue(Sheet sheet, int x, int y) {
+		return getCellValue(getMergedRegionCell(sheet, x, y));
+	}
+
+	/**
+	 * 获取合并单元格<br>
+	 * 传入的x,y坐标(列行数)可以是合并单元格范围内的任意一个单元格
+	 *
+	 * @param cell {@link Cell}
+	 * @return 合并单元格
+	 * @since 5.1.5
+	 */
+	public static Cell getMergedRegionCell(Cell cell) {
+		return getMergedRegionCell(cell.getSheet(), cell.getColumnIndex(), cell.getRowIndex());
+	}
+
+	/**
+	 * 获取合并单元格<br>
+	 * 传入的x,y坐标(列行数)可以是合并单元格范围内的任意一个单元格
+	 *
+	 * @param sheet {@link Sheet}
+	 * @param x     列号,从0开始,可以是合并单元格范围中的任意一列
+	 * @param y     行号,从0开始,可以是合并单元格范围中的任意一行
+	 * @return 合并单元格,如果非合并单元格,返回坐标对应的单元格
+	 * @since 5.1.5
+	 */
+	public static Cell getMergedRegionCell(Sheet sheet, int x, int y) {
 		final List<CellRangeAddress> addrs = sheet.getMergedRegions();
 
 		int firstColumn;
@@ -309,12 +381,12 @@ public class CellUtil {
 
 			if (y >= firstRow && y <= lastRow) {
 				if (x >= firstColumn && x <= lastColumn) {
-					return getCellValue(SheetUtil.getCell(sheet, firstRow, firstColumn));
+					return SheetUtil.getCell(sheet, firstRow, firstColumn);
 				}
 			}
 		}
 
-		return null;
+		return SheetUtil.getCell(sheet, y, x);
 	}
 
 	// -------------------------------------------------------------------------------------------------------------- Private method start

+ 10 - 11
hutool-poi/src/main/java/cn/hutool/poi/word/Word07Writer.java

@@ -1,21 +1,20 @@
 package cn.hutool.poi.word;
 
-import java.awt.Font;
-import java.io.Closeable;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
-import org.apache.poi.xwpf.usermodel.XWPFDocument;
-import org.apache.poi.xwpf.usermodel.XWPFParagraph;
-import org.apache.poi.xwpf.usermodel.XWPFRun;
-
 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.util.ArrayUtil;
+import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
+import org.apache.poi.xwpf.usermodel.XWPFRun;
+
+import java.awt.Font;
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
 
 /**
  * Word生成器

+ 17 - 9
hutool-poi/src/test/java/cn/hutool/poi/excel/test/ExcelReadTest.java

@@ -15,16 +15,15 @@ import cn.hutool.poi.excel.ExcelUtil;
 
 /**
  * Excel读取单元测试
- * 
- * @author Looly
  *
+ * @author Looly
  */
 public class ExcelReadTest {
-	
+
 	@Test
 	public void aliasTest() {
 		ExcelReader reader = ExcelUtil.getReader(ResourceUtil.getStream("alias.xlsx"));
-		
+
 		//读取单个单元格内容测试
 		Object value = reader.readCellValue(1, 2);
 		Assert.assertEquals("仓库", value);
@@ -77,13 +76,13 @@ public class ExcelReadTest {
 		Assert.assertEquals(11L, readAll.get(1).get(2));
 		Assert.assertEquals(41.5D, readAll.get(1).get(3));
 	}
-	
+
 	@Test
 	public void excelReadAsTextTest() {
 		ExcelReader reader = ExcelUtil.getReader(ResourceUtil.getStream("aaa.xlsx"));
 		Assert.assertNotNull(reader.readAsText(false));
 	}
-	
+
 	@Test
 	public void excel03ReadTest() {
 		ExcelReader reader = ExcelUtil.getReader(ResourceUtil.getStream("aaa.xls"));
@@ -141,7 +140,7 @@ public class ExcelReadTest {
 		Assert.assertEquals("男", all.get(0).getGender());
 		Assert.assertEquals(Integer.valueOf(11), all.get(0).getAge());
 	}
-	
+
 	@Test
 	@Ignore
 	public void excelReadToBeanListTest2() {
@@ -150,7 +149,7 @@ public class ExcelReadTest {
 		reader.addHeaderAlias("年龄", "age");
 		reader.addHeaderAlias("性别", "gender");
 
-		List<Person> all = reader.read(0,2, Person.class);
+		List<Person> all = reader.read(0, 2, Person.class);
 		for (Person person : all) {
 			Console.log(person);
 		}
@@ -193,11 +192,20 @@ public class ExcelReadTest {
 
 	@Test
 	@Ignore
-	public void readDoubleTest(){
+	public void readDoubleTest() {
 		ExcelReader reader = ExcelUtil.getReader("f:/test/doubleTest.xls");
 		final List<List<Object>> read = reader.read();
 		for (List<Object> list : read) {
 			Console.log(list.get(8));
 		}
 	}
+
+	@Test
+	public void mergeReadTest() {
+		final ExcelReader reader = ExcelUtil.getReader("merge_test.xlsx");
+		final List<List<Object>> read = reader.read();
+		// 验证合并单元格在两行中都可以取到值
+		Assert.assertEquals(11L, read.get(1).get(2));
+		Assert.assertEquals(11L, read.get(2).get(2));
+	}
 }

BIN
hutool-poi/src/test/resources/merge_test.xlsx