mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
fix cell style
This commit is contained in:
parent
9ed6412bac
commit
def6b802f3
@ -11,10 +11,13 @@
|
||||
* 【core】 MapUtil、CollUtil增加emptyIfNull(issue#502@Github)
|
||||
* 【core】 增加emptyIfNull等(issue#503@Github)
|
||||
* 【setting】 Props增加toBean方法(issue#499@Github)
|
||||
* 【poi】 CellUtil增加getMergedRegionValue方法,ExcelWriter增加getDisposition方法
|
||||
* 【http】 HttpBase增加headerMap方法
|
||||
|
||||
### Bug修复
|
||||
* 【http】 修复HttpRquest中body方法长度计算问题(issue#I10UPG@Gitee)
|
||||
* 【system】 修复获取本地IP问题(pr#65@Gitee)
|
||||
* 【poi】 修复设置单元格样式无效问题
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -134,6 +134,25 @@ public abstract class HttpBase<T> {
|
||||
return header(name, value, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置请求头
|
||||
*
|
||||
* @param headers 请求头
|
||||
* @param isOverride 是否覆盖已有头信息
|
||||
* @return this
|
||||
* @since 4.6.3
|
||||
*/
|
||||
public T headerMap(Map<String, String> headers, boolean isOverride) {
|
||||
if(CollectionUtil.isEmpty(headers)) {
|
||||
return (T)this;
|
||||
}
|
||||
|
||||
for (Entry<String, String> entry : headers.entrySet()) {
|
||||
this.header(entry.getKey(), StrUtil.nullToEmpty(entry.getValue()), isOverride);
|
||||
}
|
||||
return (T)this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置请求头<br>
|
||||
* 不覆盖原有请求头
|
||||
@ -146,8 +165,7 @@ public abstract class HttpBase<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置请求头<br>
|
||||
* 不覆盖原有请求头
|
||||
* 设置请求头
|
||||
*
|
||||
* @param headers 请求头
|
||||
* @param isOverride 是否覆盖已有头信息
|
||||
|
@ -14,6 +14,7 @@ import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.poi.excel.cell.CellUtil;
|
||||
import cn.hutool.poi.excel.style.StyleUtil;
|
||||
|
||||
/**
|
||||
* Excel基础类,用于抽象ExcelWriter和ExcelReader中共用部分的对象和方法
|
||||
@ -198,45 +199,74 @@ public class ExcelBase<T extends ExcelBase<T>> implements Closeable {
|
||||
* @since 4.1.4
|
||||
*/
|
||||
public CellStyle getOrCreateCellStyle(int x, int y) {
|
||||
final CellStyle cellStyle = getOrCreateCell(x, y).getCellStyle();
|
||||
return StyleUtil.isNullOrDefaultStyle(this.workbook, cellStyle) ? createCellStyle(x, y) : cellStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定单元格创建样式,返回样式后可以设置样式内容
|
||||
*
|
||||
* @param x X坐标,从0计数,既列号
|
||||
* @param y Y坐标,从0计数,既行号
|
||||
* @return {@link CellStyle}
|
||||
* @since 4.6.3
|
||||
*/
|
||||
public CellStyle createCellStyle(int x, int y) {
|
||||
final Cell cell = getOrCreateCell(x, y);
|
||||
CellStyle cellStyle = cell.getCellStyle();
|
||||
if (null == cellStyle) {
|
||||
cellStyle = this.workbook.createCellStyle();
|
||||
cell.setCellStyle(cellStyle);
|
||||
}
|
||||
final CellStyle cellStyle = this.workbook.createCellStyle();
|
||||
cell.setCellStyle(cellStyle);
|
||||
return cellStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取或创建某一行的样式,返回样式后可以设置样式内容
|
||||
* 获取或创建某一行的样式,返回样式后可以设置样式内容<br>
|
||||
* 需要注意,此方法返回行样式,设置背景色在单元格设置值后会被覆盖,需要单独设置其单元格的样式。
|
||||
*
|
||||
* @param y Y坐标,从0计数,既行号
|
||||
* @return {@link CellStyle}
|
||||
* @since 4.1.4
|
||||
*/
|
||||
public CellStyle getOrCreateRowStyle(int y) {
|
||||
final Row row = getOrCreateRow(y);
|
||||
CellStyle rowStyle = row.getRowStyle();
|
||||
if (null == rowStyle) {
|
||||
rowStyle = this.workbook.createCellStyle();
|
||||
row.setRowStyle(rowStyle);
|
||||
}
|
||||
CellStyle rowStyle = getOrCreateRow(y).getRowStyle();
|
||||
return StyleUtil.isNullOrDefaultStyle(this.workbook, rowStyle) ? createRowStyle(y) : rowStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建某一行的样式,返回样式后可以设置样式内容
|
||||
*
|
||||
* @param y Y坐标,从0计数,既行号
|
||||
* @return {@link CellStyle}
|
||||
* @since 4.6.3
|
||||
*/
|
||||
public CellStyle createRowStyle(int y) {
|
||||
final CellStyle rowStyle = this.workbook.createCellStyle();
|
||||
getOrCreateRow(y).setRowStyle(rowStyle);
|
||||
return rowStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取或创建某一行的样式,返回样式后可以设置样式内容
|
||||
* 获取或创建某一行的样式,返回样式后可以设置样式内容<br>
|
||||
* 需要注意,此方法返回行样式,设置背景色在单元格设置值后会被覆盖,需要单独设置其单元格的样式。
|
||||
*
|
||||
* @param x X坐标,从0计数,既列号
|
||||
* @return {@link CellStyle}
|
||||
* @since 4.1.4
|
||||
*/
|
||||
public CellStyle getOrCreateColumnStyle(int x) {
|
||||
CellStyle columnStyle = this.sheet.getColumnStyle(x);
|
||||
if (null == columnStyle) {
|
||||
columnStyle = this.workbook.createCellStyle();
|
||||
this.sheet.setDefaultColumnStyle(x, columnStyle);
|
||||
}
|
||||
final CellStyle columnStyle = this.sheet.getColumnStyle(x);
|
||||
return StyleUtil.isNullOrDefaultStyle(this.workbook, columnStyle) ? createColumnStyle(x) : columnStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建某一行的样式,返回样式后可以设置样式内容
|
||||
*
|
||||
* @param x X坐标,从0计数,既列号
|
||||
* @return {@link CellStyle}
|
||||
* @since 4.6.3
|
||||
*/
|
||||
public CellStyle createColumnStyle(int x) {
|
||||
final CellStyle columnStyle = this.workbook.createCellStyle();
|
||||
this.sheet.setDefaultColumnStyle(x, columnStyle);
|
||||
return columnStyle;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package cn.hutool.poi.excel;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
@ -34,6 +35,10 @@ import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.poi.excel.cell.CellUtil;
|
||||
import cn.hutool.poi.excel.style.Align;
|
||||
|
||||
@ -263,6 +268,17 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
||||
this.sheet.autoSizeColumn(columnIndex, useMergedCells);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用默认样式
|
||||
*
|
||||
* @return this
|
||||
* @see #setStyleSet(StyleSet)
|
||||
* @since 4.6.3
|
||||
*/
|
||||
public ExcelWriter disableDefaultStyle() {
|
||||
return setStyleSet(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置样式集,如果不使用样式,传入{@code null}
|
||||
@ -319,6 +335,31 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
||||
public int getCurrentRow() {
|
||||
return this.currentRow.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Content-Disposition头对应的值,可以通过调用以下方法快速设置下载Excel的头信息:
|
||||
*
|
||||
* <pre>
|
||||
* response.setHeader("Content-Disposition", excelWriter.getDisposition("test.xlsx", CharsetUtil.CHARSET_UTF_8));
|
||||
* </pre>
|
||||
*
|
||||
* @param fileName 文件名,如果文件名没有扩展名,会自动按照生成Excel类型补齐扩展名,如果提供空,使用随机UUID
|
||||
* @param charset 编码,null则使用默认UTF-8编码
|
||||
* @return Content-Disposition值
|
||||
*/
|
||||
public String getDisposition(String fileName, Charset charset) {
|
||||
if(null == charset) {
|
||||
charset = CharsetUtil.CHARSET_UTF_8;
|
||||
}
|
||||
|
||||
if(StrUtil.isBlank(fileName)) {
|
||||
// 未提供文件名使用随机UUID作为文件名
|
||||
fileName = IdUtil.fastSimpleUUID();
|
||||
}
|
||||
|
||||
fileName = StrUtil.addSuffixIfNot(URLUtil.encodeAll(fileName, charset), isXlsx() ? ".xlsx" : ".xls");
|
||||
return StrUtil.format("attachment; filename=\"{}\"; filename*={}''{}", fileName, charset.name(), fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前所在行
|
||||
@ -824,7 +865,7 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
||||
* @param y Y坐标,从0计数,既行号
|
||||
* @return {@link CellStyle}
|
||||
* @since 4.0.9
|
||||
* @deprecated 请使用{@link #getOrCreateCellStyle(int, int)}
|
||||
* @deprecated 请使用{@link #createCellStyle(int, int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public CellStyle createStyleForCell(int x, int y) {
|
||||
@ -833,6 +874,25 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
||||
cell.setCellStyle(cellStyle);
|
||||
return cellStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置某个单元格的样式<br>
|
||||
* 此方法用于多个单元格共享样式的情况<br>
|
||||
* 可以调用{@link #getOrCreateCellStyle(int, int)} 方法创建或取得一个样式对象。
|
||||
*
|
||||
* <p>
|
||||
* 需要注意的是,共享样式会共享同一个{@link CellStyle},一个单元格样式改变,全部改变。
|
||||
*
|
||||
* @param x X坐标,从0计数,既列号
|
||||
* @param y Y坐标,从0计数,既行号
|
||||
* @return this
|
||||
* @since 4.6.3
|
||||
*/
|
||||
public ExcelWriter setStyle(CellStyle style, int x, int y) {
|
||||
final Cell cell = getOrCreateCell(x, y);
|
||||
cell.setCellStyle(style);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建字体
|
||||
|
@ -3,6 +3,7 @@ package cn.hutool.poi.excel.cell;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
@ -13,6 +14,7 @@ import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.ss.util.RegionUtil;
|
||||
import org.apache.poi.ss.util.SheetUtil;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@ -26,7 +28,18 @@ import cn.hutool.poi.excel.editors.TrimEditor;
|
||||
* @since 4.0.7
|
||||
*/
|
||||
public class CellUtil {
|
||||
|
||||
|
||||
/**
|
||||
* 获取单元格值
|
||||
*
|
||||
* @param cell {@link Cell}单元格
|
||||
* @return 值,类型可能为:Date、Double、Boolean、String
|
||||
* @since 4.6.3
|
||||
*/
|
||||
public static Object getCellValue(Cell cell) {
|
||||
return getCellValue(cell, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单元格值
|
||||
*
|
||||
@ -121,7 +134,11 @@ public class CellUtil {
|
||||
* @param isHeader 是否为标题单元格
|
||||
*/
|
||||
public static void setCellValue(Cell cell, Object value, StyleSet styleSet, boolean isHeader) {
|
||||
if(null != styleSet) {
|
||||
if(null == cell) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null != styleSet) {
|
||||
final CellStyle headCellStyle = styleSet.getHeadCellStyle();
|
||||
final CellStyle cellStyle = styleSet.getCellStyle();
|
||||
if (isHeader && null != headCellStyle) {
|
||||
@ -148,7 +165,7 @@ public class CellUtil {
|
||||
} else if (value instanceof RichTextString) {
|
||||
cell.setCellValue((RichTextString) value);
|
||||
} else if (value instanceof Number) {
|
||||
if ((value instanceof Double || value instanceof Float || value instanceof BigDecimal) && null != styleSet && null != styleSet.getCellStyleForNumber()) {
|
||||
if ((value instanceof Double || value instanceof Float || value instanceof BigDecimal) && null != styleSet && null != styleSet.getCellStyleForNumber()) {
|
||||
cell.setCellStyle(styleSet.getCellStyleForNumber());
|
||||
}
|
||||
cell.setCellValue(((Number) value).doubleValue());
|
||||
@ -221,6 +238,40 @@ public class CellUtil {
|
||||
return sheet.addMergedRegion(cellRangeAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取合并单元格的值<br>
|
||||
* 传入的x,y坐标(列行数)可以是合并单元格范围内的任意一个单元格
|
||||
*
|
||||
*
|
||||
* @param sheet {@link Sheet}
|
||||
* @param y 行号,从0开始,可以是合并单元格范围中的任意一行
|
||||
* @param x 列号,从0开始,可以是合并单元格范围中的任意一列
|
||||
* @return 合并单元格的值
|
||||
* @since 4.6.3
|
||||
*/
|
||||
public static Object getMergedRegionValue(Sheet sheet, int x, int y) {
|
||||
final List<CellRangeAddress> addrs = sheet.getMergedRegions();
|
||||
|
||||
int firstColumn;
|
||||
int lastColumn;
|
||||
int firstRow;
|
||||
int lastRow;
|
||||
for (CellRangeAddress ca : addrs) {
|
||||
firstColumn = ca.getFirstColumn();
|
||||
lastColumn = ca.getLastColumn();
|
||||
firstRow = ca.getFirstRow();
|
||||
lastRow = ca.getLastRow();
|
||||
|
||||
if (y >= firstRow && y <= lastRow) {
|
||||
if (x >= firstColumn && x <= lastColumn) {
|
||||
return getCellValue(SheetUtil.getCell(sheet, firstRow, firstColumn));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------- Private method start
|
||||
/**
|
||||
* 获取数字类型的单元格值
|
||||
|
@ -175,4 +175,18 @@ public class StyleUtil {
|
||||
setColor(cellStyle, IndexedColors.GREY_25_PERCENT, FillPatternType.SOLID_FOREGROUND);
|
||||
return cellStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 给定样式是否为null(无样式)或默认样式,默认样式为<code>workbook.getCellStyleAt(0)</code>
|
||||
* @param workbook 工作簿
|
||||
* @param style 被检查的样式
|
||||
* @return 是否为null(无样式)或默认样式
|
||||
* @since 4.6.3
|
||||
*/
|
||||
public static boolean isNullOrDefaultStyle(Workbook workbook, CellStyle style) {
|
||||
if(null == style || style.equals(workbook.getCellStyleAt(0))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -208,6 +208,33 @@ public class ExcelWriteTest {
|
||||
// 关闭writer,释放内存
|
||||
writer.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void writeMapWithStyleTest() {
|
||||
Map<String, Object> row1 = MapUtil.newHashMap(true);
|
||||
row1.put("姓名", "张三");
|
||||
row1.put("年龄", 23);
|
||||
row1.put("成绩", 88.32);
|
||||
row1.put("是否合格", true);
|
||||
row1.put("考试日期", DateUtil.date());
|
||||
|
||||
// 通过工具类创建writer
|
||||
String path = "f:/test/writeMapWithStyleTest.xlsx";
|
||||
FileUtil.del(path);
|
||||
ExcelWriter writer = ExcelUtil.getWriter(path);
|
||||
writer.setStyleSet(null);
|
||||
|
||||
// 一次性写出内容,使用默认样式
|
||||
writer.writeRow(row1, true);
|
||||
|
||||
// 设置某个单元格样式
|
||||
CellStyle orCreateRowStyle = writer.getOrCreateCellStyle(0, 1);
|
||||
StyleUtil.setColor(orCreateRowStyle,IndexedColors.RED.getIndex(),FillPatternType.SOLID_FOREGROUND );
|
||||
|
||||
// 关闭writer,释放内存
|
||||
writer.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
@ -278,7 +305,7 @@ public class ExcelWriteTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
// @Ignore
|
||||
@Ignore
|
||||
public void writeMapOnlyAliasTest2() {
|
||||
Map<Object, Object> row1 = new LinkedHashMap<>();
|
||||
row1.put("name", "张三");
|
||||
|
Loading…
Reference in New Issue
Block a user