mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
add ExcelConfig
This commit is contained in:
parent
103e48cf06
commit
6440c302a5
@ -31,18 +31,22 @@ import java.io.Closeable;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Excel基础类,用于抽象ExcelWriter和ExcelReader中共用部分的对象和方法
|
* Excel基础类,用于抽象ExcelWriter和ExcelReader中共用部分的对象和方法
|
||||||
*
|
*
|
||||||
* @param <T> 子类类型,用于返回this
|
* @param <T> 子类类型,用于返回this
|
||||||
|
* @param <C> ExcelConfig类型
|
||||||
* @author looly
|
* @author looly
|
||||||
* @since 4.1.4
|
* @since 4.1.4
|
||||||
*/
|
*/
|
||||||
public class ExcelBase<T extends ExcelBase<T>> implements Closeable {
|
public class ExcelBase<T extends ExcelBase<T, C>, C extends ExcelConfig> implements Closeable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excel配置,此项不为空
|
||||||
|
*/
|
||||||
|
protected C config;
|
||||||
/**
|
/**
|
||||||
* 是否被关闭
|
* 是否被关闭
|
||||||
*/
|
*/
|
||||||
@ -59,22 +63,40 @@ public class ExcelBase<T extends ExcelBase<T>> implements Closeable {
|
|||||||
* Excel中对应的Sheet
|
* Excel中对应的Sheet
|
||||||
*/
|
*/
|
||||||
protected Sheet sheet;
|
protected Sheet sheet;
|
||||||
/**
|
|
||||||
* 标题行别名
|
|
||||||
*/
|
|
||||||
protected Map<String, String> headerAlias;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
|
* @param config config
|
||||||
* @param sheet Excel中的sheet
|
* @param sheet Excel中的sheet
|
||||||
*/
|
*/
|
||||||
public ExcelBase(final Sheet sheet) {
|
public ExcelBase(final C config, final Sheet sheet) {
|
||||||
Assert.notNull(sheet, "No Sheet provided.");
|
this.config = Assert.notNull(config);
|
||||||
this.sheet = sheet;
|
this.sheet = Assert.notNull(sheet, "No Sheet provided.");
|
||||||
this.workbook = sheet.getWorkbook();
|
this.workbook = sheet.getWorkbook();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置Excel配置
|
||||||
|
*
|
||||||
|
* @param config Excel配置
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public T setConfig(final C config) {
|
||||||
|
this.config = config;
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Excel配置
|
||||||
|
*
|
||||||
|
* @return Excel配置
|
||||||
|
*/
|
||||||
|
public C getConfig() {
|
||||||
|
return this.config;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取Workbook
|
* 获取Workbook
|
||||||
*
|
*
|
||||||
@ -428,24 +450,26 @@ public class ExcelBase<T extends ExcelBase<T>> implements Closeable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建 {@link Hyperlink},默认内容(标签为链接地址本身)
|
* 创建 {@link Hyperlink},默认内容(标签为链接地址本身)
|
||||||
* @param type 链接类型
|
*
|
||||||
|
* @param type 链接类型
|
||||||
* @param address 链接地址
|
* @param address 链接地址
|
||||||
* @return 链接
|
* @return 链接
|
||||||
* @since 5.7.13
|
* @since 5.7.13
|
||||||
*/
|
*/
|
||||||
public Hyperlink createHyperlink(final HyperlinkType type, final String address){
|
public Hyperlink createHyperlink(final HyperlinkType type, final String address) {
|
||||||
return createHyperlink(type, address, address);
|
return createHyperlink(type, address, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建 {@link Hyperlink},默认内容
|
* 创建 {@link Hyperlink},默认内容
|
||||||
* @param type 链接类型
|
*
|
||||||
|
* @param type 链接类型
|
||||||
* @param address 链接地址
|
* @param address 链接地址
|
||||||
* @param label 标签,即单元格中显示的内容
|
* @param label 标签,即单元格中显示的内容
|
||||||
* @return 链接
|
* @return 链接
|
||||||
* @since 5.7.13
|
* @since 5.7.13
|
||||||
*/
|
*/
|
||||||
public Hyperlink createHyperlink(final HyperlinkType type, final String address, final String label){
|
public Hyperlink createHyperlink(final HyperlinkType type, final String address, final String label) {
|
||||||
final Hyperlink hyperlink = this.workbook.getCreationHelper().createHyperlink(type);
|
final Hyperlink hyperlink = this.workbook.getCreationHelper().createHyperlink(type);
|
||||||
hyperlink.setAddress(address);
|
hyperlink.setAddress(address);
|
||||||
hyperlink.setLabel(label);
|
hyperlink.setLabel(label);
|
||||||
@ -572,66 +596,4 @@ public class ExcelBase<T extends ExcelBase<T>> implements Closeable {
|
|||||||
this.workbook = null;
|
this.workbook = null;
|
||||||
this.isClosed = true;
|
this.isClosed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得标题行的别名Map
|
|
||||||
*
|
|
||||||
* @return 别名Map
|
|
||||||
*/
|
|
||||||
public Map<String, String> getHeaderAlias() {
|
|
||||||
return headerAlias;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置标题行的别名Map
|
|
||||||
*
|
|
||||||
* @param headerAlias 别名Map
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public T setHeaderAlias(final Map<String, String> headerAlias) {
|
|
||||||
this.headerAlias = headerAlias;
|
|
||||||
return (T) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 增加标题别名
|
|
||||||
*
|
|
||||||
* @param header 标题
|
|
||||||
* @param alias 别名
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public T addHeaderAlias(final String header, final String alias) {
|
|
||||||
Map<String, String> headerAlias = this.headerAlias;
|
|
||||||
if (null == headerAlias) {
|
|
||||||
headerAlias = new LinkedHashMap<>();
|
|
||||||
}
|
|
||||||
this.headerAlias = headerAlias;
|
|
||||||
this.headerAlias.put(header, alias);
|
|
||||||
return (T) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 去除标题别名
|
|
||||||
*
|
|
||||||
* @param header 标题
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public T removeHeaderAlias(final String header) {
|
|
||||||
this.headerAlias.remove(header);
|
|
||||||
return (T) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清空标题别名,key为Map中的key,value为别名
|
|
||||||
*
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public T clearHeaderAlias() {
|
|
||||||
this.headerAlias = null;
|
|
||||||
return (T) this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024. looly(loolly@aliyun.com)
|
||||||
|
* Hutool is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* https://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dromara.hutool.poi.excel;
|
||||||
|
|
||||||
|
import org.dromara.hutool.core.collection.CollUtil;
|
||||||
|
import org.dromara.hutool.core.util.ObjUtil;
|
||||||
|
import org.dromara.hutool.poi.excel.cell.CellEditor;
|
||||||
|
import org.dromara.hutool.poi.excel.cell.CellReferenceUtil;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excel读取和写出通用配置
|
||||||
|
*
|
||||||
|
* @author Looly
|
||||||
|
* @since 6.0.0
|
||||||
|
*/
|
||||||
|
public class ExcelConfig {
|
||||||
|
/**
|
||||||
|
* 标题行别名
|
||||||
|
*/
|
||||||
|
protected Map<String, String> headerAlias;
|
||||||
|
/**
|
||||||
|
* 单元格值处理接口
|
||||||
|
*/
|
||||||
|
protected CellEditor cellEditor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得标题行的别名Map
|
||||||
|
*
|
||||||
|
* @return 别名Map
|
||||||
|
*/
|
||||||
|
public Map<String, String> getHeaderAlias() {
|
||||||
|
return headerAlias;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置标题行的别名Map
|
||||||
|
*
|
||||||
|
* @param headerAlias 别名Map
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public ExcelConfig setHeaderAlias(final Map<String, String> headerAlias) {
|
||||||
|
this.headerAlias = headerAlias;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 增加标题别名
|
||||||
|
*
|
||||||
|
* @param header 标题
|
||||||
|
* @param alias 别名
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public ExcelConfig addHeaderAlias(final String header, final String alias) {
|
||||||
|
Map<String, String> headerAlias = this.headerAlias;
|
||||||
|
if (null == headerAlias) {
|
||||||
|
headerAlias = new LinkedHashMap<>();
|
||||||
|
this.headerAlias = headerAlias;
|
||||||
|
}
|
||||||
|
headerAlias.put(header, alias);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 去除标题别名
|
||||||
|
*
|
||||||
|
* @param header 标题
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public ExcelConfig removeHeaderAlias(final String header) {
|
||||||
|
this.headerAlias.remove(header);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空标题别名,key为Map中的key,value为别名
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public ExcelConfig clearHeaderAlias() {
|
||||||
|
return setHeaderAlias(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换标题别名,如果没有别名则使用原标题,当标题为空时,列号对应的字母便是header
|
||||||
|
*
|
||||||
|
* @param headerList 原标题列表
|
||||||
|
* @return 转换别名列表
|
||||||
|
*/
|
||||||
|
public List<String> aliasHeader(final List<Object> headerList) {
|
||||||
|
if (CollUtil.isEmpty(headerList)) {
|
||||||
|
return new ArrayList<>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
final int size = headerList.size();
|
||||||
|
final List<String> result = new ArrayList<>(size);
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
result.add(aliasHeader(headerList.get(i), i));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换标题别名,如果没有别名则使用原标题,当标题为空时,列号对应的字母便是header
|
||||||
|
*
|
||||||
|
* @param headerObj 原标题
|
||||||
|
* @param index 标题所在列号,当标题为空时,列号对应的字母便是header
|
||||||
|
* @return 转换别名列表
|
||||||
|
*/
|
||||||
|
public String aliasHeader(final Object headerObj, final int index) {
|
||||||
|
if (null == headerObj) {
|
||||||
|
return CellReferenceUtil.indexToColName(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String header = headerObj.toString();
|
||||||
|
if (null != this.headerAlias) {
|
||||||
|
return ObjUtil.defaultIfNull(this.headerAlias.get(header), header);
|
||||||
|
}
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单元格值处理器
|
||||||
|
*
|
||||||
|
* @return 单元格值处理器
|
||||||
|
*/
|
||||||
|
public CellEditor getCellEditor() {
|
||||||
|
return this.cellEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置单元格值处理逻辑<br>
|
||||||
|
* 当Excel中的值并不能满足我们的读取要求时,通过传入一个编辑接口,可以对单元格值自定义,例如对数字和日期类型值转换为字符串等
|
||||||
|
*
|
||||||
|
* @param cellEditor 单元格值处理接口
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public ExcelConfig setCellEditor(final CellEditor cellEditor) {
|
||||||
|
this.cellEditor = cellEditor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -73,7 +73,7 @@ public class RowUtil {
|
|||||||
*/
|
*/
|
||||||
public static List<Object> readRow(final Row row, final int startCellNumInclude, final int endCellNumInclude, final CellEditor cellEditor) {
|
public static List<Object> readRow(final Row row, final int startCellNumInclude, final int endCellNumInclude, final CellEditor cellEditor) {
|
||||||
if (null == row) {
|
if (null == row) {
|
||||||
return new ArrayList<>(0);
|
return ListUtil.empty();
|
||||||
}
|
}
|
||||||
final short rowLength = row.getLastCellNum();
|
final short rowLength = row.getLastCellNum();
|
||||||
if (rowLength < 0) {
|
if (rowLength < 0) {
|
||||||
|
@ -13,16 +13,8 @@
|
|||||||
package org.dromara.hutool.poi.excel.reader;
|
package org.dromara.hutool.poi.excel.reader;
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
import org.dromara.hutool.core.collection.CollUtil;
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
import org.dromara.hutool.core.util.ObjUtil;
|
import org.dromara.hutool.poi.excel.ExcelConfig;
|
||||||
import org.dromara.hutool.poi.excel.RowUtil;
|
|
||||||
import org.dromara.hutool.poi.excel.cell.CellEditor;
|
|
||||||
import org.dromara.hutool.poi.excel.cell.CellReferenceUtil;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 抽象{@link Sheet}数据读取实现
|
* 抽象{@link Sheet}数据读取实现
|
||||||
@ -33,26 +25,15 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractSheetReader<T> implements SheetReader<T> {
|
public abstract class AbstractSheetReader<T> implements SheetReader<T> {
|
||||||
|
|
||||||
/**
|
protected final CellRangeAddress cellRangeAddress;
|
||||||
* 读取起始行(包含,从0开始计数)
|
|
||||||
*/
|
|
||||||
protected final int startRowIndex;
|
|
||||||
/**
|
|
||||||
* 读取结束行(包含,从0开始计数)
|
|
||||||
*/
|
|
||||||
protected final int endRowIndex;
|
|
||||||
/**
|
/**
|
||||||
* 是否忽略空行
|
* 是否忽略空行
|
||||||
*/
|
*/
|
||||||
protected boolean ignoreEmptyRow = true;
|
protected boolean ignoreEmptyRow = true;
|
||||||
/**
|
/**
|
||||||
* 单元格值处理接口
|
* Excel配置
|
||||||
*/
|
*/
|
||||||
protected CellEditor cellEditor;
|
protected ExcelConfig config;
|
||||||
/**
|
|
||||||
* 标题别名
|
|
||||||
*/
|
|
||||||
private Map<String, String> headerAlias;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
@ -61,18 +42,28 @@ public abstract class AbstractSheetReader<T> implements SheetReader<T> {
|
|||||||
* @param endRowIndex 结束行(包含,从0开始计数)
|
* @param endRowIndex 结束行(包含,从0开始计数)
|
||||||
*/
|
*/
|
||||||
public AbstractSheetReader(final int startRowIndex, final int endRowIndex) {
|
public AbstractSheetReader(final int startRowIndex, final int endRowIndex) {
|
||||||
this.startRowIndex = startRowIndex;
|
this(new CellRangeAddress(
|
||||||
this.endRowIndex = endRowIndex;
|
Math.min(startRowIndex, endRowIndex),
|
||||||
|
Math.max(startRowIndex, endRowIndex),
|
||||||
|
0, Integer.MAX_VALUE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置单元格值处理逻辑<br>
|
* 构造
|
||||||
* 当Excel中的值并不能满足我们的读取要求时,通过传入一个编辑接口,可以对单元格值自定义,例如对数字和日期类型值转换为字符串等
|
|
||||||
*
|
*
|
||||||
* @param cellEditor 单元格值处理接口
|
* @param cellRangeAddress 读取范围
|
||||||
*/
|
*/
|
||||||
public void setCellEditor(final CellEditor cellEditor) {
|
public AbstractSheetReader(final CellRangeAddress cellRangeAddress) {
|
||||||
this.cellEditor = cellEditor;
|
this.cellRangeAddress = cellRangeAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置Excel配置
|
||||||
|
*
|
||||||
|
* @param config Excel配置
|
||||||
|
*/
|
||||||
|
public void setExcelConfig(final ExcelConfig config) {
|
||||||
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,78 +74,4 @@ public abstract class AbstractSheetReader<T> implements SheetReader<T> {
|
|||||||
public void setIgnoreEmptyRow(final boolean ignoreEmptyRow) {
|
public void setIgnoreEmptyRow(final boolean ignoreEmptyRow) {
|
||||||
this.ignoreEmptyRow = ignoreEmptyRow;
|
this.ignoreEmptyRow = ignoreEmptyRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置标题行的别名Map
|
|
||||||
*
|
|
||||||
* @param headerAlias 别名Map
|
|
||||||
*/
|
|
||||||
public void setHeaderAlias(final Map<String, String> headerAlias) {
|
|
||||||
this.headerAlias = headerAlias;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 增加标题别名
|
|
||||||
*
|
|
||||||
* @param header 标题
|
|
||||||
* @param alias 别名
|
|
||||||
*/
|
|
||||||
public void addHeaderAlias(final String header, final String alias) {
|
|
||||||
Map<String, String> headerAlias = this.headerAlias;
|
|
||||||
if (null == headerAlias) {
|
|
||||||
headerAlias = new LinkedHashMap<>();
|
|
||||||
}
|
|
||||||
this.headerAlias = headerAlias;
|
|
||||||
this.headerAlias.put(header, alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 转换标题别名,如果没有别名则使用原标题,当标题为空时,列号对应的字母便是header
|
|
||||||
*
|
|
||||||
* @param headerList 原标题列表
|
|
||||||
* @return 转换别名列表
|
|
||||||
*/
|
|
||||||
protected List<String> aliasHeader(final List<Object> headerList) {
|
|
||||||
if (CollUtil.isEmpty(headerList)) {
|
|
||||||
return new ArrayList<>(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int size = headerList.size();
|
|
||||||
final ArrayList<String> result = new ArrayList<>(size);
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
result.add(aliasHeader(headerList.get(i), i));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 转换标题别名,如果没有别名则使用原标题,当标题为空时,列号对应的字母便是header
|
|
||||||
*
|
|
||||||
* @param headerObj 原标题
|
|
||||||
* @param index 标题所在列号,当标题为空时,列号对应的字母便是header
|
|
||||||
* @return 转换别名列表
|
|
||||||
* @since 4.3.2
|
|
||||||
*/
|
|
||||||
protected String aliasHeader(final Object headerObj, final int index) {
|
|
||||||
if (null == headerObj) {
|
|
||||||
return CellReferenceUtil.indexToColName(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
final String header = headerObj.toString();
|
|
||||||
if(null != this.headerAlias){
|
|
||||||
return ObjUtil.defaultIfNull(this.headerAlias.get(header), header);
|
|
||||||
}
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取某一行数据
|
|
||||||
*
|
|
||||||
* @param sheet {@link Sheet}
|
|
||||||
* @param rowIndex 行号,从0开始
|
|
||||||
* @return 一行数据
|
|
||||||
*/
|
|
||||||
protected List<Object> readRow(final Sheet sheet, final int rowIndex) {
|
|
||||||
return RowUtil.readRow(sheet.getRow(rowIndex), this.cellEditor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
|
|
||||||
package org.dromara.hutool.poi.excel.reader;
|
package org.dromara.hutool.poi.excel.reader;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
import org.dromara.hutool.core.bean.BeanUtil;
|
import org.dromara.hutool.core.bean.BeanUtil;
|
||||||
import org.dromara.hutool.core.bean.copier.CopyOptions;
|
import org.dromara.hutool.core.bean.copier.CopyOptions;
|
||||||
import org.dromara.hutool.poi.excel.cell.CellEditor;
|
import org.dromara.hutool.poi.excel.ExcelConfig;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -63,13 +63,12 @@ public class BeanSheetReader<T> implements SheetReader<List<T>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置单元格值处理逻辑<br>
|
* 设置Excel配置
|
||||||
* 当Excel中的值并不能满足我们的读取要求时,通过传入一个编辑接口,可以对单元格值自定义,例如对数字和日期类型值转换为字符串等
|
|
||||||
*
|
*
|
||||||
* @param cellEditor 单元格值处理接口
|
* @param config Excel配置
|
||||||
*/
|
*/
|
||||||
public void setCellEditor(final CellEditor cellEditor) {
|
public void setExcelConfig(final ExcelConfig config) {
|
||||||
this.mapSheetReader.setCellEditor(cellEditor);
|
this.mapSheetReader.setExcelConfig(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,23 +79,4 @@ public class BeanSheetReader<T> implements SheetReader<List<T>> {
|
|||||||
public void setIgnoreEmptyRow(final boolean ignoreEmptyRow) {
|
public void setIgnoreEmptyRow(final boolean ignoreEmptyRow) {
|
||||||
this.mapSheetReader.setIgnoreEmptyRow(ignoreEmptyRow);
|
this.mapSheetReader.setIgnoreEmptyRow(ignoreEmptyRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置标题行的别名Map
|
|
||||||
*
|
|
||||||
* @param headerAlias 别名Map
|
|
||||||
*/
|
|
||||||
public void setHeaderAlias(final Map<String, String> headerAlias) {
|
|
||||||
this.mapSheetReader.setHeaderAlias(headerAlias);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 增加标题别名
|
|
||||||
*
|
|
||||||
* @param header 标题
|
|
||||||
* @param alias 别名
|
|
||||||
*/
|
|
||||||
public void addHeaderAlias(final String header, final String alias) {
|
|
||||||
this.mapSheetReader.addHeaderAlias(header, alias);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,10 @@
|
|||||||
|
|
||||||
package org.dromara.hutool.poi.excel.reader;
|
package org.dromara.hutool.poi.excel.reader;
|
||||||
|
|
||||||
import org.dromara.hutool.poi.excel.cell.CellUtil;
|
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
|
import org.dromara.hutool.poi.excel.cell.CellEditor;
|
||||||
|
import org.dromara.hutool.poi.excel.cell.CellUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -26,8 +28,6 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class ColumnSheetReader extends AbstractSheetReader<List<Object>> {
|
public class ColumnSheetReader extends AbstractSheetReader<List<Object>> {
|
||||||
|
|
||||||
private final int columnIndex;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
@ -36,17 +36,18 @@ public class ColumnSheetReader extends AbstractSheetReader<List<Object>> {
|
|||||||
* @param endRowIndex 结束行(包含,从0开始计数)
|
* @param endRowIndex 结束行(包含,从0开始计数)
|
||||||
*/
|
*/
|
||||||
public ColumnSheetReader(final int columnIndex, final int startRowIndex, final int endRowIndex) {
|
public ColumnSheetReader(final int columnIndex, final int startRowIndex, final int endRowIndex) {
|
||||||
super(startRowIndex, endRowIndex);
|
super(new CellRangeAddress(startRowIndex, endRowIndex, columnIndex, columnIndex));
|
||||||
this.columnIndex = columnIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Object> read(final Sheet sheet) {
|
public List<Object> read(final Sheet sheet) {
|
||||||
final List<Object> resultList = new ArrayList<>();
|
final List<Object> resultList = new ArrayList<>();
|
||||||
|
|
||||||
final int startRowIndex = Math.max(this.startRowIndex, sheet.getFirstRowNum());// 读取起始行(包含)
|
final int startRowIndex = Math.max(this.cellRangeAddress.getFirstRow(), sheet.getFirstRowNum());// 读取起始行(包含)
|
||||||
final int endRowIndex = Math.min(this.endRowIndex, sheet.getLastRowNum());// 读取结束行(包含)
|
final int endRowIndex = Math.min(this.cellRangeAddress.getLastRow(), sheet.getLastRowNum());// 读取结束行(包含)
|
||||||
|
final int columnIndex = this.cellRangeAddress.getFirstColumn();
|
||||||
|
|
||||||
|
final CellEditor cellEditor = this.config.getCellEditor();
|
||||||
Object value;
|
Object value;
|
||||||
for (int i = startRowIndex; i <= endRowIndex; i++) {
|
for (int i = startRowIndex; i <= endRowIndex; i++) {
|
||||||
value = CellUtil.getCellValue(CellUtil.getCell(sheet.getRow(i), columnIndex), cellEditor);
|
value = CellUtil.getCellValue(CellUtil.getCell(sheet.getRow(i), columnIndex), cellEditor);
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024. looly(loolly@aliyun.com)
|
||||||
|
* Hutool is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* https://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dromara.hutool.poi.excel.reader;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.dromara.hutool.core.func.SerBiConsumer;
|
||||||
|
import org.dromara.hutool.poi.excel.cell.CellUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取Excel的Sheet,使用Consumer方式处理单元格
|
||||||
|
*
|
||||||
|
* @author Looly
|
||||||
|
* @since 6.0.0
|
||||||
|
*/
|
||||||
|
public class ConsumerSheetReader extends AbstractSheetReader<Void> {
|
||||||
|
|
||||||
|
|
||||||
|
private final SerBiConsumer<Cell, Object> cellHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造
|
||||||
|
*
|
||||||
|
* @param startRowIndex 起始行(包含,从0开始计数)
|
||||||
|
* @param endRowIndex 结束行(包含,从0开始计数)
|
||||||
|
* @param cellHandler 单元格处理器,用于处理读到的单元格及其数据
|
||||||
|
*/
|
||||||
|
public ConsumerSheetReader(final int startRowIndex, final int endRowIndex, final SerBiConsumer<Cell, Object> cellHandler) {
|
||||||
|
super(startRowIndex, endRowIndex);
|
||||||
|
this.cellHandler = cellHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void read(final Sheet sheet) {
|
||||||
|
final int startRowIndex = Math.max(this.cellRangeAddress.getFirstRow(), sheet.getFirstRowNum());// 读取起始行(包含)
|
||||||
|
final int endRowIndex = Math.min(this.cellRangeAddress.getLastRow(), sheet.getLastRowNum());// 读取结束行(包含)
|
||||||
|
|
||||||
|
Row row;
|
||||||
|
for (int y = startRowIndex; y <= endRowIndex; y++) {
|
||||||
|
row = sheet.getRow(y);
|
||||||
|
if (null != row) {
|
||||||
|
final short startColumnIndex = (short) Math.max(this.cellRangeAddress.getFirstColumn(), row.getFirstCellNum());
|
||||||
|
final short endColumnIndex = (short) Math.min(this.cellRangeAddress.getLastColumn(), row.getLastCellNum());
|
||||||
|
Cell cell;
|
||||||
|
for (short x = startColumnIndex; x < endColumnIndex; x++) {
|
||||||
|
cell = row.getCell(x);
|
||||||
|
cellHandler.accept(cell, CellUtil.getCellValue(cell));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -12,18 +12,17 @@
|
|||||||
|
|
||||||
package org.dromara.hutool.poi.excel.reader;
|
package org.dromara.hutool.poi.excel.reader;
|
||||||
|
|
||||||
import org.dromara.hutool.core.io.IoUtil;
|
|
||||||
import org.dromara.hutool.core.io.file.FileUtil;
|
|
||||||
import org.dromara.hutool.core.lang.Assert;
|
|
||||||
import org.dromara.hutool.core.func.SerBiConsumer;
|
|
||||||
import org.dromara.hutool.poi.excel.*;
|
|
||||||
import org.dromara.hutool.poi.excel.cell.CellEditor;
|
|
||||||
import org.dromara.hutool.poi.excel.cell.CellUtil;
|
|
||||||
import org.apache.poi.ss.extractor.ExcelExtractor;
|
import org.apache.poi.ss.extractor.ExcelExtractor;
|
||||||
import org.apache.poi.ss.usermodel.Cell;
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
import org.apache.poi.ss.usermodel.Row;
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.dromara.hutool.core.func.SerBiConsumer;
|
||||||
|
import org.dromara.hutool.core.io.IoUtil;
|
||||||
|
import org.dromara.hutool.core.io.file.FileUtil;
|
||||||
|
import org.dromara.hutool.core.lang.Assert;
|
||||||
|
import org.dromara.hutool.poi.excel.*;
|
||||||
|
import org.dromara.hutool.poi.excel.cell.CellUtil;
|
||||||
import org.dromara.hutool.poi.excel.writer.ExcelWriter;
|
import org.dromara.hutool.poi.excel.writer.ExcelWriter;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -38,16 +37,12 @@ import java.util.Map;
|
|||||||
* @author Looly
|
* @author Looly
|
||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
*/
|
*/
|
||||||
public class ExcelReader extends ExcelBase<ExcelReader> {
|
public class ExcelReader extends ExcelBase<ExcelReader, ExcelConfig> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否忽略空行
|
* 是否忽略空行
|
||||||
*/
|
*/
|
||||||
private boolean ignoreEmptyRow = true;
|
private boolean ignoreEmptyRow = true;
|
||||||
/**
|
|
||||||
* 单元格值处理接口
|
|
||||||
*/
|
|
||||||
private CellEditor cellEditor;
|
|
||||||
// ------------------------------------------------------------------------------------------------------- Constructor start
|
// ------------------------------------------------------------------------------------------------------- Constructor start
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,7 +134,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
* @param sheet Excel中的sheet
|
* @param sheet Excel中的sheet
|
||||||
*/
|
*/
|
||||||
public ExcelReader(final Sheet sheet) {
|
public ExcelReader(final Sheet sheet) {
|
||||||
super(sheet);
|
super(new ExcelConfig(), sheet);
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------------- Constructor end
|
// ------------------------------------------------------------------------------------------------------- Constructor end
|
||||||
|
|
||||||
@ -165,17 +160,6 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置单元格值处理逻辑<br>
|
|
||||||
* 当Excel中的值并不能满足我们的读取要求时,通过传入一个编辑接口,可以对单元格值自定义,例如对数字和日期类型值转换为字符串等
|
|
||||||
*
|
|
||||||
* @param cellEditor 单元格值处理接口
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
public ExcelReader setCellEditor(final CellEditor cellEditor) {
|
|
||||||
this.cellEditor = cellEditor;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
// ------------------------------------------------------------------------------------------------------- Getters and Setters end
|
// ------------------------------------------------------------------------------------------------------- Getters and Setters end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -220,9 +204,8 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
*/
|
*/
|
||||||
public List<List<Object>> read(final int startRowIndex, final int endRowIndex, final boolean aliasFirstLine) {
|
public List<List<Object>> read(final int startRowIndex, final int endRowIndex, final boolean aliasFirstLine) {
|
||||||
final ListSheetReader reader = new ListSheetReader(startRowIndex, endRowIndex, aliasFirstLine);
|
final ListSheetReader reader = new ListSheetReader(startRowIndex, endRowIndex, aliasFirstLine);
|
||||||
reader.setCellEditor(this.cellEditor);
|
reader.setExcelConfig(this.config);
|
||||||
reader.setIgnoreEmptyRow(this.ignoreEmptyRow);
|
reader.setIgnoreEmptyRow(this.ignoreEmptyRow);
|
||||||
reader.setHeaderAlias(headerAlias);
|
|
||||||
return read(reader);
|
return read(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,9 +232,8 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
*/
|
*/
|
||||||
public List<Object> readColumn(final int columnIndex, final int startRowIndex, final int endRowIndex) {
|
public List<Object> readColumn(final int columnIndex, final int startRowIndex, final int endRowIndex) {
|
||||||
final ColumnSheetReader reader = new ColumnSheetReader(columnIndex, startRowIndex, endRowIndex);
|
final ColumnSheetReader reader = new ColumnSheetReader(columnIndex, startRowIndex, endRowIndex);
|
||||||
reader.setCellEditor(this.cellEditor);
|
reader.setExcelConfig(this.config);
|
||||||
reader.setIgnoreEmptyRow(this.ignoreEmptyRow);
|
reader.setIgnoreEmptyRow(this.ignoreEmptyRow);
|
||||||
reader.setHeaderAlias(headerAlias);
|
|
||||||
return read(reader);
|
return read(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,25 +257,13 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
* @param cellHandler 单元格处理器,用于处理读到的单元格及其数据
|
* @param cellHandler 单元格处理器,用于处理读到的单元格及其数据
|
||||||
* @since 5.3.8
|
* @since 5.3.8
|
||||||
*/
|
*/
|
||||||
public void read(int startRowIndex, int endRowIndex, final SerBiConsumer<Cell, Object> cellHandler) {
|
public void read(final int startRowIndex, final int endRowIndex, final SerBiConsumer<Cell, Object> cellHandler) {
|
||||||
checkNotClosed();
|
checkNotClosed();
|
||||||
|
|
||||||
startRowIndex = Math.max(startRowIndex, this.sheet.getFirstRowNum());// 读取起始行(包含)
|
final ConsumerSheetReader reader = new ConsumerSheetReader(startRowIndex, endRowIndex, cellHandler);
|
||||||
endRowIndex = Math.min(endRowIndex, this.sheet.getLastRowNum());// 读取结束行(包含)
|
reader.setExcelConfig(this.config);
|
||||||
|
reader.setIgnoreEmptyRow(this.ignoreEmptyRow);
|
||||||
Row row;
|
reader.read(sheet);
|
||||||
short columnSize;
|
|
||||||
for (int y = startRowIndex; y <= endRowIndex; y++) {
|
|
||||||
row = this.sheet.getRow(y);
|
|
||||||
if (null != row) {
|
|
||||||
columnSize = row.getLastCellNum();
|
|
||||||
Cell cell;
|
|
||||||
for (short x = 0; x < columnSize; x++) {
|
|
||||||
cell = row.getCell(x);
|
|
||||||
cellHandler.accept(cell, CellUtil.getCellValue(cell));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -317,9 +287,8 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
*/
|
*/
|
||||||
public List<Map<String, Object>> read(final int headerRowIndex, final int startRowIndex, final int endRowIndex) {
|
public List<Map<String, Object>> read(final int headerRowIndex, final int startRowIndex, final int endRowIndex) {
|
||||||
final MapSheetReader reader = new MapSheetReader(headerRowIndex, startRowIndex, endRowIndex);
|
final MapSheetReader reader = new MapSheetReader(headerRowIndex, startRowIndex, endRowIndex);
|
||||||
reader.setCellEditor(this.cellEditor);
|
reader.setExcelConfig(this.config);
|
||||||
reader.setIgnoreEmptyRow(this.ignoreEmptyRow);
|
reader.setIgnoreEmptyRow(this.ignoreEmptyRow);
|
||||||
reader.setHeaderAlias(headerAlias);
|
|
||||||
return read(reader);
|
return read(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,9 +329,8 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
*/
|
*/
|
||||||
public <T> List<T> read(final int headerRowIndex, final int startRowIndex, final int endRowIndex, final Class<T> beanType) {
|
public <T> List<T> read(final int headerRowIndex, final int startRowIndex, final int endRowIndex, final Class<T> beanType) {
|
||||||
final BeanSheetReader<T> reader = new BeanSheetReader<>(headerRowIndex, startRowIndex, endRowIndex, beanType);
|
final BeanSheetReader<T> reader = new BeanSheetReader<>(headerRowIndex, startRowIndex, endRowIndex, beanType);
|
||||||
reader.setCellEditor(this.cellEditor);
|
reader.setExcelConfig(this.config);
|
||||||
reader.setIgnoreEmptyRow(this.ignoreEmptyRow);
|
reader.setIgnoreEmptyRow(this.ignoreEmptyRow);
|
||||||
reader.setHeaderAlias(headerAlias);
|
|
||||||
return read(reader);
|
return read(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,7 +389,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
* @since 4.0.3
|
* @since 4.0.3
|
||||||
*/
|
*/
|
||||||
public Object readCellValue(final int x, final int y) {
|
public Object readCellValue(final int x, final int y) {
|
||||||
return CellUtil.getCellValue(getCell(x, y), this.cellEditor);
|
return CellUtil.getCellValue(getCell(x, y), this.config.getCellEditor());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -452,7 +420,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
* @return 单元格值列表
|
* @return 单元格值列表
|
||||||
*/
|
*/
|
||||||
private List<Object> readRow(final Row row) {
|
private List<Object> readRow(final Row row) {
|
||||||
return RowUtil.readRow(row, this.cellEditor);
|
return RowUtil.readRow(row, this.config.getCellEditor());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +15,8 @@ package org.dromara.hutool.poi.excel.reader;
|
|||||||
import org.dromara.hutool.core.collection.CollUtil;
|
import org.dromara.hutool.core.collection.CollUtil;
|
||||||
import org.dromara.hutool.core.convert.Convert;
|
import org.dromara.hutool.core.convert.Convert;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.dromara.hutool.poi.excel.RowUtil;
|
||||||
|
import org.dromara.hutool.poi.excel.cell.CellEditor;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -46,15 +48,17 @@ public class ListSheetReader extends AbstractSheetReader<List<List<Object>>> {
|
|||||||
public List<List<Object>> read(final Sheet sheet) {
|
public List<List<Object>> read(final Sheet sheet) {
|
||||||
final List<List<Object>> resultList = new ArrayList<>();
|
final List<List<Object>> resultList = new ArrayList<>();
|
||||||
|
|
||||||
final int startRowIndex = Math.max(this.startRowIndex, sheet.getFirstRowNum());// 读取起始行(包含)
|
final int startRowIndex = Math.max(this.cellRangeAddress.getFirstRow(), sheet.getFirstRowNum());// 读取起始行(包含)
|
||||||
final int endRowIndex = Math.min(this.endRowIndex, sheet.getLastRowNum());// 读取结束行(包含)
|
final int endRowIndex = Math.min(this.cellRangeAddress.getLastRow(), sheet.getLastRowNum());// 读取结束行(包含)
|
||||||
|
|
||||||
List<Object> rowList;
|
List<Object> rowList;
|
||||||
|
final CellEditor cellEditor = this.config.getCellEditor();
|
||||||
for (int i = startRowIndex; i <= endRowIndex; i++) {
|
for (int i = startRowIndex; i <= endRowIndex; i++) {
|
||||||
rowList = readRow(sheet, i);
|
rowList = RowUtil.readRow(sheet.getRow(i), cellEditor);
|
||||||
if (CollUtil.isNotEmpty(rowList) || !ignoreEmptyRow) {
|
if (CollUtil.isNotEmpty(rowList) || !ignoreEmptyRow) {
|
||||||
if (aliasFirstLine && i == startRowIndex) {
|
if (aliasFirstLine && i == startRowIndex) {
|
||||||
// 第一行作为标题行,替换别名
|
// 第一行作为标题行,替换别名
|
||||||
rowList = Convert.toList(Object.class, aliasHeader(rowList));
|
rowList = Convert.toList(Object.class, this.config.aliasHeader(rowList));
|
||||||
}
|
}
|
||||||
resultList.add(rowList);
|
resultList.add(rowList);
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import org.dromara.hutool.core.collection.iter.IterUtil;
|
|||||||
import org.dromara.hutool.core.collection.ListUtil;
|
import org.dromara.hutool.core.collection.ListUtil;
|
||||||
import org.dromara.hutool.core.text.StrUtil;
|
import org.dromara.hutool.core.text.StrUtil;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.dromara.hutool.poi.excel.RowUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -57,15 +58,18 @@ public class MapSheetReader extends AbstractSheetReader<List<Map<String, Object>
|
|||||||
throw new IndexOutOfBoundsException(StrUtil.format("Header row index {} is lower than first row index {}.", headerRowIndex, firstRowNum));
|
throw new IndexOutOfBoundsException(StrUtil.format("Header row index {} is lower than first row index {}.", headerRowIndex, firstRowNum));
|
||||||
} else if (headerRowIndex > lastRowNum) {
|
} else if (headerRowIndex > lastRowNum) {
|
||||||
throw new IndexOutOfBoundsException(StrUtil.format("Header row index {} is greater than last row index {}.", headerRowIndex, lastRowNum));
|
throw new IndexOutOfBoundsException(StrUtil.format("Header row index {} is greater than last row index {}.", headerRowIndex, lastRowNum));
|
||||||
} else if (startRowIndex > lastRowNum) {
|
}
|
||||||
|
|
||||||
|
int startRowIndex = this.cellRangeAddress.getFirstRow();
|
||||||
|
if (startRowIndex > lastRowNum) {
|
||||||
// issue#I5U1JA 只有标题行的Excel,起始行是1,标题行(最后的行号是0)
|
// issue#I5U1JA 只有标题行的Excel,起始行是1,标题行(最后的行号是0)
|
||||||
return ListUtil.empty();
|
return ListUtil.empty();
|
||||||
}
|
}
|
||||||
final int startRowIndex = Math.max(this.startRowIndex, firstRowNum);// 读取起始行(包含)
|
startRowIndex = Math.max(startRowIndex, firstRowNum);// 读取起始行(包含)
|
||||||
final int endRowIndex = Math.min(this.endRowIndex, lastRowNum);// 读取结束行(包含)
|
final int endRowIndex = Math.min(this.cellRangeAddress.getLastRow(), lastRowNum);// 读取结束行(包含)
|
||||||
|
|
||||||
// 读取header
|
// 读取header
|
||||||
final List<String> headerList = aliasHeader(readRow(sheet, headerRowIndex));
|
final List<String> headerList = this.config.aliasHeader(readRow(sheet, headerRowIndex));
|
||||||
|
|
||||||
final List<Map<String, Object>> result = new ArrayList<>(endRowIndex - startRowIndex + 1);
|
final List<Map<String, Object>> result = new ArrayList<>(endRowIndex - startRowIndex + 1);
|
||||||
List<Object> rowList;
|
List<Object> rowList;
|
||||||
@ -80,4 +84,15 @@ public class MapSheetReader extends AbstractSheetReader<List<Map<String, Object>
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取某一行数据
|
||||||
|
*
|
||||||
|
* @param sheet {@link Sheet}
|
||||||
|
* @param rowIndex 行号,从0开始
|
||||||
|
* @return 一行数据
|
||||||
|
*/
|
||||||
|
private List<Object> readRow(final Sheet sheet, final int rowIndex) {
|
||||||
|
return RowUtil.readRow(sheet.getRow(rowIndex), this.config.getCellEditor());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
package org.dromara.hutool.poi.excel.writer;
|
package org.dromara.hutool.poi.excel.writer;
|
||||||
|
|
||||||
|
import org.dromara.hutool.core.io.IoUtil;
|
||||||
import org.dromara.hutool.core.io.file.FileUtil;
|
import org.dromara.hutool.core.io.file.FileUtil;
|
||||||
import org.dromara.hutool.core.io.IORuntimeException;
|
import org.dromara.hutool.core.io.IORuntimeException;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
@ -32,6 +33,9 @@ import java.io.OutputStream;
|
|||||||
*/
|
*/
|
||||||
public class BigExcelWriter extends ExcelWriter {
|
public class BigExcelWriter extends ExcelWriter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认内存中保存的行数,默认100
|
||||||
|
*/
|
||||||
public static final int DEFAULT_WINDOW_SIZE = SXSSFWorkbook.DEFAULT_WINDOW_SIZE;
|
public static final int DEFAULT_WINDOW_SIZE = SXSSFWorkbook.DEFAULT_WINDOW_SIZE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -181,6 +185,7 @@ public class BigExcelWriter extends ExcelWriter {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("resource")
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
if (null != this.destFile && !isFlushed) {
|
if (null != this.destFile && !isFlushed) {
|
||||||
@ -188,7 +193,7 @@ public class BigExcelWriter extends ExcelWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 清理临时文件
|
// 清理临时文件
|
||||||
((SXSSFWorkbook) this.workbook).dispose();
|
IoUtil.closeIfPossible(this.workbook);
|
||||||
super.closeWithoutFlush();
|
super.closeWithoutFlush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024. looly(loolly@aliyun.com)
|
||||||
|
* Hutool is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* https://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dromara.hutool.poi.excel.writer;
|
||||||
|
|
||||||
|
import org.dromara.hutool.core.comparator.IndexedComparator;
|
||||||
|
import org.dromara.hutool.core.map.MapUtil;
|
||||||
|
import org.dromara.hutool.poi.excel.ExcelConfig;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excel写出配置
|
||||||
|
*
|
||||||
|
* @author Looly
|
||||||
|
* @since 6.0.0
|
||||||
|
*/
|
||||||
|
public class ExcelWriteConfig extends ExcelConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否只保留别名对应的字段
|
||||||
|
*/
|
||||||
|
protected boolean onlyAlias;
|
||||||
|
/**
|
||||||
|
* 标题顺序比较器
|
||||||
|
*/
|
||||||
|
protected Comparator<String> aliasComparator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExcelWriteConfig setHeaderAlias(final Map<String, String> headerAlias) {
|
||||||
|
this.aliasComparator = null;
|
||||||
|
return (ExcelWriteConfig) super.setHeaderAlias(headerAlias);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExcelWriteConfig addHeaderAlias(final String header, final String alias) {
|
||||||
|
this.aliasComparator = null;
|
||||||
|
return (ExcelWriteConfig) super.addHeaderAlias(header, alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExcelWriteConfig removeHeaderAlias(final String header) {
|
||||||
|
this.aliasComparator = null;
|
||||||
|
return (ExcelWriteConfig) super.removeHeaderAlias(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置是否只保留别名中的字段值,如果为true,则不设置alias的字段将不被输出,false表示原样输出
|
||||||
|
* Bean中设置@Alias时,setOnlyAlias是无效的,这个参数只和addHeaderAlias配合使用,原因是注解是Bean内部的操作,而addHeaderAlias是Writer的操作,不互通。
|
||||||
|
*
|
||||||
|
* @param isOnlyAlias 是否只保留别名中的字段值
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public ExcelWriteConfig setOnlyAlias(final boolean isOnlyAlias) {
|
||||||
|
this.onlyAlias = isOnlyAlias;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单例的别名比较器,比较器的顺序为别名加入的顺序
|
||||||
|
*
|
||||||
|
* @return Comparator
|
||||||
|
*/
|
||||||
|
public Comparator<String> getCachedAliasComparator() {
|
||||||
|
final Map<String, String> headerAlias = this.headerAlias;
|
||||||
|
if (MapUtil.isEmpty(headerAlias)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Comparator<String> aliasComparator = this.aliasComparator;
|
||||||
|
if (null == aliasComparator) {
|
||||||
|
final Set<String> keySet = headerAlias.keySet();
|
||||||
|
aliasComparator = new IndexedComparator<>(keySet.toArray(new String[0]));
|
||||||
|
this.aliasComparator = aliasComparator;
|
||||||
|
}
|
||||||
|
return aliasComparator;
|
||||||
|
}
|
||||||
|
}
|
@ -22,7 +22,6 @@ import org.apache.poi.xssf.usermodel.XSSFDataValidation;
|
|||||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||||
import org.dromara.hutool.core.bean.BeanUtil;
|
import org.dromara.hutool.core.bean.BeanUtil;
|
||||||
import org.dromara.hutool.core.collection.ListUtil;
|
import org.dromara.hutool.core.collection.ListUtil;
|
||||||
import org.dromara.hutool.core.comparator.IndexedComparator;
|
|
||||||
import org.dromara.hutool.core.io.IORuntimeException;
|
import org.dromara.hutool.core.io.IORuntimeException;
|
||||||
import org.dromara.hutool.core.io.IoUtil;
|
import org.dromara.hutool.core.io.IoUtil;
|
||||||
import org.dromara.hutool.core.io.file.FileUtil;
|
import org.dromara.hutool.core.io.file.FileUtil;
|
||||||
@ -63,16 +62,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
* @since 3.2.0
|
* @since 3.2.0
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("resource")
|
@SuppressWarnings("resource")
|
||||||
public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
public class ExcelWriter extends ExcelBase<ExcelWriter, ExcelWriteConfig> {
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否只保留别名对应的字段
|
|
||||||
*/
|
|
||||||
private boolean onlyAlias;
|
|
||||||
/**
|
|
||||||
* 标题顺序比较器
|
|
||||||
*/
|
|
||||||
private Comparator<String> aliasComparator;
|
|
||||||
/**
|
/**
|
||||||
* 样式集,定义不同类型数据样式
|
* 样式集,定义不同类型数据样式
|
||||||
*/
|
*/
|
||||||
@ -81,10 +72,6 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
|||||||
* 标题项对应列号缓存,每次写标题更新此缓存
|
* 标题项对应列号缓存,每次写标题更新此缓存
|
||||||
*/
|
*/
|
||||||
private Map<String, Integer> headLocationCache;
|
private Map<String, Integer> headLocationCache;
|
||||||
/**
|
|
||||||
* 单元格值处理接口
|
|
||||||
*/
|
|
||||||
private CellEditor cellEditor;
|
|
||||||
/**
|
/**
|
||||||
* 当前行
|
* 当前行
|
||||||
*/
|
*/
|
||||||
@ -188,22 +175,16 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
|||||||
* @since 4.0.6
|
* @since 4.0.6
|
||||||
*/
|
*/
|
||||||
public ExcelWriter(final Sheet sheet) {
|
public ExcelWriter(final Sheet sheet) {
|
||||||
super(sheet);
|
super(new ExcelWriteConfig(), sheet);
|
||||||
this.styleSet = new DefaultStyleSet(workbook);
|
this.styleSet = new DefaultStyleSet(workbook);
|
||||||
this.currentRow = new AtomicInteger(0);
|
this.currentRow = new AtomicInteger(0);
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置单元格值处理逻辑<br>
|
@Override
|
||||||
* 当Excel中的值并不能满足我们的读取要求时,通过传入一个编辑接口,可以对单元格值自定义,例如对数字和日期类型值转换为字符串等
|
public ExcelWriter setConfig(final ExcelWriteConfig config) {
|
||||||
*
|
return super.setConfig(config);
|
||||||
* @param cellEditor 单元格值处理接口
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
public ExcelWriter setCellEditor(final CellEditor cellEditor) {
|
|
||||||
this.cellEditor = cellEditor;
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -410,39 +391,6 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//region header alias
|
//region header alias
|
||||||
@Override
|
|
||||||
public ExcelWriter setHeaderAlias(final Map<String, String> headerAlias) {
|
|
||||||
// 新增别名时清除比较器缓存
|
|
||||||
this.aliasComparator = null;
|
|
||||||
return super.setHeaderAlias(headerAlias);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExcelWriter clearHeaderAlias() {
|
|
||||||
// 清空别名时清除比较器缓存
|
|
||||||
this.aliasComparator = null;
|
|
||||||
return super.clearHeaderAlias();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExcelWriter addHeaderAlias(final String name, final String alias) {
|
|
||||||
// 新增别名时清除比较器缓存
|
|
||||||
this.aliasComparator = null;
|
|
||||||
return super.addHeaderAlias(name, alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置是否只保留别名中的字段值,如果为true,则不设置alias的字段将不被输出,false表示原样输出
|
|
||||||
* Bean中设置@Alias时,setOnlyAlias是无效的,这个参数只和addHeaderAlias配合使用,原因是注解是Bean内部的操作,而addHeaderAlias是Writer的操作,不互通。
|
|
||||||
*
|
|
||||||
* @param isOnlyAlias 是否只保留别名中的字段值
|
|
||||||
* @return this
|
|
||||||
* @since 4.1.22
|
|
||||||
*/
|
|
||||||
public ExcelWriter setOnlyAlias(final boolean isOnlyAlias) {
|
|
||||||
this.onlyAlias = isOnlyAlias;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -704,7 +652,7 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
|||||||
// 设置内容
|
// 设置内容
|
||||||
if (null != content) {
|
if (null != content) {
|
||||||
final Cell cell = getOrCreateCell(cellRangeAddress.getFirstColumn(), cellRangeAddress.getFirstRow());
|
final Cell cell = getOrCreateCell(cellRangeAddress.getFirstColumn(), cellRangeAddress.getFirstRow());
|
||||||
CellUtil.setCellValue(cell, content, cellStyle, this.cellEditor);
|
CellUtil.setCellValue(cell, content, cellStyle, this.config.getCellEditor());
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -911,11 +859,12 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
|||||||
Assert.isFalse(this.isClosed, "ExcelWriter has been closed!");
|
Assert.isFalse(this.isClosed, "ExcelWriter has been closed!");
|
||||||
this.headLocationCache = new SafeConcurrentHashMap<>();
|
this.headLocationCache = new SafeConcurrentHashMap<>();
|
||||||
final Row row = this.sheet.createRow(this.currentRow.getAndIncrement());
|
final Row row = this.sheet.createRow(this.currentRow.getAndIncrement());
|
||||||
|
final CellEditor cellEditor = this.config.getCellEditor();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
Cell cell;
|
Cell cell;
|
||||||
for (final Object value : rowData) {
|
for (final Object value : rowData) {
|
||||||
cell = row.createCell(i);
|
cell = row.createCell(i);
|
||||||
CellUtil.setCellValue(cell, value, this.styleSet, true, this.cellEditor);
|
CellUtil.setCellValue(cell, value, this.styleSet, true, cellEditor);
|
||||||
this.headLocationCache.put(StrUtil.toString(value), i);
|
this.headLocationCache.put(StrUtil.toString(value), i);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -939,6 +888,7 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
|||||||
final Iterator<?> iterator = rowData.iterator();
|
final Iterator<?> iterator = rowData.iterator();
|
||||||
//如果获取的row存在单元格,则执行复杂表头逻辑,否则直接调用writeHeadRow(Iterable<?> rowData)
|
//如果获取的row存在单元格,则执行复杂表头逻辑,否则直接调用writeHeadRow(Iterable<?> rowData)
|
||||||
if (row.getLastCellNum() != 0) {
|
if (row.getLastCellNum() != 0) {
|
||||||
|
final CellEditor cellEditor = this.config.getCellEditor();
|
||||||
for (int i = 0; i < this.workbook.getSpreadsheetVersion().getMaxColumns(); i++) {
|
for (int i = 0; i < this.workbook.getSpreadsheetVersion().getMaxColumns(); i++) {
|
||||||
Cell cell = row.getCell(i);
|
Cell cell = row.getCell(i);
|
||||||
if (cell != null) {
|
if (cell != null) {
|
||||||
@ -946,7 +896,7 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
|||||||
}
|
}
|
||||||
if (iterator.hasNext()) {
|
if (iterator.hasNext()) {
|
||||||
cell = row.createCell(i);
|
cell = row.createCell(i);
|
||||||
CellUtil.setCellValue(cell, iterator.next(), this.styleSet, true, this.cellEditor);
|
CellUtil.setCellValue(cell, iterator.next(), this.styleSet, true, cellEditor);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -975,10 +925,12 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
public ExcelWriter writeRow(final Object rowBean, final boolean isWriteKeyAsHead) {
|
public ExcelWriter writeRow(final Object rowBean, final boolean isWriteKeyAsHead) {
|
||||||
|
final ExcelWriteConfig config = this.config;
|
||||||
|
|
||||||
final Map rowMap;
|
final Map rowMap;
|
||||||
if (rowBean instanceof Map) {
|
if (rowBean instanceof Map) {
|
||||||
if (MapUtil.isNotEmpty(this.headerAlias)) {
|
if (MapUtil.isNotEmpty(config.getHeaderAlias())) {
|
||||||
rowMap = MapUtil.newTreeMap((Map) rowBean, getCachedAliasComparator());
|
rowMap = MapUtil.newTreeMap((Map) rowBean, config.getCachedAliasComparator());
|
||||||
} else {
|
} else {
|
||||||
rowMap = (Map) rowBean;
|
rowMap = (Map) rowBean;
|
||||||
}
|
}
|
||||||
@ -990,11 +942,11 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
|||||||
// Hyperlink当成一个值
|
// Hyperlink当成一个值
|
||||||
return writeRow(ListUtil.of(rowBean), isWriteKeyAsHead);
|
return writeRow(ListUtil.of(rowBean), isWriteKeyAsHead);
|
||||||
} else if (BeanUtil.isReadableBean(rowBean.getClass())) {
|
} else if (BeanUtil.isReadableBean(rowBean.getClass())) {
|
||||||
if (MapUtil.isEmpty(this.headerAlias)) {
|
if (MapUtil.isEmpty(config.getHeaderAlias())) {
|
||||||
rowMap = BeanUtil.beanToMap(rowBean, new LinkedHashMap<>(), false, false);
|
rowMap = BeanUtil.beanToMap(rowBean, new LinkedHashMap<>(), false, false);
|
||||||
} else {
|
} else {
|
||||||
// 别名存在情况下按照别名的添加顺序排序Bean数据
|
// 别名存在情况下按照别名的添加顺序排序Bean数据
|
||||||
rowMap = BeanUtil.beanToMap(rowBean, new TreeMap<>(getCachedAliasComparator()), false, false);
|
rowMap = BeanUtil.beanToMap(rowBean, new TreeMap<>(config.getCachedAliasComparator()), false, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 其它转为字符串默认输出
|
// 其它转为字符串默认输出
|
||||||
@ -1033,6 +985,7 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
|||||||
// 如果已经写出标题行,根据标题行找对应的值写入
|
// 如果已经写出标题行,根据标题行找对应的值写入
|
||||||
if (MapUtil.isNotEmpty(this.headLocationCache)) {
|
if (MapUtil.isNotEmpty(this.headLocationCache)) {
|
||||||
final Row row = RowUtil.getOrCreateRow(this.sheet, this.currentRow.getAndIncrement());
|
final Row row = RowUtil.getOrCreateRow(this.sheet, this.currentRow.getAndIncrement());
|
||||||
|
final CellEditor cellEditor = this.config.getCellEditor();
|
||||||
Integer location;
|
Integer location;
|
||||||
for (final Table.Cell<?, ?, ?> cell : aliasTable) {
|
for (final Table.Cell<?, ?, ?> cell : aliasTable) {
|
||||||
// 首先查找原名对应的列号
|
// 首先查找原名对应的列号
|
||||||
@ -1042,7 +995,7 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
|||||||
location = this.headLocationCache.get(StrUtil.toString(cell.getColumnKey()));
|
location = this.headLocationCache.get(StrUtil.toString(cell.getColumnKey()));
|
||||||
}
|
}
|
||||||
if (null != location) {
|
if (null != location) {
|
||||||
CellUtil.setCellValue(CellUtil.getOrCreateCell(row, location), cell.getValue(), this.styleSet, false, this.cellEditor);
|
CellUtil.setCellValue(CellUtil.getOrCreateCell(row, location), cell.getValue(), this.styleSet, false, cellEditor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1061,7 +1014,7 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
|||||||
*/
|
*/
|
||||||
public ExcelWriter writeRow(final Iterable<?> rowData) {
|
public ExcelWriter writeRow(final Iterable<?> rowData) {
|
||||||
Assert.isFalse(this.isClosed, "ExcelWriter has been closed!");
|
Assert.isFalse(this.isClosed, "ExcelWriter has been closed!");
|
||||||
RowUtil.writeRow(this.sheet.createRow(this.currentRow.getAndIncrement()), rowData, this.styleSet, false, this.cellEditor);
|
RowUtil.writeRow(this.sheet.createRow(this.currentRow.getAndIncrement()), rowData, this.styleSet, false, this.config.getCellEditor());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
@ -1185,7 +1138,7 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
|||||||
*/
|
*/
|
||||||
public ExcelWriter writeCellValue(final int x, final int y, final Object value, final boolean isHeader) {
|
public ExcelWriter writeCellValue(final int x, final int y, final Object value, final boolean isHeader) {
|
||||||
final Cell cell = getOrCreateCell(x, y);
|
final Cell cell = getOrCreateCell(x, y);
|
||||||
CellUtil.setCellValue(cell, value, this.styleSet, isHeader, this.cellEditor);
|
CellUtil.setCellValue(cell, value, this.styleSet, isHeader, this.config.getCellEditor());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
@ -1406,15 +1359,17 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
|||||||
*/
|
*/
|
||||||
private Table<?, ?, ?> aliasTable(final Map<?, ?> rowMap) {
|
private Table<?, ?, ?> aliasTable(final Map<?, ?> rowMap) {
|
||||||
final Table<Object, Object, Object> filteredTable = new RowKeyTable<>(new LinkedHashMap<>(), TableMap::new);
|
final Table<Object, Object, Object> filteredTable = new RowKeyTable<>(new LinkedHashMap<>(), TableMap::new);
|
||||||
if (MapUtil.isEmpty(this.headerAlias)) {
|
final Map<String, String> headerAlias = this.config.getHeaderAlias();
|
||||||
|
final boolean onlyAlias = this.config.onlyAlias;
|
||||||
|
if (MapUtil.isEmpty(headerAlias)) {
|
||||||
rowMap.forEach((key, value) -> filteredTable.put(key, key, value));
|
rowMap.forEach((key, value) -> filteredTable.put(key, key, value));
|
||||||
} else {
|
} else {
|
||||||
rowMap.forEach((key, value) -> {
|
rowMap.forEach((key, value) -> {
|
||||||
final String aliasName = this.headerAlias.get(StrUtil.toString(key));
|
final String aliasName = headerAlias.get(StrUtil.toString(key));
|
||||||
if (null != aliasName) {
|
if (null != aliasName) {
|
||||||
// 别名键值对加入
|
// 别名键值对加入
|
||||||
filteredTable.put(key, aliasName, value);
|
filteredTable.put(key, aliasName, value);
|
||||||
} else if (!this.onlyAlias) {
|
} else if (!onlyAlias) {
|
||||||
// 保留无别名设置的键值对
|
// 保留无别名设置的键值对
|
||||||
filteredTable.put(key, key, value);
|
filteredTable.put(key, key, value);
|
||||||
}
|
}
|
||||||
@ -1423,24 +1378,5 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
|||||||
|
|
||||||
return filteredTable;
|
return filteredTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取单例的别名比较器,比较器的顺序为别名加入的顺序
|
|
||||||
*
|
|
||||||
* @return Comparator
|
|
||||||
* @since 4.1.5
|
|
||||||
*/
|
|
||||||
private Comparator<String> getCachedAliasComparator() {
|
|
||||||
if (MapUtil.isEmpty(this.headerAlias)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Comparator<String> aliasComparator = this.aliasComparator;
|
|
||||||
if (null == aliasComparator) {
|
|
||||||
final Set<String> keySet = this.headerAlias.keySet();
|
|
||||||
aliasComparator = new IndexedComparator<>(keySet.toArray(new String[0]));
|
|
||||||
this.aliasComparator = aliasComparator;
|
|
||||||
}
|
|
||||||
return aliasComparator;
|
|
||||||
}
|
|
||||||
// endregion
|
// endregion
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ public class CellEditorTest {
|
|||||||
@org.junit.jupiter.api.Test
|
@org.junit.jupiter.api.Test
|
||||||
public void readTest(){
|
public void readTest(){
|
||||||
final ExcelReader excelReader= ExcelUtil.getReader("cell_editor_test.xlsx");
|
final ExcelReader excelReader= ExcelUtil.getReader("cell_editor_test.xlsx");
|
||||||
excelReader.setCellEditor(new ExcelHandler());
|
excelReader.getConfig().setCellEditor(new ExcelHandler());
|
||||||
final List<Test> excelReaderObjects=excelReader.readAll(Test.class);
|
final List<Test> excelReaderObjects=excelReader.readAll(Test.class);
|
||||||
|
|
||||||
Assertions.assertEquals("0", excelReaderObjects.get(0).getTest1());
|
Assertions.assertEquals("0", excelReaderObjects.get(0).getTest1());
|
||||||
|
@ -19,6 +19,7 @@ import org.dromara.hutool.core.map.MapUtil;
|
|||||||
import org.dromara.hutool.core.util.ObjUtil;
|
import org.dromara.hutool.core.util.ObjUtil;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.apache.poi.ss.usermodel.Cell;
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.dromara.hutool.poi.excel.ExcelConfig;
|
||||||
import org.dromara.hutool.poi.excel.ExcelUtil;
|
import org.dromara.hutool.poi.excel.ExcelUtil;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
@ -48,7 +49,7 @@ public class ExcelReadTest {
|
|||||||
headerAlias.put("库房", "storageName");
|
headerAlias.put("库房", "storageName");
|
||||||
headerAlias.put("盘点权限", "checkPerm");
|
headerAlias.put("盘点权限", "checkPerm");
|
||||||
headerAlias.put("领料审批权限", "allotAuditPerm");
|
headerAlias.put("领料审批权限", "allotAuditPerm");
|
||||||
reader.setHeaderAlias(headerAlias);
|
reader.getConfig().setHeaderAlias(headerAlias);
|
||||||
|
|
||||||
// 读取list时默认首个非空行为标题
|
// 读取list时默认首个非空行为标题
|
||||||
final List<List<Object>> read = reader.read(0, Integer.MAX_VALUE, true);
|
final List<List<Object>> read = reader.read(0, Integer.MAX_VALUE, true);
|
||||||
@ -146,10 +147,11 @@ public class ExcelReadTest {
|
|||||||
@Test
|
@Test
|
||||||
public void excelReadToBeanListTest() {
|
public void excelReadToBeanListTest() {
|
||||||
final ExcelReader reader = ExcelUtil.getReader(ResourceUtil.getStream("aaa.xlsx"));
|
final ExcelReader reader = ExcelUtil.getReader(ResourceUtil.getStream("aaa.xlsx"));
|
||||||
reader.addHeaderAlias("姓名", "name");
|
final ExcelConfig config = reader.getConfig();
|
||||||
reader.addHeaderAlias("年龄", "age");
|
config.addHeaderAlias("姓名", "name");
|
||||||
reader.addHeaderAlias("性别", "gender");
|
config.addHeaderAlias("年龄", "age");
|
||||||
reader.addHeaderAlias("鞋码", "shoeSize");
|
config.addHeaderAlias("性别", "gender");
|
||||||
|
config.addHeaderAlias("鞋码", "shoeSize");
|
||||||
|
|
||||||
final List<Person> all = reader.readAll(Person.class);
|
final List<Person> all = reader.readAll(Person.class);
|
||||||
Assertions.assertEquals("张三", all.get(0).getName());
|
Assertions.assertEquals("张三", all.get(0).getName());
|
||||||
@ -162,9 +164,10 @@ public class ExcelReadTest {
|
|||||||
@Disabled
|
@Disabled
|
||||||
public void excelReadToBeanListTest2() {
|
public void excelReadToBeanListTest2() {
|
||||||
final ExcelReader reader = ExcelUtil.getReader("f:/test/toBean.xlsx");
|
final ExcelReader reader = ExcelUtil.getReader("f:/test/toBean.xlsx");
|
||||||
reader.addHeaderAlias("姓名", "name");
|
final ExcelConfig config = reader.getConfig();
|
||||||
reader.addHeaderAlias("年龄", "age");
|
config.addHeaderAlias("姓名", "name");
|
||||||
reader.addHeaderAlias("性别", "gender");
|
config.addHeaderAlias("年龄", "age");
|
||||||
|
config.addHeaderAlias("性别", "gender");
|
||||||
|
|
||||||
final List<Person> all = reader.read(0, 2, Person.class);
|
final List<Person> all = reader.read(0, 2, Person.class);
|
||||||
for (final Person person : all) {
|
for (final Person person : all) {
|
||||||
@ -220,7 +223,8 @@ public class ExcelReadTest {
|
|||||||
@Test
|
@Test
|
||||||
public void nullValueEditTest(){
|
public void nullValueEditTest(){
|
||||||
final ExcelReader reader = ExcelUtil.getReader("null_cell_test.xlsx");
|
final ExcelReader reader = ExcelUtil.getReader("null_cell_test.xlsx");
|
||||||
reader.setCellEditor((cell, value)-> ObjUtil.defaultIfNull(value, "#"));
|
final ExcelConfig config = reader.getConfig();
|
||||||
|
config.setCellEditor((cell, value)-> ObjUtil.defaultIfNull(value, "#"));
|
||||||
final List<List<Object>> read = reader.read();
|
final List<List<Object>> read = reader.read();
|
||||||
|
|
||||||
// 对于任意一个单元格有值的情况下,之前的单元格值按照null处理
|
// 对于任意一个单元格有值的情况下,之前的单元格值按照null处理
|
||||||
@ -271,14 +275,14 @@ public class ExcelReadTest {
|
|||||||
//https://gitee.com/dromara/hutool/issues/I5OSFC
|
//https://gitee.com/dromara/hutool/issues/I5OSFC
|
||||||
final ExcelReader reader = ExcelUtil.getReader(ResourceUtil.getStream("read.xlsx"));
|
final ExcelReader reader = ExcelUtil.getReader(ResourceUtil.getStream("read.xlsx"));
|
||||||
final List<Map<String, Object>> read = reader.read(1,2,2);
|
final List<Map<String, Object>> read = reader.read(1,2,2);
|
||||||
for (Map<String, Object> map : read) {
|
for (final Map<String, Object> map : read) {
|
||||||
Console.log(map);
|
Console.log(map);
|
||||||
}
|
}
|
||||||
//超出lastIndex 抛出相应提示:startRowIndex row index 4 is greater than last row index 2.
|
//超出lastIndex 抛出相应提示:startRowIndex row index 4 is greater than last row index 2.
|
||||||
//而非:Illegal Capacity: -1
|
//而非:Illegal Capacity: -1
|
||||||
try {
|
try {
|
||||||
final List<Map<String, Object>> readGreaterIndex = reader.read(1,4,4);
|
final List<Map<String, Object>> readGreaterIndex = reader.read(1,4,4);
|
||||||
} catch (Exception e) {
|
} catch (final Exception e) {
|
||||||
Console.log(e.toString());
|
Console.log(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,11 +191,12 @@ public class BigExcelWriteTest {
|
|||||||
FileUtil.del(FileUtil.file(file));
|
FileUtil.del(FileUtil.file(file));
|
||||||
final BigExcelWriter writer = ExcelUtil.getBigWriter(file);
|
final BigExcelWriter writer = ExcelUtil.getBigWriter(file);
|
||||||
//自定义标题
|
//自定义标题
|
||||||
writer.addHeaderAlias("name", "姓名");
|
final ExcelWriteConfig config = writer.getConfig();
|
||||||
writer.addHeaderAlias("age", "年龄");
|
config.addHeaderAlias("name", "姓名");
|
||||||
writer.addHeaderAlias("score", "分数");
|
config.addHeaderAlias("age", "年龄");
|
||||||
writer.addHeaderAlias("isPass", "是否通过");
|
config.addHeaderAlias("score", "分数");
|
||||||
writer.addHeaderAlias("examDate", "考试时间");
|
config.addHeaderAlias("isPass", "是否通过");
|
||||||
|
config.addHeaderAlias("examDate", "考试时间");
|
||||||
// 合并单元格后的标题行,使用默认标题样式
|
// 合并单元格后的标题行,使用默认标题样式
|
||||||
writer.merge(4, "一班成绩单");
|
writer.merge(4, "一班成绩单");
|
||||||
// 一次性写出内容,使用默认样式
|
// 一次性写出内容,使用默认样式
|
||||||
@ -234,8 +235,9 @@ public class BigExcelWriteTest {
|
|||||||
final String path = "d:/test/issue1210.xlsx";
|
final String path = "d:/test/issue1210.xlsx";
|
||||||
FileUtil.del(FileUtil.file(path));
|
FileUtil.del(FileUtil.file(path));
|
||||||
final BigExcelWriter writer = ExcelUtil.getBigWriter(path);
|
final BigExcelWriter writer = ExcelUtil.getBigWriter(path);
|
||||||
writer.addHeaderAlias("id", "SN");
|
final ExcelWriteConfig config = writer.getConfig();
|
||||||
writer.addHeaderAlias("userName", "User Name");
|
config.addHeaderAlias("id", "SN");
|
||||||
|
config.addHeaderAlias("userName", "User Name");
|
||||||
|
|
||||||
final List<Map<String, Object>> list = new ArrayList<>();
|
final List<Map<String, Object>> list = new ArrayList<>();
|
||||||
list.add(new HashMap<String, Object>() {
|
list.add(new HashMap<String, Object>() {
|
||||||
|
@ -306,11 +306,12 @@ public class ExcelWriteTest {
|
|||||||
FileUtil.del(FileUtil.file(file));
|
FileUtil.del(FileUtil.file(file));
|
||||||
final ExcelWriter writer = ExcelUtil.getWriter(file);
|
final ExcelWriter writer = ExcelUtil.getWriter(file);
|
||||||
// 自定义标题
|
// 自定义标题
|
||||||
writer.addHeaderAlias("name", "姓名");
|
final ExcelWriteConfig config = writer.getConfig();
|
||||||
writer.addHeaderAlias("age", "年龄");
|
config.addHeaderAlias("name", "姓名");
|
||||||
writer.addHeaderAlias("score", "分数");
|
config.addHeaderAlias("age", "年龄");
|
||||||
writer.addHeaderAlias("isPass", "是否通过");
|
config.addHeaderAlias("score", "分数");
|
||||||
writer.addHeaderAlias("examDate", "考试时间");
|
config.addHeaderAlias("isPass", "是否通过");
|
||||||
|
config.addHeaderAlias("examDate", "考试时间");
|
||||||
// 合并单元格后的标题行,使用默认标题样式
|
// 合并单元格后的标题行,使用默认标题样式
|
||||||
writer.merge(4, "一班成绩单");
|
writer.merge(4, "一班成绩单");
|
||||||
// 一次性写出内容,使用默认样式
|
// 一次性写出内容,使用默认样式
|
||||||
@ -340,10 +341,11 @@ public class ExcelWriteTest {
|
|||||||
final String file = "f:/test/test_alias.xlsx";
|
final String file = "f:/test/test_alias.xlsx";
|
||||||
FileUtil.del(FileUtil.file(file));
|
FileUtil.del(FileUtil.file(file));
|
||||||
final ExcelWriter writer = ExcelUtil.getWriter(file);
|
final ExcelWriter writer = ExcelUtil.getWriter(file);
|
||||||
writer.setOnlyAlias(true);
|
final ExcelWriteConfig config = writer.getConfig();
|
||||||
|
config.setOnlyAlias(true);
|
||||||
// 自定义标题
|
// 自定义标题
|
||||||
writer.addHeaderAlias("name", "姓名");
|
config.addHeaderAlias("name", "姓名");
|
||||||
writer.addHeaderAlias("age", "年龄");
|
config.addHeaderAlias("age", "年龄");
|
||||||
// 合并单元格后的标题行,使用默认标题样式
|
// 合并单元格后的标题行,使用默认标题样式
|
||||||
writer.merge(4, "一班成绩单");
|
writer.merge(4, "一班成绩单");
|
||||||
// 一次性写出内容,使用默认样式
|
// 一次性写出内容,使用默认样式
|
||||||
@ -372,10 +374,11 @@ public class ExcelWriteTest {
|
|||||||
// 通过工具类创建writer
|
// 通过工具类创建writer
|
||||||
final String file = "d:/test/test_alias.xls";
|
final String file = "d:/test/test_alias.xls";
|
||||||
final ExcelWriter writer = ExcelUtil.getWriter(file, "test1");
|
final ExcelWriter writer = ExcelUtil.getWriter(file, "test1");
|
||||||
// writer.setOnlyAlias(true);
|
|
||||||
// 自定义标题
|
// 自定义标题
|
||||||
writer.addHeaderAlias("name", "姓名");
|
final ExcelWriteConfig config = writer.getConfig();
|
||||||
writer.addHeaderAlias("age", "年龄");
|
// writer.setOnlyAlias(true);
|
||||||
|
config.addHeaderAlias("name", "姓名");
|
||||||
|
config.addHeaderAlias("age", "年龄");
|
||||||
// 一次性写出内容,使用默认样式
|
// 一次性写出内容,使用默认样式
|
||||||
writer.write(rows, true);
|
writer.write(rows, true);
|
||||||
// 关闭writer,释放内存
|
// 关闭writer,释放内存
|
||||||
@ -403,12 +406,13 @@ public class ExcelWriteTest {
|
|||||||
// 通过工具类创建writer
|
// 通过工具类创建writer
|
||||||
final String file = "d:/test/test_alias.xls";
|
final String file = "d:/test/test_alias.xls";
|
||||||
final ExcelWriter writer = ExcelUtil.getWriter(file, "test1");
|
final ExcelWriter writer = ExcelUtil.getWriter(file, "test1");
|
||||||
writer.setOnlyAlias(true);
|
final ExcelWriteConfig config = writer.getConfig();
|
||||||
|
config.setOnlyAlias(true);
|
||||||
|
|
||||||
// 自定义标题
|
// 自定义标题
|
||||||
writer.addHeaderAlias("name", "姓名");
|
config.addHeaderAlias("name", "姓名");
|
||||||
writer.addHeaderAlias("age", "年龄");
|
config.addHeaderAlias("age", "年龄");
|
||||||
writer.addHeaderAlias("examDate", "考试时间");
|
config.addHeaderAlias("examDate", "考试时间");
|
||||||
|
|
||||||
// 一次性写出内容,使用默认样式
|
// 一次性写出内容,使用默认样式
|
||||||
writer.write(rows, true);
|
writer.write(rows, true);
|
||||||
@ -438,12 +442,13 @@ public class ExcelWriteTest {
|
|||||||
final String file = "e:/writeBeanTest.xlsx";
|
final String file = "e:/writeBeanTest.xlsx";
|
||||||
FileUtil.del(FileUtil.file(file));
|
FileUtil.del(FileUtil.file(file));
|
||||||
final ExcelWriter writer = ExcelUtil.getWriter(file);
|
final ExcelWriter writer = ExcelUtil.getWriter(file);
|
||||||
|
final ExcelWriteConfig config = writer.getConfig();
|
||||||
// 自定义标题
|
// 自定义标题
|
||||||
writer.addHeaderAlias("name", "姓名");
|
config.addHeaderAlias("name", "姓名");
|
||||||
writer.addHeaderAlias("age", "年龄");
|
config.addHeaderAlias("age", "年龄");
|
||||||
writer.addHeaderAlias("score", "分数");
|
config.addHeaderAlias("score", "分数");
|
||||||
writer.addHeaderAlias("isPass", "是否通过");
|
config.addHeaderAlias("isPass", "是否通过");
|
||||||
writer.addHeaderAlias("examDate", "考试时间");
|
config.addHeaderAlias("examDate", "考试时间");
|
||||||
// 合并单元格后的标题行,使用默认标题样式
|
// 合并单元格后的标题行,使用默认标题样式
|
||||||
writer.merge(4, "一班成绩单");
|
writer.merge(4, "一班成绩单");
|
||||||
// 一次性写出内容,使用默认样式
|
// 一次性写出内容,使用默认样式
|
||||||
@ -471,9 +476,10 @@ public class ExcelWriteTest {
|
|||||||
FileUtil.del(FileUtil.file(file));
|
FileUtil.del(FileUtil.file(file));
|
||||||
final ExcelWriter writer = ExcelUtil.getWriter(file);
|
final ExcelWriter writer = ExcelUtil.getWriter(file);
|
||||||
// 自定义标题
|
// 自定义标题
|
||||||
writer.addHeaderAlias("id", "编号");
|
final ExcelWriteConfig config = writer.getConfig();
|
||||||
writer.addHeaderAlias("num", "序号");
|
config.addHeaderAlias("id", "编号");
|
||||||
writer.addHeaderAlias("body", "内容");
|
config.addHeaderAlias("num", "序号");
|
||||||
|
config.addHeaderAlias("body", "内容");
|
||||||
// 一次性写出内容,使用默认样式
|
// 一次性写出内容,使用默认样式
|
||||||
writer.write(rows, true);
|
writer.write(rows, true);
|
||||||
// 关闭writer,释放内存
|
// 关闭writer,释放内存
|
||||||
@ -529,18 +535,19 @@ public class ExcelWriteTest {
|
|||||||
rows.add(tempList);
|
rows.add(tempList);
|
||||||
}
|
}
|
||||||
final ExcelWriter writer = ExcelUtil.getWriter("D:\\test\\multiSheet.xlsx", "正常数据");
|
final ExcelWriter writer = ExcelUtil.getWriter("D:\\test\\multiSheet.xlsx", "正常数据");
|
||||||
writer.addHeaderAlias("1", "row1");
|
final ExcelWriteConfig config = writer.getConfig();
|
||||||
writer.addHeaderAlias("3", "row2");
|
config.addHeaderAlias("1", "row1");
|
||||||
writer.setOnlyAlias(true);
|
config.addHeaderAlias("3", "row2");
|
||||||
|
config.setOnlyAlias(true);
|
||||||
|
|
||||||
writer.write(rows, true);
|
writer.write(rows, true);
|
||||||
writer.autoSizeColumnAll(false, 0);
|
writer.autoSizeColumnAll(false, 0);
|
||||||
|
|
||||||
//表2
|
//表2
|
||||||
writer.setSheet("当前重复数据");
|
writer.setSheet("当前重复数据");
|
||||||
writer.clearHeaderAlias();
|
config.clearHeaderAlias();
|
||||||
writer.addHeaderAlias("3", "行3");
|
config.addHeaderAlias("3", "行3");
|
||||||
writer.addHeaderAlias("1", "行1");
|
config.addHeaderAlias("1", "行1");
|
||||||
writer.write(rows, true);
|
writer.write(rows, true);
|
||||||
writer.autoSizeColumnAll(false, 0);
|
writer.autoSizeColumnAll(false, 0);
|
||||||
|
|
||||||
@ -749,7 +756,7 @@ public class ExcelWriteTest {
|
|||||||
//通过工具类创建writer
|
//通过工具类创建writer
|
||||||
FileUtil.del(FileUtil.file("d:/test/writeTest2123.xlsx"));
|
FileUtil.del(FileUtil.file("d:/test/writeTest2123.xlsx"));
|
||||||
final ExcelWriter writer = ExcelUtil.getWriter("d:/test/writeTest2123.xlsx");
|
final ExcelWriter writer = ExcelUtil.getWriter("d:/test/writeTest2123.xlsx");
|
||||||
writer.addHeaderAlias("xmnf", "项目年份");//1
|
writer.getConfig().addHeaderAlias("xmnf", "项目年份");//1
|
||||||
|
|
||||||
//合并单元格后的标题行,使用默认标题样式
|
//合并单元格后的标题行,使用默认标题样式
|
||||||
writer.merge(7, "测试标题");
|
writer.merge(7, "测试标题");
|
||||||
|
@ -37,9 +37,10 @@ public class Issue2221Test {
|
|||||||
public void writeDuplicateHeaderAliasTest() {
|
public void writeDuplicateHeaderAliasTest() {
|
||||||
final ExcelWriter writer = ExcelUtil.getWriter("d:/test/duplicateAlias.xlsx");
|
final ExcelWriter writer = ExcelUtil.getWriter("d:/test/duplicateAlias.xlsx");
|
||||||
// 设置别名
|
// 设置别名
|
||||||
writer.addHeaderAlias("androidLc", "安卓");
|
final ExcelWriteConfig config = writer.getConfig();
|
||||||
writer.addHeaderAlias("androidAc", "安卓");
|
config.addHeaderAlias("androidLc", "安卓");
|
||||||
writer.setOnlyAlias(true);
|
config.addHeaderAlias("androidAc", "安卓");
|
||||||
|
config.setOnlyAlias(true);
|
||||||
|
|
||||||
// 写入数据
|
// 写入数据
|
||||||
final List<Map<Object, Object>> data = ListUtil.view(
|
final List<Map<Object, Object>> data = ListUtil.view(
|
||||||
@ -77,12 +78,13 @@ public class Issue2221Test {
|
|||||||
writer.setFreezePane(2);
|
writer.setFreezePane(2);
|
||||||
|
|
||||||
// 设置别名
|
// 设置别名
|
||||||
writer.addHeaderAlias("date", "日期");
|
final ExcelWriteConfig config = writer.getConfig();
|
||||||
writer.addHeaderAlias("androidLc", "安卓");
|
config.addHeaderAlias("date", "日期");
|
||||||
writer.addHeaderAlias("iosLc", "iOS");
|
config.addHeaderAlias("androidLc", "安卓");
|
||||||
writer.addHeaderAlias("androidAc", " 安卓");
|
config.addHeaderAlias("iosLc", "iOS");
|
||||||
writer.addHeaderAlias("iosAc", " iOS");
|
config.addHeaderAlias("androidAc", " 安卓");
|
||||||
writer.setOnlyAlias(true);
|
config.addHeaderAlias("iosAc", " iOS");
|
||||||
|
config.setOnlyAlias(true);
|
||||||
|
|
||||||
// 设置合并的单元格
|
// 设置合并的单元格
|
||||||
writer.merge(new CellRangeAddress(0, 1, 0, 0), "日期", true);
|
writer.merge(new CellRangeAddress(0, 1, 0, 0), "日期", true);
|
||||||
|
@ -57,8 +57,9 @@ public class IssueI66Z6BTest {
|
|||||||
final ExcelWriter writer = ExcelUtil.getWriter(destFile);
|
final ExcelWriter writer = ExcelUtil.getWriter(destFile);
|
||||||
|
|
||||||
//自定义标题别名
|
//自定义标题别名
|
||||||
writer.addHeaderAlias("姓名", "name");
|
final ExcelWriteConfig config = writer.getConfig();
|
||||||
writer.addHeaderAlias("年龄", "age");
|
config.addHeaderAlias("姓名", "name");
|
||||||
|
config.addHeaderAlias("年龄", "age");
|
||||||
|
|
||||||
writer.write(dataList, true);
|
writer.write(dataList, true);
|
||||||
writer.close();
|
writer.close();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user