diff --git a/CHANGELOG.md b/CHANGELOG.md index 95a3a6968..c939ac23c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * 【core 】 BitStatusUtil添加来源声明(issue#1824@Github) * 【core 】 UrlQuery.build增加重载,支持可选是否转义(issue#I4AIX1@Gitee) * 【core 】 ListUtil增加swapTo和swapElement方法(pr#416@Gitee) +* 【poi 】 ExcelWriter支持Hyperlink(issue#I49QAL@Gitee) * ### 🐞Bug修复 * 【core 】 修复FuncKey函数无效问题 diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java index b366514dd..0f11bac7c 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java @@ -5,8 +5,10 @@ import cn.hutool.core.lang.Assert; import cn.hutool.poi.excel.cell.CellLocation; import cn.hutool.poi.excel.cell.CellUtil; import cn.hutool.poi.excel.style.StyleUtil; +import org.apache.poi.common.usermodel.HyperlinkType; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Hyperlink; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; @@ -390,6 +392,32 @@ public class ExcelBase> implements Closeable { return columnStyle; } + /** + * 创建 {@link Hyperlink},默认内容(标签为链接地址本身) + * @param type 链接类型 + * @param address 链接地址 + * @return 链接 + * @since 5.7.13 + */ + public Hyperlink createHyperlink(HyperlinkType type, String address){ + return createHyperlink(type, address, address); + } + + /** + * 创建 {@link Hyperlink},默认内容 + * @param type 链接类型 + * @param address 链接地址 + * @param label 标签,即单元格中显示的内容 + * @return 链接 + * @since 5.7.13 + */ + public Hyperlink createHyperlink(HyperlinkType type, String address, String label){ + final Hyperlink hyperlink = this.workbook.getCreationHelper().createHyperlink(type); + hyperlink.setAddress(address); + hyperlink.setLabel(label); + return hyperlink; + } + /** * 获取总行数,计算方法为: * diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelWriter.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelWriter.java index eedbb506d..e6a11c2d8 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelWriter.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelWriter.java @@ -16,6 +16,7 @@ import cn.hutool.core.util.URLUtil; import cn.hutool.poi.excel.cell.CellLocation; import cn.hutool.poi.excel.cell.CellUtil; import cn.hutool.poi.excel.style.Align; +import org.apache.poi.common.usermodel.Hyperlink; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.DataValidation; @@ -947,6 +948,9 @@ public class ExcelWriter extends ExcelBase { } else { rowMap = (Map) rowBean; } + } else if (rowBean instanceof Hyperlink) { + // Hyperlink当成一个值 + return writeRow(CollUtil.newArrayList(rowBean), isWriteKeyAsHead); } else if (BeanUtil.isBean(rowBean.getClass())) { if (MapUtil.isEmpty(this.headerAlias)) { rowMap = BeanUtil.beanToMap(rowBean, new LinkedHashMap<>(), false, false); diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/StyleSet.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/StyleSet.java index 52fb05423..2bec87b58 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/StyleSet.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/StyleSet.java @@ -1,6 +1,7 @@ package cn.hutool.poi.excel; import cn.hutool.poi.excel.style.StyleUtil; +import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.FillPatternType; @@ -14,7 +15,7 @@ import java.io.Serializable; /** * 样式集合,此样式集合汇集了整个工作簿的样式,用于减少样式的创建和冗余 - * + * * @author looly * */ @@ -31,10 +32,12 @@ public class StyleSet implements Serializable{ protected CellStyle cellStyleForNumber; /** 默认日期样式 */ protected CellStyle cellStyleForDate; + /** 默认链接样式 */ + protected CellStyle cellStyleForHyperlink; /** * 构造 - * + * * @param workbook 工作簿 */ public StyleSet(Workbook workbook) { @@ -42,56 +45,74 @@ public class StyleSet implements Serializable{ this.headCellStyle = StyleUtil.createHeadCellStyle(workbook); this.cellStyle = StyleUtil.createDefaultCellStyle(workbook); + // 默认数字格式 + cellStyleForNumber = StyleUtil.cloneCellStyle(workbook, this.cellStyle); + // 2表示:0.00 + cellStyleForNumber.setDataFormat((short) 2); + // 默认日期格式 this.cellStyleForDate = StyleUtil.cloneCellStyle(workbook, this.cellStyle); // 22表示:m/d/yy h:mm this.cellStyleForDate.setDataFormat((short) 22); - // 默认数字格式 - cellStyleForNumber = StyleUtil.cloneCellStyle(workbook, this.cellStyle); - // 2表示:0.00 - cellStyleForNumber.setDataFormat((short) 2); + + // 默认链接样式 + this.cellStyleForHyperlink = StyleUtil.cloneCellStyle(workbook, this.cellStyle); + final Font font = this.workbook.createFont(); + font.setUnderline((byte) 1); + font.setColor(HSSFColor.HSSFColorPredefined.BLUE.getIndex()); + this.cellStyleForHyperlink.setFont(font); } /** * 获取头部样式,获取后可以定义整体头部样式 - * + * * @return 头部样式 */ public CellStyle getHeadCellStyle() { - return headCellStyle; + return this.headCellStyle; } /** * 获取常规单元格样式,获取后可以定义整体头部样式 - * + * * @return 常规单元格样式 */ public CellStyle getCellStyle() { - return cellStyle; + return this.cellStyle; } /** - * 获取数字(带小数点)单元格样式,获取后可以定义整体头部样式 - * + * 获取数字(带小数点)单元格样式,获取后可以定义整体数字样式 + * * @return 数字(带小数点)单元格样式 */ public CellStyle getCellStyleForNumber() { - return cellStyleForNumber; + return this.cellStyleForNumber; } /** - * 获取日期单元格样式,获取后可以定义整体头部样式 - * + * 获取日期单元格样式,获取后可以定义整体日期样式 + * * @return 日期单元格样式 */ public CellStyle getCellStyleForDate() { - return cellStyleForDate; + return this.cellStyleForDate; + } + + /** + * 获取链接单元格样式,获取后可以定义整体链接样式 + * + * @return 链接单元格样式 + * @since 5.7.13 + */ + public CellStyle getCellStyleForHyperlink() { + return this.cellStyleForHyperlink; } /** * 定义所有单元格的边框类型 - * + * * @param borderSize 边框粗细{@link BorderStyle}枚举 * @param colorIndex 颜色的short值 * @return this @@ -102,12 +123,13 @@ public class StyleSet implements Serializable{ StyleUtil.setBorder(this.cellStyle, borderSize, colorIndex); StyleUtil.setBorder(this.cellStyleForNumber, borderSize, colorIndex); StyleUtil.setBorder(this.cellStyleForDate, borderSize, colorIndex); + StyleUtil.setBorder(this.cellStyleForHyperlink, borderSize, colorIndex); return this; } /** * 设置cell文本对齐样式 - * + * * @param halign 横向位置 * @param valign 纵向位置 * @return this @@ -118,12 +140,13 @@ public class StyleSet implements Serializable{ StyleUtil.setAlign(this.cellStyle, halign, valign); StyleUtil.setAlign(this.cellStyleForNumber, halign, valign); StyleUtil.setAlign(this.cellStyleForDate, halign, valign); + StyleUtil.setAlign(this.cellStyleForHyperlink, halign, valign); return this; } /** * 设置单元格背景样式 - * + * * @param backgroundColor 背景色 * @param withHeadCell 是否也定义头部样式 * @return this @@ -136,12 +159,13 @@ public class StyleSet implements Serializable{ StyleUtil.setColor(this.cellStyle, backgroundColor, FillPatternType.SOLID_FOREGROUND); StyleUtil.setColor(this.cellStyleForNumber, backgroundColor, FillPatternType.SOLID_FOREGROUND); StyleUtil.setColor(this.cellStyleForDate, backgroundColor, FillPatternType.SOLID_FOREGROUND); + StyleUtil.setColor(this.cellStyleForHyperlink, backgroundColor, FillPatternType.SOLID_FOREGROUND); return this; } /** * 设置全局字体 - * + * * @param color 字体颜色 * @param fontSize 字体大小,-1表示默认大小 * @param fontName 字体名,null表示默认字体 @@ -155,7 +179,7 @@ public class StyleSet implements Serializable{ /** * 设置全局字体 - * + * * @param font 字体,可以通过{@link StyleUtil#createFont(Workbook, short, short, String)}创建 * @param ignoreHead 是否跳过头部样式 * @return this @@ -168,12 +192,13 @@ public class StyleSet implements Serializable{ this.cellStyle.setFont(font); this.cellStyleForNumber.setFont(font); this.cellStyleForDate.setFont(font); + this.cellStyleForHyperlink.setFont(font); return this; } /** * 设置单元格文本自动换行 - * + * * @return this * @since 4.5.16 */ @@ -181,6 +206,8 @@ public class StyleSet implements Serializable{ this.cellStyle.setWrapText(true); this.cellStyleForNumber.setWrapText(true); this.cellStyleForDate.setWrapText(true); + this.cellStyleForHyperlink.setWrapText(true); return this; } + } diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/CellUtil.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/CellUtil.java index 6cb0ebce3..9b31c340d 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/CellUtil.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/CellUtil.java @@ -15,6 +15,7 @@ import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.Comment; import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.ss.usermodel.Drawing; +import org.apache.poi.ss.usermodel.Hyperlink; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; @@ -171,6 +172,11 @@ public class CellUtil { if ((value instanceof Double || value instanceof Float || value instanceof BigDecimal) && null != styleSet && null != styleSet.getCellStyleForNumber()) { cell.setCellStyle(styleSet.getCellStyleForNumber()); } + } else if(value instanceof Hyperlink){ + // 自定义超链接样式 + if (null != styleSet && null != styleSet.getCellStyleForHyperlink()) { + cell.setCellStyle(styleSet.getCellStyleForHyperlink()); + } } setCellValue(cell, value); diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/setters/CellSetterFactory.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/setters/CellSetterFactory.java index 2cb38edae..59d5f83c8 100755 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/setters/CellSetterFactory.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/setters/CellSetterFactory.java @@ -1,6 +1,7 @@ package cn.hutool.poi.excel.cell.setters; import cn.hutool.poi.excel.cell.CellSetter; +import org.apache.poi.ss.usermodel.Hyperlink; import org.apache.poi.ss.usermodel.RichTextString; import java.time.temporal.TemporalAccessor; @@ -38,6 +39,8 @@ public class CellSetterFactory { return new RichTextCellSetter((RichTextString) value); } else if (value instanceof Number) { return new NumberCellSetter((Number) value); + }else if (value instanceof Hyperlink) { + return new HyperlinkCellSetter((Hyperlink) value); } else { return new CharSequenceCellSetter(value.toString()); } diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/setters/HyperlinkCellSetter.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/setters/HyperlinkCellSetter.java new file mode 100644 index 000000000..6bb0a64f4 --- /dev/null +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/cell/setters/HyperlinkCellSetter.java @@ -0,0 +1,32 @@ +package cn.hutool.poi.excel.cell.setters; + +import cn.hutool.core.lang.Console; +import cn.hutool.poi.excel.cell.CellSetter; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Hyperlink; + +/** + * {@link Hyperlink} 值单元格设置器 + * + * @author looly + * @since 5.7.13 + */ +public class HyperlinkCellSetter implements CellSetter { + + private final Hyperlink value; + + /** + * 构造 + * + * @param value 值 + */ + HyperlinkCellSetter(Hyperlink value) { + this.value = value; + } + + @Override + public void setValue(Cell cell) { + cell.setHyperlink(this.value); + cell.setCellValue(this.value.getLabel()); + } +} diff --git a/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelWriteTest.java b/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelWriteTest.java index 3d9892e6f..ad5c3c5fc 100644 --- a/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelWriteTest.java +++ b/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelWriteTest.java @@ -10,12 +10,14 @@ import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.poi.excel.cell.setters.EscapeStrCellSetter; import cn.hutool.poi.excel.style.StyleUtil; +import org.apache.poi.common.usermodel.HyperlinkType; import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.BuiltinFormats; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.Hyperlink; import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.VerticalAlignment; import org.apache.poi.ss.util.CellRangeAddressList; @@ -770,4 +772,15 @@ public class ExcelWriteTest { writer.write(ListUtil.of(1427545395336093698L)); writer.close(); } + + @Test + @Ignore + public void writeHyperlinkTest(){ + final ExcelWriter writer = ExcelUtil.getWriter("d:/test/hyperlink.xlsx"); + + final Hyperlink hyperlink = writer.createHyperlink(HyperlinkType.URL, "https://hutool.cn"); + + writer.write(ListUtil.of(hyperlink)); + writer.close(); + } }