mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-30 20:57:59 +08:00
support mergeCell
This commit is contained in:
parent
3ba3690b0e
commit
83d6428db8
@ -6,6 +6,8 @@
|
||||
## 5.1.5
|
||||
|
||||
### 新特性
|
||||
* 【poi 】 Excel合并单元格读取同一个值,不再为空
|
||||
|
||||
### Bug修复
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
@ -1,7 +1,9 @@
|
||||
package cn.hutool.db.dialect;
|
||||
|
||||
/**
|
||||
* 方言名
|
||||
* 方言名<br>
|
||||
* 方言枚举列出了Hutool支持的所有数据库方言
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
|
@ -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]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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++) {
|
||||
|
@ -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, 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 row, int column) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -284,17 +316,57 @@ public class CellUtil {
|
||||
return sheet.addMergedRegion(cellRangeAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取合并单元格的值<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
|
||||
|
@ -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生成器
|
||||
|
@ -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
Normal file
BIN
hutool-poi/src/test/resources/merge_test.xlsx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user