From aafb3e9a43b41ec78b33d9ba4c7529aff0ee6c06 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Sat, 18 Sep 2021 16:01:30 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=86=99=E5=85=A5=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 +- pom.xml | 2 +- .../annotation/format/DateTimeFormat.java | 4 +- .../write/style/ContentFontStyle.java | 8 +- .../annotation/write/style/ContentStyle.java | 33 +-- .../annotation/write/style/HeadFontStyle.java | 12 +- .../annotation/write/style/HeadStyle.java | 33 +-- .../com/alibaba/excel/enums/BooleanEnum.java | 33 +++ .../excel/enums/poi/BorderStyleEnum.java | 95 +++++++++ .../excel/enums/poi/FillPatternTypeEnum.java | 119 +++++++++++ .../enums/poi/HorizontalAlignmentEnum.java | 94 +++++++++ .../enums/poi/VerticalAlignmentEnum.java | 71 +++++++ .../excel/metadata/data/DataFormatData.java | 20 ++ .../excel/metadata/data/WriteCellData.java | 11 + .../property/DateTimeFormatProperty.java | 23 +- .../excel/metadata/property/FontProperty.java | 140 +++++------- .../metadata/property/StyleProperty.java | 128 +++++++---- .../alibaba/excel/util/WriteHandlerUtils.java | 13 +- .../handler/DefaultWriteHandlerLoader.java | 28 +-- .../context/CellWriteHandlerContext.java | 7 + .../write/metadata/style/WriteCellStyle.java | 199 +++++++++++++++--- .../excel/write/metadata/style/WriteFont.java | 41 ++++ .../AbstractVerticalCellStyleStrategy.java | 15 +- .../excel/write/style/DefaultStyle.java | 46 ++++ .../style/HorizontalCellStyleStrategy.java | 21 +- .../test/demo/write/CommentWriteHandler.java | 19 +- .../demo/write/CustomCellWriteHandler.java | 24 +-- .../demo/write/CustomSheetWriteHandler.java | 26 +-- .../test/demo/write/DemoStyleData.java | 11 +- .../easyexcel/test/demo/write/WriteTest.java | 96 +++++++-- .../easyexcel/test/temp/WriteV33Test.java | 190 +++++++++-------- .../easyexcel/test/temp/simple/DemoData1.java | 5 +- .../easyexcel/test/temp/simple/DemoData2.java | 5 +- update.md | 5 + 34 files changed, 1150 insertions(+), 434 deletions(-) create mode 100644 src/main/java/com/alibaba/excel/enums/BooleanEnum.java create mode 100644 src/main/java/com/alibaba/excel/enums/poi/BorderStyleEnum.java create mode 100644 src/main/java/com/alibaba/excel/enums/poi/FillPatternTypeEnum.java create mode 100644 src/main/java/com/alibaba/excel/enums/poi/HorizontalAlignmentEnum.java create mode 100644 src/main/java/com/alibaba/excel/enums/poi/VerticalAlignmentEnum.java create mode 100644 src/main/java/com/alibaba/excel/write/style/DefaultStyle.java diff --git a/README.md b/README.md index 10e7f2d1..6c255fa4 100644 --- a/README.md +++ b/README.md @@ -29,9 +29,10 @@ Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都 * 3+ 版本至少 Java8 ### 关于版本升级 * 不建议跨大版本升级 尤其跨2个大版本 -* 2+ 升级到 3+ - * 使用了自定义拦截器去修改样式的会出问题 - * 读的时候`invoke`里面抛出异常,不会再额外封装一层`ExcelAnalysisException` +* 2+ 升级到 3+ 一些不兼容的地方 + * 使用了自定义拦截器去修改样式的会出问题(不会编译报错) + * 读的时候`invoke`里面抛出异常,不会再额外封装一层`ExcelAnalysisException` (不会编译报错) + * 样式等注解涉及到 `boolean` or 一些枚举 值的 有变动,新增默认值(会编译报错,注解改就行) * 大版本升级后建议相关内容重新测试下 ## 人员招募 diff --git a/pom.xml b/pom.xml index 3f29ad91..2fb651aa 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.alibaba easyexcel - 3.0.0-beta1 + 3.0.0-beta2 jar easyexcel diff --git a/src/main/java/com/alibaba/excel/annotation/format/DateTimeFormat.java b/src/main/java/com/alibaba/excel/annotation/format/DateTimeFormat.java index 96aff229..fefceded 100644 --- a/src/main/java/com/alibaba/excel/annotation/format/DateTimeFormat.java +++ b/src/main/java/com/alibaba/excel/annotation/format/DateTimeFormat.java @@ -6,6 +6,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import com.alibaba.excel.enums.BooleanEnum; + /** * Convert date format. * @@ -34,5 +36,5 @@ public @interface DateTimeFormat { * * @return True if date uses 1904 windowing, or false if using 1900 date windowing. */ - boolean use1904windowing() default false; + BooleanEnum use1904windowing() default BooleanEnum.DEFAULT; } diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/ContentFontStyle.java b/src/main/java/com/alibaba/excel/annotation/write/style/ContentFontStyle.java index 533ae6aa..fd890d48 100644 --- a/src/main/java/com/alibaba/excel/annotation/write/style/ContentFontStyle.java +++ b/src/main/java/com/alibaba/excel/annotation/write/style/ContentFontStyle.java @@ -6,6 +6,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import com.alibaba.excel.enums.BooleanEnum; + import org.apache.poi.common.usermodel.fonts.FontCharset; import org.apache.poi.hssf.usermodel.HSSFPalette; import org.apache.poi.ss.usermodel.Font; @@ -34,12 +36,12 @@ public @interface ContentFontStyle { /** * Whether to use italics or not */ - boolean italic() default false; + BooleanEnum italic() default BooleanEnum.DEFAULT; /** * Whether to use a strikeout horizontal line through the text or not */ - boolean strikeout() default false; + BooleanEnum strikeout() default BooleanEnum.DEFAULT; /** * The color for the font @@ -85,5 +87,5 @@ public @interface ContentFontStyle { /** * Bold */ - boolean bold() default false; + BooleanEnum bold() default BooleanEnum.DEFAULT; } diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/ContentStyle.java b/src/main/java/com/alibaba/excel/annotation/write/style/ContentStyle.java index 9ef3f47e..bfa8aa4f 100644 --- a/src/main/java/com/alibaba/excel/annotation/write/style/ContentStyle.java +++ b/src/main/java/com/alibaba/excel/annotation/write/style/ContentStyle.java @@ -6,13 +6,16 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import org.apache.poi.ss.usermodel.BorderStyle; +import com.alibaba.excel.enums.BooleanEnum; +import com.alibaba.excel.enums.poi.BorderStyleEnum; +import com.alibaba.excel.enums.poi.FillPatternTypeEnum; +import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum; +import com.alibaba.excel.enums.poi.VerticalAlignmentEnum; + import org.apache.poi.ss.usermodel.BuiltinFormats; import org.apache.poi.ss.usermodel.FillPatternType; -import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.IgnoredErrorType; import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.VerticalAlignment; /** * Custom content styles @@ -31,36 +34,36 @@ public @interface ContentStyle { /** * Set the cell's using this style to be hidden */ - boolean hidden() default false; + BooleanEnum hidden() default BooleanEnum.DEFAULT; /** * Set the cell's using this style to be locked */ - boolean locked() default false; + BooleanEnum locked() default BooleanEnum.DEFAULT; /** * Turn on or off "Quote Prefix" or "123 Prefix" for the style, which is used to tell Excel that the thing which * looks like a number or a formula shouldn't be treated as on. Turning this on is somewhat (but not completely, see * {@link IgnoredErrorType}) like prefixing the cell value with a ' in Excel */ - boolean quotePrefix() default false; + BooleanEnum quotePrefix() default BooleanEnum.DEFAULT; /** * Set the type of horizontal alignment for the cell */ - HorizontalAlignment horizontalAlignment() default HorizontalAlignment.GENERAL; + HorizontalAlignmentEnum horizontalAlignment() default HorizontalAlignmentEnum.DEFAULT; /** * Set whether the text should be wrapped. Setting this flag to true make all content visible within a * cell by displaying it on multiple lines * */ - boolean wrapped() default false; + BooleanEnum wrapped() default BooleanEnum.DEFAULT; /** * Set the type of vertical alignment for the cell */ - VerticalAlignment verticalAlignment() default VerticalAlignment.CENTER; + VerticalAlignmentEnum verticalAlignment() default VerticalAlignmentEnum.DEFAULT; /** * Set the degree of rotation for the text in the cell. @@ -80,22 +83,22 @@ public @interface ContentStyle { /** * Set the type of border to use for the left border of the cell */ - BorderStyle borderLeft() default BorderStyle.NONE; + BorderStyleEnum borderLeft() default BorderStyleEnum.DEFAULT; /** * Set the type of border to use for the right border of the cell */ - BorderStyle borderRight() default BorderStyle.NONE; + BorderStyleEnum borderRight() default BorderStyleEnum.DEFAULT; /** * Set the type of border to use for the top border of the cell */ - BorderStyle borderTop() default BorderStyle.NONE; + BorderStyleEnum borderTop() default BorderStyleEnum.DEFAULT; /** * Set the type of border to use for the bottom border of the cell */ - BorderStyle borderBottom() default BorderStyle.NONE; + BorderStyleEnum borderBottom() default BorderStyleEnum.DEFAULT; /** * Set the color to use for the left border @@ -133,7 +136,7 @@ public @interface ContentStyle { * * @see FillPatternType#SOLID_FOREGROUND */ - FillPatternType fillPatternType() default FillPatternType.NO_FILL; + FillPatternTypeEnum fillPatternType() default FillPatternTypeEnum.DEFAULT; /** * Set the background fill color. @@ -154,6 +157,6 @@ public @interface ContentStyle { /** * Controls if the Cell should be auto-sized to shrink to fit if the text is too long */ - boolean shrinkToFit() default false; + BooleanEnum shrinkToFit() default BooleanEnum.DEFAULT; } diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/HeadFontStyle.java b/src/main/java/com/alibaba/excel/annotation/write/style/HeadFontStyle.java index d25dad77..e7f0e1ba 100644 --- a/src/main/java/com/alibaba/excel/annotation/write/style/HeadFontStyle.java +++ b/src/main/java/com/alibaba/excel/annotation/write/style/HeadFontStyle.java @@ -6,6 +6,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import com.alibaba.excel.enums.BooleanEnum; + import org.apache.poi.common.usermodel.fonts.FontCharset; import org.apache.poi.hssf.usermodel.HSSFPalette; import org.apache.poi.ss.usermodel.Font; @@ -24,22 +26,22 @@ public @interface HeadFontStyle { /** * The name for the font (i.e. Arial) */ - String fontName() default "宋体"; + String fontName() default ""; /** * Height in the familiar unit of measure - points */ - short fontHeightInPoints() default 14; + short fontHeightInPoints() default -1; /** * Whether to use italics or not */ - boolean italic() default false; + BooleanEnum italic() default BooleanEnum.DEFAULT; /** * Whether to use a strikeout horizontal line through the text or not */ - boolean strikeout() default false; + BooleanEnum strikeout() default BooleanEnum.DEFAULT; /** * The color for the font @@ -85,5 +87,5 @@ public @interface HeadFontStyle { /** * Bold */ - boolean bold() default true; + BooleanEnum bold() default BooleanEnum.DEFAULT; } diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/HeadStyle.java b/src/main/java/com/alibaba/excel/annotation/write/style/HeadStyle.java index 5bc3ffc6..85900eac 100644 --- a/src/main/java/com/alibaba/excel/annotation/write/style/HeadStyle.java +++ b/src/main/java/com/alibaba/excel/annotation/write/style/HeadStyle.java @@ -6,13 +6,16 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import org.apache.poi.ss.usermodel.BorderStyle; +import com.alibaba.excel.enums.BooleanEnum; +import com.alibaba.excel.enums.poi.BorderStyleEnum; +import com.alibaba.excel.enums.poi.FillPatternTypeEnum; +import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum; +import com.alibaba.excel.enums.poi.VerticalAlignmentEnum; + import org.apache.poi.ss.usermodel.BuiltinFormats; import org.apache.poi.ss.usermodel.FillPatternType; -import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.IgnoredErrorType; import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.VerticalAlignment; /** * Custom header styles @@ -31,35 +34,35 @@ public @interface HeadStyle { /** * Set the cell's using this style to be hidden */ - boolean hidden() default false; + BooleanEnum hidden() default BooleanEnum.DEFAULT; /** * Set the cell's using this style to be locked */ - boolean locked() default true; + BooleanEnum locked() default BooleanEnum.DEFAULT; /** * Turn on or off "Quote Prefix" or "123 Prefix" for the style, which is used to tell Excel that the thing which * looks like a number or a formula shouldn't be treated as on. Turning this on is somewhat (but not completely, see * {@link IgnoredErrorType}) like prefixing the cell value with a ' in Excel */ - boolean quotePrefix() default false; + BooleanEnum quotePrefix() default BooleanEnum.DEFAULT; /** * Set the type of horizontal alignment for the cell */ - HorizontalAlignment horizontalAlignment() default HorizontalAlignment.CENTER; + HorizontalAlignmentEnum horizontalAlignment() default HorizontalAlignmentEnum.DEFAULT; /** * Set whether the text should be wrapped. Setting this flag to true make all content visible within a * cell by displaying it on multiple lines */ - boolean wrapped() default true; + BooleanEnum wrapped() default BooleanEnum.DEFAULT; /** * Set the type of vertical alignment for the cell */ - VerticalAlignment verticalAlignment() default VerticalAlignment.CENTER; + VerticalAlignmentEnum verticalAlignment() default VerticalAlignmentEnum.DEFAULT; /** * Set the degree of rotation for the text in the cell. @@ -79,22 +82,22 @@ public @interface HeadStyle { /** * Set the type of border to use for the left border of the cell */ - BorderStyle borderLeft() default BorderStyle.THIN; + BorderStyleEnum borderLeft() default BorderStyleEnum.DEFAULT; /** * Set the type of border to use for the right border of the cell */ - BorderStyle borderRight() default BorderStyle.THIN; + BorderStyleEnum borderRight() default BorderStyleEnum.DEFAULT; /** * Set the type of border to use for the top border of the cell */ - BorderStyle borderTop() default BorderStyle.THIN; + BorderStyleEnum borderTop() default BorderStyleEnum.DEFAULT; /** * Set the type of border to use for the bottom border of the cell */ - BorderStyle borderBottom() default BorderStyle.THIN; + BorderStyleEnum borderBottom() default BorderStyleEnum.DEFAULT; /** * Set the color to use for the left border @@ -129,7 +132,7 @@ public @interface HeadStyle { * * @see FillPatternType#SOLID_FOREGROUND */ - FillPatternType fillPatternType() default FillPatternType.SOLID_FOREGROUND; + FillPatternTypeEnum fillPatternType() default FillPatternTypeEnum.DEFAULT; /** * Set the background fill color. @@ -148,6 +151,6 @@ public @interface HeadStyle { /** * Controls if the Cell should be auto-sized to shrink to fit if the text is too long */ - boolean shrinkToFit() default false; + BooleanEnum shrinkToFit() default BooleanEnum.DEFAULT; } diff --git a/src/main/java/com/alibaba/excel/enums/BooleanEnum.java b/src/main/java/com/alibaba/excel/enums/BooleanEnum.java new file mode 100644 index 00000000..ee5274d2 --- /dev/null +++ b/src/main/java/com/alibaba/excel/enums/BooleanEnum.java @@ -0,0 +1,33 @@ +package com.alibaba.excel.enums; + +import lombok.Getter; + +/** + * Default values cannot be used for annotations. + * So an additional an enumeration to determine whether the user has added the enumeration. + * + * @author Jiaju Zhuang + */ +@Getter +public enum BooleanEnum { + /** + * NULL + */ + DEFAULT(null), + /** + * TRUE + */ + TRUE(Boolean.TRUE), + /** + * FALSE + */ + FALSE(Boolean.FALSE), + ; + + Boolean booleanValue; + + BooleanEnum(Boolean booleanValue) { + this.booleanValue = booleanValue; + } + +} diff --git a/src/main/java/com/alibaba/excel/enums/poi/BorderStyleEnum.java b/src/main/java/com/alibaba/excel/enums/poi/BorderStyleEnum.java new file mode 100644 index 00000000..1033ef1a --- /dev/null +++ b/src/main/java/com/alibaba/excel/enums/poi/BorderStyleEnum.java @@ -0,0 +1,95 @@ +package com.alibaba.excel.enums.poi; + +import lombok.Getter; +import org.apache.poi.ss.usermodel.BorderStyle; + +/** + * The enumeration value indicating the line style of a border in a cell, + * i.e., whether it is bordered dash dot, dash dot dot, dashed, dotted, double, hair, medium, + * medium dash dot, medium dash dot dot, medium dashed, none, slant dash dot, thick or thin. + * + * @author Jiaju Zhuang + */ +@Getter +public enum BorderStyleEnum { + /** + * null + */ + DEFAULT(null), + + /** + * No border (default) + */ + NONE(BorderStyle.NONE), + + /** + * Thin border + */ + THIN(BorderStyle.THIN), + + /** + * Medium border + */ + MEDIUM(BorderStyle.MEDIUM), + + /** + * dash border + */ + DASHED(BorderStyle.DASHED), + + /** + * dot border + */ + DOTTED(BorderStyle.DOTTED), + + /** + * Thick border + */ + THICK(BorderStyle.THICK), + + /** + * double-line border + */ + DOUBLE(BorderStyle.DOUBLE), + + /** + * hair-line border + */ + HAIR(BorderStyle.HAIR), + + /** + * Medium dashed border + */ + MEDIUM_DASHED(BorderStyle.MEDIUM_DASHED), + + /** + * dash-dot border + */ + DASH_DOT(BorderStyle.DASH_DOT), + + /** + * medium dash-dot border + */ + MEDIUM_DASH_DOT(BorderStyle.MEDIUM_DASH_DOT), + + /** + * dash-dot-dot border + */ + DASH_DOT_DOT(BorderStyle.DASH_DOT_DOT), + + /** + * medium dash-dot-dot border + */ + MEDIUM_DASH_DOT_DOT(BorderStyle.MEDIUM_DASH_DOT_DOT), + + /** + * slanted dash-dot border + */ + SLANTED_DASH_DOT(BorderStyle.SLANTED_DASH_DOT); + + BorderStyle poiBorderStyle; + + BorderStyleEnum(BorderStyle poiBorderStyle) { + this.poiBorderStyle = poiBorderStyle; + } +} diff --git a/src/main/java/com/alibaba/excel/enums/poi/FillPatternTypeEnum.java b/src/main/java/com/alibaba/excel/enums/poi/FillPatternTypeEnum.java new file mode 100644 index 00000000..26fb8b32 --- /dev/null +++ b/src/main/java/com/alibaba/excel/enums/poi/FillPatternTypeEnum.java @@ -0,0 +1,119 @@ +package com.alibaba.excel.enums.poi; + +import lombok.Getter; +import org.apache.poi.ss.usermodel.FillPatternType; + +/** + * The enumeration value indicating the style of fill pattern being used for a cell format. + * + * @author Jiaju Zhuang + */ +@Getter +public enum FillPatternTypeEnum { + + /** + * null + */ + DEFAULT(null), + + /** + * No background + */ + NO_FILL(FillPatternType.NO_FILL), + + /** + * Solidly filled + */ + SOLID_FOREGROUND(FillPatternType.SOLID_FOREGROUND), + + /** + * Small fine dots + */ + FINE_DOTS(FillPatternType.FINE_DOTS), + + /** + * Wide dots + */ + ALT_BARS(FillPatternType.ALT_BARS), + + /** + * Sparse dots + */ + SPARSE_DOTS(FillPatternType.SPARSE_DOTS), + + /** + * Thick horizontal bands + */ + THICK_HORZ_BANDS(FillPatternType.THICK_HORZ_BANDS), + + /** + * Thick vertical bands + */ + THICK_VERT_BANDS(FillPatternType.THICK_VERT_BANDS), + + /** + * Thick backward facing diagonals + */ + THICK_BACKWARD_DIAG(FillPatternType.THICK_BACKWARD_DIAG), + + /** + * Thick forward facing diagonals + */ + THICK_FORWARD_DIAG(FillPatternType.THICK_FORWARD_DIAG), + + /** + * Large spots + */ + BIG_SPOTS(FillPatternType.BIG_SPOTS), + + /** + * Brick-like layout + */ + BRICKS(FillPatternType.BRICKS), + + /** + * Thin horizontal bands + */ + THIN_HORZ_BANDS(FillPatternType.THIN_HORZ_BANDS), + + /** + * Thin vertical bands + */ + THIN_VERT_BANDS(FillPatternType.THIN_VERT_BANDS), + + /** + * Thin backward diagonal + */ + THIN_BACKWARD_DIAG(FillPatternType.THIN_BACKWARD_DIAG), + + /** + * Thin forward diagonal + */ + THIN_FORWARD_DIAG(FillPatternType.THIN_FORWARD_DIAG), + + /** + * Squares + */ + SQUARES(FillPatternType.SQUARES), + + /** + * Diamonds + */ + DIAMONDS(FillPatternType.DIAMONDS), + + /** + * Less Dots + */ + LESS_DOTS(FillPatternType.LESS_DOTS), + + /** + * Least Dots + */ + LEAST_DOTS(FillPatternType.LEAST_DOTS); + + FillPatternType poiFillPatternType; + + FillPatternTypeEnum(FillPatternType poiFillPatternType) { + this.poiFillPatternType = poiFillPatternType; + } +} diff --git a/src/main/java/com/alibaba/excel/enums/poi/HorizontalAlignmentEnum.java b/src/main/java/com/alibaba/excel/enums/poi/HorizontalAlignmentEnum.java new file mode 100644 index 00000000..2c0b3511 --- /dev/null +++ b/src/main/java/com/alibaba/excel/enums/poi/HorizontalAlignmentEnum.java @@ -0,0 +1,94 @@ +package com.alibaba.excel.enums.poi; + +import lombok.Getter; +import org.apache.poi.ss.usermodel.HorizontalAlignment; + +/** + * The enumeration value indicating horizontal alignment of a cell, + * i.e., whether it is aligned general, left, right, horizontally centered, filled (replicated), + * justified, centered across multiple cells, or distributed. + * @author Jiaju Zhuang + */ +@Getter +public enum HorizontalAlignmentEnum { + /** + * null + */ + DEFAULT(null), + /** + * The horizontal alignment is general-aligned. Text data is left-aligned. + * Numbers, dates, and times are rightaligned. Boolean types are centered. + * Changing the alignment does not change the type of data. + */ + GENERAL(HorizontalAlignment.GENERAL), + + /** + * The horizontal alignment is left-aligned, even in Rightto-Left mode. + * Aligns contents at the left edge of the cell. If an indent amount is specified, the contents of + * the cell is indented from the left by the specified number of character spaces. The character spaces are + * based on the default font and font size for the workbook. + */ + LEFT(HorizontalAlignment.LEFT), + + /** + * The horizontal alignment is centered, meaning the text is centered across the cell. + */ + CENTER(HorizontalAlignment.CENTER), + + /** + * The horizontal alignment is right-aligned, meaning that cell contents are aligned at the right edge of the cell, + * even in Right-to-Left mode. + */ + RIGHT(HorizontalAlignment.RIGHT), + + /** + * Indicates that the value of the cell should be filled + * across the entire width of the cell. If blank cells to the right also have the fill alignment, + * they are also filled with the value, using a convention similar to centerContinuous. + *

+ * Additional rules: + *

    + *
  1. Only whole values can be appended, not partial values.
  2. + *
  3. The column will not be widened to 'best fit' the filled value
  4. + *
  5. If appending an additional occurrence of the value exceeds the boundary of the cell + * left/right edge, don't append the additional occurrence of the value.
  6. + *
  7. The display value of the cell is filled, not the underlying raw number.
  8. + *
+ *

+ */ + FILL(HorizontalAlignment.FILL), + + /** + * The horizontal alignment is justified (flush left and right). + * For each line of text, aligns each line of the wrapped text in a cell to the right and left + * (except the last line). If no single line of text wraps in the cell, then the text is not justified. + */ + JUSTIFY(HorizontalAlignment.JUSTIFY), + + /** + * The horizontal alignment is centered across multiple cells. + * The information about how many cells to span is expressed in the Sheet Part, + * in the row of the cell in question. For each cell that is spanned in the alignment, + * a cell element needs to be written out, with the same style Id which references the centerContinuous alignment. + */ + CENTER_SELECTION(HorizontalAlignment.CENTER_SELECTION), + + /** + * Indicates that each 'word' in each line of text inside the cell is evenly distributed + * across the width of the cell, with flush right and left margins. + *

+ * When there is also an indent value to apply, both the left and right side of the cell + * are padded by the indent value. + *

+ *

A 'word' is a set of characters with no space character in them.

+ *

Two lines inside a cell are separated by a carriage return.

+ */ + DISTRIBUTED(HorizontalAlignment.DISTRIBUTED); + + HorizontalAlignment poiHorizontalAlignment; + + HorizontalAlignmentEnum(HorizontalAlignment poiHorizontalAlignment) { + this.poiHorizontalAlignment = poiHorizontalAlignment; + } + +} diff --git a/src/main/java/com/alibaba/excel/enums/poi/VerticalAlignmentEnum.java b/src/main/java/com/alibaba/excel/enums/poi/VerticalAlignmentEnum.java new file mode 100644 index 00000000..d980beca --- /dev/null +++ b/src/main/java/com/alibaba/excel/enums/poi/VerticalAlignmentEnum.java @@ -0,0 +1,71 @@ +package com.alibaba.excel.enums.poi; + +import lombok.Getter; +import org.apache.poi.ss.usermodel.VerticalAlignment; + +/** + * This enumeration value indicates the type of vertical alignment for a cell, i.e., + * whether it is aligned top, bottom, vertically centered, justified or distributed. + * + * + * + * @author Jiaju Zhuang + */ +@Getter +public enum VerticalAlignmentEnum { + /** + * null + */ + DEFAULT(null), + /** + * The vertical alignment is aligned-to-top. + */ + TOP(VerticalAlignment.TOP), + + /** + * The vertical alignment is centered across the height of the cell. + */ + CENTER(VerticalAlignment.CENTER), + + /** + * The vertical alignment is aligned-to-bottom. (typically the default value) + */ + BOTTOM(VerticalAlignment.BOTTOM), + + /** + *

+ * When text direction is horizontal: the vertical alignment of lines of text is distributed vertically, + * where each line of text inside the cell is evenly distributed across the height of the cell, + * with flush top and bottom margins. + *

+ *

+ * When text direction is vertical: similar behavior as horizontal justification. + * The alignment is justified (flush top and bottom in this case). For each line of text, each + * line of the wrapped text in a cell is aligned to the top and bottom (except the last line). + * If no single line of text wraps in the cell, then the text is not justified. + *

+ */ + JUSTIFY(VerticalAlignment.JUSTIFY), + + /** + *

+ * When text direction is horizontal: the vertical alignment of lines of text is distributed vertically, + * where each line of text inside the cell is evenly distributed across the height of the cell, + * with flush top + *

+ *

+ * When text direction is vertical: behaves exactly as distributed horizontal alignment. + * The first words in a line of text (appearing at the top of the cell) are flush + * with the top edge of the cell, and the last words of a line of text are flush with the bottom edge of the cell, + * and the line of text is distributed evenly from top to bottom. + *

+ */ + DISTRIBUTED(VerticalAlignment.DISTRIBUTED); + + VerticalAlignment poiVerticalAlignmentEnum; + + VerticalAlignmentEnum(VerticalAlignment poiVerticalAlignmentEnum) { + this.poiVerticalAlignmentEnum = poiVerticalAlignmentEnum; + } +} diff --git a/src/main/java/com/alibaba/excel/metadata/data/DataFormatData.java b/src/main/java/com/alibaba/excel/metadata/data/DataFormatData.java index 7f1a14c8..877ca270 100644 --- a/src/main/java/com/alibaba/excel/metadata/data/DataFormatData.java +++ b/src/main/java/com/alibaba/excel/metadata/data/DataFormatData.java @@ -1,5 +1,7 @@ package com.alibaba.excel.metadata.data; +import com.alibaba.excel.util.StringUtils; + import lombok.Data; /** @@ -19,6 +21,24 @@ public class DataFormatData { */ private String format; + /** + * The source is not empty merge the data to the target. + * + * @param source source + * @param target target + */ + public static void merge(DataFormatData source, DataFormatData target) { + if (source == null || target == null) { + return; + } + if (source.getIndex() != null) { + target.setIndex(source.getIndex()); + } + if (StringUtils.isNotBlank(source.getFormat())) { + target.setFormat(source.getFormat()); + } + } + @Override public DataFormatData clone() { DataFormatData dataFormatData = new DataFormatData(); diff --git a/src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java b/src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java index ed522b81..60413385 100644 --- a/src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java +++ b/src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java @@ -116,4 +116,15 @@ public class WriteCellData extends CellData { imageDataList.add(imageData); } + /** + * Return a style, if is empty, create a new + * + * @return not null. + */ + public WriteCellStyle getOrCreateStyle() { + if (this.writeCellStyle == null) { + this.writeCellStyle = new WriteCellStyle(); + } + return this.writeCellStyle; + } } diff --git a/src/main/java/com/alibaba/excel/metadata/property/DateTimeFormatProperty.java b/src/main/java/com/alibaba/excel/metadata/property/DateTimeFormatProperty.java index 798dca93..d2bb20cd 100644 --- a/src/main/java/com/alibaba/excel/metadata/property/DateTimeFormatProperty.java +++ b/src/main/java/com/alibaba/excel/metadata/property/DateTimeFormatProperty.java @@ -1,12 +1,16 @@ package com.alibaba.excel.metadata.property; import com.alibaba.excel.annotation.format.DateTimeFormat; +import com.alibaba.excel.util.BooleanUtils; + +import lombok.Data; /** * Configuration from annotations * * @author Jiaju Zhuang */ +@Data public class DateTimeFormatProperty { private String format; private Boolean use1904windowing; @@ -20,22 +24,7 @@ public class DateTimeFormatProperty { if (dateTimeFormat == null) { return null; } - return new DateTimeFormatProperty(dateTimeFormat.value(), dateTimeFormat.use1904windowing()); - } - - public String getFormat() { - return format; - } - - public void setFormat(String format) { - this.format = format; - } - - public Boolean getUse1904windowing() { - return use1904windowing; - } - - public void setUse1904windowing(Boolean use1904windowing) { - this.use1904windowing = use1904windowing; + return new DateTimeFormatProperty(dateTimeFormat.value(), + BooleanUtils.isTrue(dateTimeFormat.use1904windowing().getBooleanValue())); } } diff --git a/src/main/java/com/alibaba/excel/metadata/property/FontProperty.java b/src/main/java/com/alibaba/excel/metadata/property/FontProperty.java index 06aec863..619cfe6b 100644 --- a/src/main/java/com/alibaba/excel/metadata/property/FontProperty.java +++ b/src/main/java/com/alibaba/excel/metadata/property/FontProperty.java @@ -1,18 +1,21 @@ package com.alibaba.excel.metadata.property; +import com.alibaba.excel.annotation.write.style.ContentFontStyle; +import com.alibaba.excel.annotation.write.style.HeadFontStyle; +import com.alibaba.excel.util.StringUtils; + +import lombok.Data; import org.apache.poi.common.usermodel.fonts.FontCharset; import org.apache.poi.hssf.usermodel.HSSFPalette; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.IndexedColors; -import com.alibaba.excel.annotation.write.style.ContentFontStyle; -import com.alibaba.excel.annotation.write.style.HeadFontStyle; - /** * Configuration from annotations * * @author Jiaju Zhuang */ +@Data public class FontProperty { /** * The name for the font (i.e. Arial) @@ -77,15 +80,27 @@ public class FontProperty { return null; } FontProperty styleProperty = new FontProperty(); - styleProperty.setFontName(headFontStyle.fontName()); - styleProperty.setFontHeightInPoints(headFontStyle.fontHeightInPoints()); - styleProperty.setItalic(headFontStyle.italic()); - styleProperty.setStrikeout(headFontStyle.strikeout()); - styleProperty.setColor(headFontStyle.color()); - styleProperty.setTypeOffset(headFontStyle.typeOffset()); - styleProperty.setUnderline(headFontStyle.underline()); - styleProperty.setCharset(headFontStyle.charset()); - styleProperty.setBold(headFontStyle.bold()); + if (StringUtils.isNotBlank(headFontStyle.fontName())) { + styleProperty.setFontName(headFontStyle.fontName()); + } + if (headFontStyle.fontHeightInPoints() >= 0) { + styleProperty.setFontHeightInPoints(headFontStyle.fontHeightInPoints()); + } + styleProperty.setItalic(headFontStyle.italic().getBooleanValue()); + styleProperty.setStrikeout(headFontStyle.strikeout().getBooleanValue()); + if (headFontStyle.color() >= 0) { + styleProperty.setColor(headFontStyle.color()); + } + if (headFontStyle.typeOffset() >= 0) { + styleProperty.setTypeOffset(headFontStyle.typeOffset()); + } + if (headFontStyle.underline() >= 0) { + styleProperty.setUnderline(headFontStyle.underline()); + } + if (headFontStyle.charset() >= 0) { + styleProperty.setCharset(headFontStyle.charset()); + } + styleProperty.setBold(headFontStyle.bold().getBooleanValue()); return styleProperty; } @@ -94,87 +109,28 @@ public class FontProperty { return null; } FontProperty styleProperty = new FontProperty(); - styleProperty.setFontName(contentFontStyle.fontName()); - styleProperty.setFontHeightInPoints(contentFontStyle.fontHeightInPoints()); - styleProperty.setItalic(contentFontStyle.italic()); - styleProperty.setStrikeout(contentFontStyle.strikeout()); - styleProperty.setColor(contentFontStyle.color()); - styleProperty.setTypeOffset(contentFontStyle.typeOffset()); - styleProperty.setUnderline(contentFontStyle.underline()); - styleProperty.setCharset(contentFontStyle.charset()); - styleProperty.setBold(contentFontStyle.bold()); + if (StringUtils.isNotBlank(contentFontStyle.fontName())) { + styleProperty.setFontName(contentFontStyle.fontName()); + } + if (contentFontStyle.fontHeightInPoints() >= 0) { + styleProperty.setFontHeightInPoints(contentFontStyle.fontHeightInPoints()); + } + styleProperty.setItalic(contentFontStyle.italic().getBooleanValue()); + styleProperty.setStrikeout(contentFontStyle.strikeout().getBooleanValue()); + if (contentFontStyle.color() >= 0) { + styleProperty.setColor(contentFontStyle.color()); + } + if (contentFontStyle.typeOffset() >= 0) { + styleProperty.setTypeOffset(contentFontStyle.typeOffset()); + } + if (contentFontStyle.underline() >= 0) { + styleProperty.setUnderline(contentFontStyle.underline()); + } + if (contentFontStyle.charset() >= 0) { + styleProperty.setCharset(contentFontStyle.charset()); + } + styleProperty.setBold(contentFontStyle.bold().getBooleanValue()); return styleProperty; } - public String getFontName() { - return fontName; - } - - public void setFontName(String fontName) { - this.fontName = fontName; - } - - public Short getFontHeightInPoints() { - return fontHeightInPoints; - } - - public void setFontHeightInPoints(Short fontHeightInPoints) { - this.fontHeightInPoints = fontHeightInPoints; - } - - public Boolean getItalic() { - return italic; - } - - public void setItalic(Boolean italic) { - this.italic = italic; - } - - public Boolean getStrikeout() { - return strikeout; - } - - public void setStrikeout(Boolean strikeout) { - this.strikeout = strikeout; - } - - public Short getColor() { - return color; - } - - public void setColor(Short color) { - this.color = color; - } - - public Short getTypeOffset() { - return typeOffset; - } - - public void setTypeOffset(Short typeOffset) { - this.typeOffset = typeOffset; - } - - public Byte getUnderline() { - return underline; - } - - public void setUnderline(Byte underline) { - this.underline = underline; - } - - public Integer getCharset() { - return charset; - } - - public void setCharset(Integer charset) { - this.charset = charset; - } - - public Boolean getBold() { - return bold; - } - - public void setBold(Boolean bold) { - this.bold = bold; - } } diff --git a/src/main/java/com/alibaba/excel/metadata/property/StyleProperty.java b/src/main/java/com/alibaba/excel/metadata/property/StyleProperty.java index f6d0ab0b..4ef87f68 100644 --- a/src/main/java/com/alibaba/excel/metadata/property/StyleProperty.java +++ b/src/main/java/com/alibaba/excel/metadata/property/StyleProperty.java @@ -143,29 +143,47 @@ public class StyleProperty { return null; } StyleProperty styleProperty = new StyleProperty(); - DataFormatData dataFormatData = new DataFormatData(); - dataFormatData.setIndex(headStyle.dataFormat()); - styleProperty.setDataFormatData(dataFormatData); - styleProperty.setHidden(headStyle.hidden()); - styleProperty.setLocked(headStyle.locked()); - styleProperty.setQuotePrefix(headStyle.quotePrefix()); - styleProperty.setHorizontalAlignment(headStyle.horizontalAlignment()); - styleProperty.setWrapped(headStyle.wrapped()); - styleProperty.setVerticalAlignment(headStyle.verticalAlignment()); - styleProperty.setRotation(headStyle.rotation()); - styleProperty.setIndent(headStyle.indent()); - styleProperty.setBorderLeft(headStyle.borderLeft()); - styleProperty.setBorderRight(headStyle.borderRight()); - styleProperty.setBorderTop(headStyle.borderTop()); - styleProperty.setBorderBottom(headStyle.borderBottom()); - styleProperty.setLeftBorderColor(headStyle.leftBorderColor()); - styleProperty.setRightBorderColor(headStyle.rightBorderColor()); - styleProperty.setTopBorderColor(headStyle.topBorderColor()); - styleProperty.setBottomBorderColor(headStyle.bottomBorderColor()); - styleProperty.setFillPatternType(headStyle.fillPatternType()); - styleProperty.setFillBackgroundColor(headStyle.fillBackgroundColor()); - styleProperty.setFillForegroundColor(headStyle.fillForegroundColor()); - styleProperty.setShrinkToFit(headStyle.shrinkToFit()); + if (headStyle.dataFormat() >= 0) { + DataFormatData dataFormatData = new DataFormatData(); + dataFormatData.setIndex(headStyle.dataFormat()); + styleProperty.setDataFormatData(dataFormatData); + } + styleProperty.setHidden(headStyle.hidden().getBooleanValue()); + styleProperty.setLocked(headStyle.locked().getBooleanValue()); + styleProperty.setQuotePrefix(headStyle.quotePrefix().getBooleanValue()); + styleProperty.setHorizontalAlignment(headStyle.horizontalAlignment().getPoiHorizontalAlignment()); + styleProperty.setWrapped(headStyle.wrapped().getBooleanValue()); + styleProperty.setVerticalAlignment(headStyle.verticalAlignment().getPoiVerticalAlignmentEnum()); + if (headStyle.rotation() >= 0) { + styleProperty.setRotation(headStyle.rotation()); + } + if (headStyle.indent() >= 0) { + styleProperty.setIndent(headStyle.indent()); + } + styleProperty.setBorderLeft(headStyle.borderLeft().getPoiBorderStyle()); + styleProperty.setBorderRight(headStyle.borderRight().getPoiBorderStyle()); + styleProperty.setBorderTop(headStyle.borderTop().getPoiBorderStyle()); + styleProperty.setBorderBottom(headStyle.borderBottom().getPoiBorderStyle()); + if (headStyle.leftBorderColor() >= 0) { + styleProperty.setLeftBorderColor(headStyle.leftBorderColor()); + } + if (headStyle.rightBorderColor() >= 0) { + styleProperty.setRightBorderColor(headStyle.rightBorderColor()); + } + if (headStyle.topBorderColor() >= 0) { + styleProperty.setTopBorderColor(headStyle.topBorderColor()); + } + if (headStyle.bottomBorderColor() >= 0) { + styleProperty.setBottomBorderColor(headStyle.bottomBorderColor()); + } + styleProperty.setFillPatternType(headStyle.fillPatternType().getPoiFillPatternType()); + if (headStyle.fillBackgroundColor() >= 0) { + styleProperty.setFillBackgroundColor(headStyle.fillBackgroundColor()); + } + if (headStyle.fillForegroundColor() >= 0) { + styleProperty.setFillForegroundColor(headStyle.fillForegroundColor()); + } + styleProperty.setShrinkToFit(headStyle.shrinkToFit().getBooleanValue()); return styleProperty; } @@ -174,29 +192,47 @@ public class StyleProperty { return null; } StyleProperty styleProperty = new StyleProperty(); - DataFormatData dataFormatData = new DataFormatData(); - dataFormatData.setIndex(contentStyle.dataFormat()); - styleProperty.setDataFormatData(dataFormatData); - styleProperty.setHidden(contentStyle.hidden()); - styleProperty.setLocked(contentStyle.locked()); - styleProperty.setQuotePrefix(contentStyle.quotePrefix()); - styleProperty.setHorizontalAlignment(contentStyle.horizontalAlignment()); - styleProperty.setWrapped(contentStyle.wrapped()); - styleProperty.setVerticalAlignment(contentStyle.verticalAlignment()); - styleProperty.setRotation(contentStyle.rotation()); - styleProperty.setIndent(contentStyle.indent()); - styleProperty.setBorderLeft(contentStyle.borderLeft()); - styleProperty.setBorderRight(contentStyle.borderRight()); - styleProperty.setBorderTop(contentStyle.borderTop()); - styleProperty.setBorderBottom(contentStyle.borderBottom()); - styleProperty.setLeftBorderColor(contentStyle.leftBorderColor()); - styleProperty.setRightBorderColor(contentStyle.rightBorderColor()); - styleProperty.setTopBorderColor(contentStyle.topBorderColor()); - styleProperty.setBottomBorderColor(contentStyle.bottomBorderColor()); - styleProperty.setFillPatternType(contentStyle.fillPatternType()); - styleProperty.setFillBackgroundColor(contentStyle.fillBackgroundColor()); - styleProperty.setFillForegroundColor(contentStyle.fillForegroundColor()); - styleProperty.setShrinkToFit(contentStyle.shrinkToFit()); + if (contentStyle.dataFormat() >= 0) { + DataFormatData dataFormatData = new DataFormatData(); + dataFormatData.setIndex(contentStyle.dataFormat()); + styleProperty.setDataFormatData(dataFormatData); + } + styleProperty.setHidden(contentStyle.hidden().getBooleanValue()); + styleProperty.setLocked(contentStyle.locked().getBooleanValue()); + styleProperty.setQuotePrefix(contentStyle.quotePrefix().getBooleanValue()); + styleProperty.setHorizontalAlignment(contentStyle.horizontalAlignment().getPoiHorizontalAlignment()); + styleProperty.setWrapped(contentStyle.wrapped().getBooleanValue()); + styleProperty.setVerticalAlignment(contentStyle.verticalAlignment().getPoiVerticalAlignmentEnum()); + if (contentStyle.rotation() >= 0) { + styleProperty.setRotation(contentStyle.rotation()); + } + if (contentStyle.indent() >= 0) { + styleProperty.setIndent(contentStyle.indent()); + } + styleProperty.setBorderLeft(contentStyle.borderLeft().getPoiBorderStyle()); + styleProperty.setBorderRight(contentStyle.borderRight().getPoiBorderStyle()); + styleProperty.setBorderTop(contentStyle.borderTop().getPoiBorderStyle()); + styleProperty.setBorderBottom(contentStyle.borderBottom().getPoiBorderStyle()); + if (contentStyle.leftBorderColor() >= 0) { + styleProperty.setLeftBorderColor(contentStyle.leftBorderColor()); + } + if (contentStyle.rightBorderColor() >= 0) { + styleProperty.setRightBorderColor(contentStyle.rightBorderColor()); + } + if (contentStyle.topBorderColor() >= 0) { + styleProperty.setTopBorderColor(contentStyle.topBorderColor()); + } + if (contentStyle.bottomBorderColor() >= 0) { + styleProperty.setBottomBorderColor(contentStyle.bottomBorderColor()); + } + styleProperty.setFillPatternType(contentStyle.fillPatternType().getPoiFillPatternType()); + if (contentStyle.fillBackgroundColor() >= 0) { + styleProperty.setFillBackgroundColor(contentStyle.fillBackgroundColor()); + } + if (contentStyle.fillForegroundColor() >= 0) { + styleProperty.setFillForegroundColor(contentStyle.fillForegroundColor()); + } + styleProperty.setShrinkToFit(contentStyle.shrinkToFit().getBooleanValue()); return styleProperty; } } diff --git a/src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java b/src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java index 2e7863e8..4279baf4 100644 --- a/src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java +++ b/src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java @@ -16,6 +16,7 @@ import com.alibaba.excel.write.handler.context.RowWriteHandlerContext; import com.alibaba.excel.write.handler.context.SheetWriteHandlerContext; import com.alibaba.excel.write.handler.context.WorkbookWriteHandlerContext; +import org.apache.commons.collections4.CollectionUtils; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; @@ -123,7 +124,7 @@ public class WriteHandlerUtils { } CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(), writeContext.writeSheetHolder(), writeContext.writeTableHolder(), row, null, columnIndex, relativeRowIndex, - head, null, isHead); + head, null, null, isHead); for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof CellWriteHandler) { ((CellWriteHandler)writeHandler).beforeCellCreate(context); @@ -140,7 +141,7 @@ public class WriteHandlerUtils { } CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(), writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cell.getRow(), cell, - cell.getColumnIndex(), relativeRowIndex, head, null, isHead); + cell.getColumnIndex(), relativeRowIndex, head, null, null, isHead); for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof CellWriteHandler) { ((CellWriteHandler)writeHandler).afterCellCreate(context); @@ -159,7 +160,7 @@ public class WriteHandlerUtils { List> cellDataList = cellData == null ? null : ListUtils.newArrayList(cellData); CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(), writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cell.getRow(), cell, - cell.getColumnIndex(), relativeRowIndex, head, cellDataList, isHead); + cell.getColumnIndex(), relativeRowIndex, head, cellDataList, cellData, isHead); for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof CellWriteHandler) { ((CellWriteHandler)writeHandler).afterCellDataConverted(context); @@ -181,9 +182,13 @@ public class WriteHandlerUtils { if (handlerList == null || handlerList.isEmpty()) { return; } + WriteCellData cellData = null; + if (CollectionUtils.isNotEmpty(cellDataList)) { + cellData = cellDataList.get(0); + } CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(), writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cell.getRow(), cell, - cell.getColumnIndex(), relativeRowIndex, head, cellDataList, isHead); + cell.getColumnIndex(), relativeRowIndex, head, cellDataList, cellData, isHead); for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof CellWriteHandler) { ((CellWriteHandler)writeHandler).afterCellDispose(context); diff --git a/src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java b/src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java index 284397b6..7fda3908 100644 --- a/src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java +++ b/src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java @@ -6,15 +6,7 @@ import java.util.List; import com.alibaba.excel.write.handler.impl.DefaultRowWriteHandler; import com.alibaba.excel.write.handler.impl.DimensionWorkbookWriteHandler; import com.alibaba.excel.write.handler.impl.FillStyleCellWriteHandler; -import com.alibaba.excel.write.metadata.style.WriteCellStyle; -import com.alibaba.excel.write.metadata.style.WriteFont; -import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; - -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.FillPatternType; -import org.apache.poi.ss.usermodel.HorizontalAlignment; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.VerticalAlignment; +import com.alibaba.excel.write.style.DefaultStyle; /** * Load default handler @@ -39,23 +31,7 @@ public class DefaultWriteHandlerLoader { public static List loadDefaultHandler(Boolean useDefaultStyle) { List handlerList = new ArrayList<>(); if (useDefaultStyle) { - WriteCellStyle headWriteCellStyle = new WriteCellStyle(); - headWriteCellStyle.setWrapped(true); - headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); - headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); - headWriteCellStyle.setLocked(true); - headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND); - headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); - headWriteCellStyle.setBorderTop(BorderStyle.THIN); - headWriteCellStyle.setBorderBottom(BorderStyle.THIN); - headWriteCellStyle.setBorderLeft(BorderStyle.THIN); - headWriteCellStyle.setBorderRight(BorderStyle.THIN); - WriteFont headWriteFont = new WriteFont(); - headWriteFont.setFontName("宋体"); - headWriteFont.setFontHeightInPoints((short)14); - headWriteFont.setBold(true); - headWriteCellStyle.setWriteFont(headWriteFont); - handlerList.add(new HorizontalCellStyleStrategy(headWriteCellStyle, new ArrayList<>())); + handlerList.add(new DefaultStyle()); } handlerList.addAll(DEFAULT_WRITE_HANDLER_LIST); return handlerList; diff --git a/src/main/java/com/alibaba/excel/write/handler/context/CellWriteHandlerContext.java b/src/main/java/com/alibaba/excel/write/handler/context/CellWriteHandlerContext.java index 6dd9a988..92c1500f 100644 --- a/src/main/java/com/alibaba/excel/write/handler/context/CellWriteHandlerContext.java +++ b/src/main/java/com/alibaba/excel/write/handler/context/CellWriteHandlerContext.java @@ -62,6 +62,13 @@ public class CellWriteHandlerContext { * Nullable.It is null in the case of add header.There may be several when fill the data. */ private List> cellDataList; + /** + * Nullable. + * It is null in the case of add header. + * In the case of write there must be not null. + * firstCellData == cellDataList.get(0) + */ + private WriteCellData firstCellData; /** * Nullable.It is null in the case of fill data. */ diff --git a/src/main/java/com/alibaba/excel/write/metadata/style/WriteCellStyle.java b/src/main/java/com/alibaba/excel/write/metadata/style/WriteCellStyle.java index 4b76805b..fcbbdaed 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/style/WriteCellStyle.java +++ b/src/main/java/com/alibaba/excel/write/metadata/style/WriteCellStyle.java @@ -139,74 +139,207 @@ public class WriteCellStyle { */ private Boolean shrinkToFit; + /** + * The source is not empty merge the data to the target. + * + * @param source source + * @param target target + */ + public static void merge(WriteCellStyle source, WriteCellStyle target) { + if (source == null || target == null) { + return; + } + if (source.getDataFormatData() != null) { + if (target.getDataFormatData() == null) { + target.setDataFormatData(source.getDataFormatData()); + } else { + DataFormatData.merge(source.getDataFormatData(), target.getDataFormatData()); + } + } + if (source.getWriteFont() != null) { + if (target.getWriteFont() == null) { + target.setWriteFont(source.getWriteFont()); + } else { + WriteFont.merge(source.getWriteFont(), target.getWriteFont()); + } + } + if (source.getHidden() != null) { + target.setHidden(source.getHidden()); + } + if (source.getLocked() != null) { + target.setLocked(source.getLocked()); + } + if (source.getQuotePrefix() != null) { + target.setQuotePrefix(source.getQuotePrefix()); + } + if (source.getHorizontalAlignment() != null) { + target.setHorizontalAlignment(source.getHorizontalAlignment()); + } + if (source.getWrapped() != null) { + target.setWrapped(source.getWrapped()); + } + if (source.getVerticalAlignment() != null) { + target.setVerticalAlignment(source.getVerticalAlignment()); + } + if (source.getRotation() != null) { + target.setRotation(source.getRotation()); + } + if (source.getIndent() != null) { + target.setIndent(source.getIndent()); + } + if (source.getBorderLeft() != null) { + target.setBorderLeft(source.getBorderLeft()); + } + if (source.getBorderRight() != null) { + target.setBorderRight(source.getBorderRight()); + } + if (source.getBorderTop() != null) { + target.setBorderTop(source.getBorderTop()); + } + if (source.getBorderBottom() != null) { + target.setBorderBottom(source.getBorderBottom()); + } + if (source.getLeftBorderColor() != null) { + target.setLeftBorderColor(source.getLeftBorderColor()); + } + if (source.getRightBorderColor() != null) { + target.setRightBorderColor(source.getRightBorderColor()); + } + if (source.getTopBorderColor() != null) { + target.setTopBorderColor(source.getTopBorderColor()); + } + if (source.getBottomBorderColor() != null) { + target.setBottomBorderColor(source.getBottomBorderColor()); + } + if (source.getFillPatternType() != null) { + target.setFillPatternType(source.getFillPatternType()); + } + if (source.getFillBackgroundColor() != null) { + target.setFillBackgroundColor(source.getFillBackgroundColor()); + } + if (source.getFillForegroundColor() != null) { + target.setFillForegroundColor(source.getFillForegroundColor()); + } + if (source.getShrinkToFit() != null) { + target.setShrinkToFit(source.getShrinkToFit()); + } + } + + /** + * The source is not empty merge the data to the target. + * + * @param styleProperty styleProperty + * @param fontProperty fontProperty + */ public static WriteCellStyle build(StyleProperty styleProperty, FontProperty fontProperty) { if (styleProperty == null && fontProperty == null) { return null; } WriteCellStyle writeCellStyle = new WriteCellStyle(); if (styleProperty != null) { - writeCellStyle.setDataFormatData(styleProperty.getDataFormatData()); - writeCellStyle.setHidden(styleProperty.getHidden()); - writeCellStyle.setLocked(styleProperty.getLocked()); - writeCellStyle.setQuotePrefix(styleProperty.getQuotePrefix()); - writeCellStyle.setHorizontalAlignment(styleProperty.getHorizontalAlignment()); - writeCellStyle.setWrapped(styleProperty.getWrapped()); - writeCellStyle.setVerticalAlignment(styleProperty.getVerticalAlignment()); - if (styleProperty.getRotation() >= 0) { + if (styleProperty.getDataFormatData() != null) { + if (writeCellStyle.getDataFormatData() == null) { + writeCellStyle.setDataFormatData(styleProperty.getDataFormatData()); + } else { + DataFormatData.merge(styleProperty.getDataFormatData(), writeCellStyle.getDataFormatData()); + } + } + if (styleProperty.getHidden() != null) { + writeCellStyle.setHidden(styleProperty.getHidden()); + } + if (styleProperty.getLocked() != null) { + writeCellStyle.setLocked(styleProperty.getLocked()); + } + if (styleProperty.getQuotePrefix() != null) { + writeCellStyle.setQuotePrefix(styleProperty.getQuotePrefix()); + } + if (styleProperty.getHorizontalAlignment() != null) { + writeCellStyle.setHorizontalAlignment(styleProperty.getHorizontalAlignment()); + } + if (styleProperty.getWrapped() != null) { + writeCellStyle.setWrapped(styleProperty.getWrapped()); + } + if (styleProperty.getVerticalAlignment() != null) { + writeCellStyle.setVerticalAlignment(styleProperty.getVerticalAlignment()); + } + if (styleProperty.getRotation() != null) { writeCellStyle.setRotation(styleProperty.getRotation()); } - if (styleProperty.getIndent() >= 0) { + if (styleProperty.getIndent() != null) { writeCellStyle.setIndent(styleProperty.getIndent()); } - writeCellStyle.setBorderLeft(styleProperty.getBorderLeft()); - writeCellStyle.setBorderRight(styleProperty.getBorderRight()); - writeCellStyle.setBorderTop(styleProperty.getBorderTop()); - writeCellStyle.setBorderBottom(styleProperty.getBorderBottom()); - if (styleProperty.getLeftBorderColor() >= 0) { + if (styleProperty.getBorderLeft() != null) { + writeCellStyle.setBorderLeft(styleProperty.getBorderLeft()); + } + if (styleProperty.getBorderRight() != null) { + writeCellStyle.setBorderRight(styleProperty.getBorderRight()); + } + if (styleProperty.getBorderTop() != null) { + writeCellStyle.setBorderTop(styleProperty.getBorderTop()); + } + if (styleProperty.getBorderBottom() != null) { + writeCellStyle.setBorderBottom(styleProperty.getBorderBottom()); + } + if (styleProperty.getLeftBorderColor() != null) { writeCellStyle.setLeftBorderColor(styleProperty.getLeftBorderColor()); } - if (styleProperty.getRightBorderColor() >= 0) { + if (styleProperty.getRightBorderColor() != null) { writeCellStyle.setRightBorderColor(styleProperty.getRightBorderColor()); } - if (styleProperty.getTopBorderColor() >= 0) { + if (styleProperty.getTopBorderColor() != null) { writeCellStyle.setTopBorderColor(styleProperty.getTopBorderColor()); } - if (styleProperty.getBottomBorderColor() >= 0) { + if (styleProperty.getBottomBorderColor() != null) { writeCellStyle.setBottomBorderColor(styleProperty.getBottomBorderColor()); } - writeCellStyle.setFillPatternType(styleProperty.getFillPatternType()); - if (styleProperty.getFillBackgroundColor() >= 0) { + if (styleProperty.getFillPatternType() != null) { + writeCellStyle.setFillPatternType(styleProperty.getFillPatternType()); + } + if (styleProperty.getFillBackgroundColor() != null) { writeCellStyle.setFillBackgroundColor(styleProperty.getFillBackgroundColor()); } - if (styleProperty.getFillForegroundColor() >= 0) { + if (styleProperty.getFillForegroundColor() != null) { writeCellStyle.setFillForegroundColor(styleProperty.getFillForegroundColor()); } - writeCellStyle.setShrinkToFit(styleProperty.getShrinkToFit()); + if (styleProperty.getShrinkToFit() != null) { + writeCellStyle.setShrinkToFit(styleProperty.getShrinkToFit()); + } } if (fontProperty != null) { - WriteFont writeFont = new WriteFont(); - writeCellStyle.setWriteFont(writeFont); - if (!StringUtils.isEmpty(fontProperty.getFontName())) { + if (writeCellStyle.getWriteFont() == null) { + writeCellStyle.setWriteFont(new WriteFont()); + } + WriteFont writeFont = writeCellStyle.getWriteFont(); + + if (StringUtils.isNotBlank(fontProperty.getFontName())) { writeFont.setFontName(fontProperty.getFontName()); } - writeFont.setFontHeightInPoints(fontProperty.getFontHeightInPoints()); - writeFont.setItalic(fontProperty.getItalic()); - writeFont.setStrikeout(fontProperty.getStrikeout()); - if (fontProperty.getColor() >= 0) { + if (fontProperty.getFontHeightInPoints() != null) { + writeFont.setFontHeightInPoints(fontProperty.getFontHeightInPoints()); + } + if (fontProperty.getItalic() != null) { + writeFont.setItalic(fontProperty.getItalic()); + } + if (fontProperty.getStrikeout() != null) { + writeFont.setStrikeout(fontProperty.getStrikeout()); + } + if (fontProperty.getColor() != null) { writeFont.setColor(fontProperty.getColor()); } - if (fontProperty.getTypeOffset() >= 0) { + if (fontProperty.getTypeOffset() != null) { writeFont.setTypeOffset(fontProperty.getTypeOffset()); } - if (fontProperty.getUnderline() >= 0) { + if (fontProperty.getUnderline() != null) { writeFont.setUnderline(fontProperty.getUnderline()); } - if (fontProperty.getCharset() >= 0) { + if (fontProperty.getCharset() != null) { writeFont.setCharset(fontProperty.getCharset()); } - writeFont.setBold(fontProperty.getBold()); + if (fontProperty.getBold() != null) { + writeFont.setBold(fontProperty.getBold()); + } } - return writeCellStyle; } + } diff --git a/src/main/java/com/alibaba/excel/write/metadata/style/WriteFont.java b/src/main/java/com/alibaba/excel/write/metadata/style/WriteFont.java index f7194bf9..d1f42f01 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/style/WriteFont.java +++ b/src/main/java/com/alibaba/excel/write/metadata/style/WriteFont.java @@ -1,5 +1,7 @@ package com.alibaba.excel.write.metadata.style; +import com.alibaba.excel.util.StringUtils; + import lombok.Data; import org.apache.poi.common.usermodel.fonts.FontCharset; import org.apache.poi.hssf.usermodel.HSSFPalette; @@ -70,4 +72,43 @@ public class WriteFont { * Bold */ private Boolean bold; + + /** + * The source is not empty merge the data to the target. + * + * @param source source + * @param target target + */ + public static void merge(WriteFont source, WriteFont target) { + if (source == null || target == null) { + return; + } + if (StringUtils.isNotBlank(source.getFontName())) { + target.setFontName(source.getFontName()); + } + if (source.getFontHeightInPoints() != null) { + target.setFontHeightInPoints(source.getFontHeightInPoints()); + } + if (source.getItalic() != null) { + target.setItalic(source.getItalic()); + } + if (source.getStrikeout() != null) { + target.setStrikeout(source.getStrikeout()); + } + if (source.getColor() != null) { + target.setColor(source.getColor()); + } + if (source.getTypeOffset() != null) { + target.setTypeOffset(source.getTypeOffset()); + } + if (source.getUnderline() != null) { + target.setUnderline(source.getUnderline()); + } + if (source.getCharset() != null) { + target.setCharset(source.getCharset()); + } + if (source.getBold() != null) { + target.setBold(source.getBold()); + } + } } diff --git a/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java index 7d8e1b46..e37987bb 100644 --- a/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java @@ -1,14 +1,10 @@ package com.alibaba.excel.write.style; -import java.util.List; - import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.write.handler.context.CellWriteHandlerContext; import com.alibaba.excel.write.metadata.style.WriteCellStyle; -import org.apache.commons.collections4.CollectionUtils; - /** * Use the same style for the column * @@ -21,8 +17,8 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl if (stopProcessing(context)) { return; } - WriteCellData cellData = context.getCellDataList().get(0); - cellData.setWriteCellStyle(headCellStyle(context.getHeadData())); + WriteCellData cellData = context.getFirstCellData(); + WriteCellStyle.merge(headCellStyle(context.getHeadData()), cellData.getOrCreateStyle()); } @Override @@ -30,8 +26,8 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl if (stopProcessing(context)) { return; } - WriteCellData cellData = context.getCellDataList().get(0); - cellData.setWriteCellStyle(contentCellStyle(context)); + WriteCellData cellData = context.getFirstCellData(); + WriteCellStyle.merge(contentCellStyle(context), cellData.getOrCreateStyle()); } /** @@ -65,8 +61,7 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl } protected boolean stopProcessing(CellWriteHandlerContext context) { - List> cellDataList = context.getCellDataList(); - if (CollectionUtils.isEmpty(cellDataList) || cellDataList.size() > 1) { + if (context.getFirstCellData() == null) { return true; } return context.getHeadData() == null; diff --git a/src/main/java/com/alibaba/excel/write/style/DefaultStyle.java b/src/main/java/com/alibaba/excel/write/style/DefaultStyle.java new file mode 100644 index 00000000..38a43d58 --- /dev/null +++ b/src/main/java/com/alibaba/excel/write/style/DefaultStyle.java @@ -0,0 +1,46 @@ +package com.alibaba.excel.write.style; + +import com.alibaba.excel.constant.OrderConstant; +import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import com.alibaba.excel.write.metadata.style.WriteFont; + +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.VerticalAlignment; + +/** + * The default styles + * + * @author Jiaju Zhuang + */ +public class DefaultStyle extends HorizontalCellStyleStrategy { + + @Override + public int order() { + return OrderConstant.DEFINE_STYLE - 1; + } + + public DefaultStyle() { + super(); + WriteCellStyle headWriteCellStyle = new WriteCellStyle(); + headWriteCellStyle.setWrapped(true); + headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); + headWriteCellStyle.setLocked(true); + headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND); + headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); + headWriteCellStyle.setBorderTop(BorderStyle.THIN); + headWriteCellStyle.setBorderBottom(BorderStyle.THIN); + headWriteCellStyle.setBorderLeft(BorderStyle.THIN); + headWriteCellStyle.setBorderRight(BorderStyle.THIN); + WriteFont headWriteFont = new WriteFont(); + headWriteFont.setFontName("宋体"); + headWriteFont.setFontHeightInPoints((short)14); + headWriteFont.setBold(true); + headWriteCellStyle.setWriteFont(headWriteFont); + + setHeadWriteCellStyle(headWriteCellStyle); + } +} diff --git a/src/main/java/com/alibaba/excel/write/style/HorizontalCellStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/HorizontalCellStyleStrategy.java index 58b0836a..8f033710 100644 --- a/src/main/java/com/alibaba/excel/write/style/HorizontalCellStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/HorizontalCellStyleStrategy.java @@ -7,6 +7,7 @@ import com.alibaba.excel.util.ListUtils; import com.alibaba.excel.write.handler.context.CellWriteHandlerContext; import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import lombok.Data; import org.apache.commons.collections4.CollectionUtils; /** @@ -14,11 +15,15 @@ import org.apache.commons.collections4.CollectionUtils; * * @author Jiaju Zhuang */ +@Data public class HorizontalCellStyleStrategy extends AbstractCellStyleStrategy { private WriteCellStyle headWriteCellStyle; private List contentWriteCellStyleList; + public HorizontalCellStyleStrategy() { + } + public HorizontalCellStyleStrategy(WriteCellStyle headWriteCellStyle, List contentWriteCellStyleList) { this.headWriteCellStyle = headWriteCellStyle; @@ -37,8 +42,8 @@ public class HorizontalCellStyleStrategy extends AbstractCellStyleStrategy { if (stopProcessing(context) || headWriteCellStyle == null) { return; } - WriteCellData cellData = context.getCellDataList().get(0); - cellData.setWriteCellStyle(headWriteCellStyle); + WriteCellData cellData = context.getFirstCellData(); + WriteCellStyle.merge(headWriteCellStyle, cellData.getOrCreateStyle()); } @Override @@ -46,18 +51,18 @@ public class HorizontalCellStyleStrategy extends AbstractCellStyleStrategy { if (stopProcessing(context) || CollectionUtils.isEmpty(contentWriteCellStyleList)) { return; } - WriteCellData cellData = context.getCellDataList().get(0); + WriteCellData cellData = context.getFirstCellData(); if (context.getRelativeRowIndex() == null || context.getRelativeRowIndex() <= 0) { - cellData.setWriteCellStyle(contentWriteCellStyleList.get(0)); + WriteCellStyle.merge(contentWriteCellStyleList.get(0), cellData.getOrCreateStyle()); } else { - cellData.setWriteCellStyle( - contentWriteCellStyleList.get(context.getRelativeRowIndex() % contentWriteCellStyleList.size())); + WriteCellStyle.merge( + contentWriteCellStyleList.get(context.getRelativeRowIndex() % contentWriteCellStyleList.size()), + cellData.getOrCreateStyle()); } } protected boolean stopProcessing(CellWriteHandlerContext context) { - List> cellDataList = context.getCellDataList(); - return CollectionUtils.isEmpty(cellDataList) || cellDataList.size() > 1; + return context.getFirstCellData() == null; } } diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/write/CommentWriteHandler.java b/src/test/java/com/alibaba/easyexcel/test/demo/write/CommentWriteHandler.java index d6eacb42..1be0fbdd 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/write/CommentWriteHandler.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/write/CommentWriteHandler.java @@ -1,29 +1,28 @@ package com.alibaba.easyexcel.test.demo.write; +import com.alibaba.excel.util.BooleanUtils; +import com.alibaba.excel.write.handler.RowWriteHandler; +import com.alibaba.excel.write.handler.context.RowWriteHandlerContext; + +import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.Comment; import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.usermodel.XSSFClientAnchor; import org.apache.poi.xssf.usermodel.XSSFRichTextString; -import com.alibaba.excel.write.handler.AbstractRowWriteHandler; -import com.alibaba.excel.write.handler.RowWriteHandler; -import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; -import com.alibaba.excel.write.metadata.holder.WriteTableHolder; - /** * 自定义拦截器.新增注释,第一行头加批注 * * @author Jiaju Zhuang */ +@Slf4j public class CommentWriteHandler implements RowWriteHandler { @Override - public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, - Integer relativeRowIndex, Boolean isHead) { - if (isHead) { - Sheet sheet = writeSheetHolder.getSheet(); + public void afterRowDispose(RowWriteHandlerContext context) { + if (BooleanUtils.isTrue(context.getHead())) { + Sheet sheet = context.getWriteSheetHolder().getSheet(); Drawing drawingPatriarch = sheet.createDrawingPatriarch(); // 在第一行 第二列创建一个批注 Comment comment = diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java b/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java index 960eda40..81e12f52 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java @@ -1,36 +1,30 @@ package com.alibaba.easyexcel.test.demo.write; -import java.util.List; - -import com.alibaba.excel.metadata.Head; -import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.util.BooleanUtils; import com.alibaba.excel.write.handler.CellWriteHandler; -import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; -import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import com.alibaba.excel.write.handler.context.CellWriteHandlerContext; +import lombok.extern.slf4j.Slf4j; import org.apache.poi.common.usermodel.HyperlinkType; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.ss.usermodel.Hyperlink; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * 自定义拦截器。对第一行第一列的头超链接到:https://github.com/alibaba/easyexcel * * @author Jiaju Zhuang */ +@Slf4j public class CustomCellWriteHandler implements CellWriteHandler { - private static final Logger LOGGER = LoggerFactory.getLogger(CustomCellWriteHandler.class); - @Override - public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + public void afterCellDispose(CellWriteHandlerContext context) { + Cell cell = context.getCell(); // 这里可以对cell进行任何操作 - LOGGER.info("第{}行,第{}列写入完成。", cell.getRowIndex(), cell.getColumnIndex()); - if (isHead && cell.getColumnIndex() == 0) { - CreationHelper createHelper = writeSheetHolder.getSheet().getWorkbook().getCreationHelper(); + log.info("第{}行,第{}列写入完成。", cell.getRowIndex(), cell.getColumnIndex()); + if (BooleanUtils.isTrue(context.getHead()) && cell.getColumnIndex() == 0) { + CreationHelper createHelper = context.getWriteSheetHolder().getSheet().getWorkbook().getCreationHelper(); Hyperlink hyperlink = createHelper.createHyperlink(HyperlinkType.URL); hyperlink.setAddress("https://github.com/alibaba/easyexcel"); cell.setHyperlink(hyperlink); diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomSheetWriteHandler.java b/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomSheetWriteHandler.java index fe29045c..87765358 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomSheetWriteHandler.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomSheetWriteHandler.java @@ -1,39 +1,31 @@ package com.alibaba.easyexcel.test.demo.write; +import com.alibaba.excel.write.handler.SheetWriteHandler; +import com.alibaba.excel.write.handler.context.SheetWriteHandlerContext; + +import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.DataValidation; import org.apache.poi.ss.usermodel.DataValidationConstraint; import org.apache.poi.ss.usermodel.DataValidationHelper; import org.apache.poi.ss.util.CellRangeAddressList; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.alibaba.excel.write.handler.SheetWriteHandler; -import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; -import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; /** * 自定义拦截器.对第一列第一行和第二行的数据新增下拉框,显示 测试1 测试2 * * @author Jiaju Zhuang */ +@Slf4j public class CustomSheetWriteHandler implements SheetWriteHandler { - private static final Logger LOGGER = LoggerFactory.getLogger(CustomSheetWriteHandler.class); - - @Override - public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { - - } - @Override - public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { - LOGGER.info("第{}个Sheet写入成功。", writeSheetHolder.getSheetNo()); + public void afterSheetCreate(SheetWriteHandlerContext context) { + log.info("第{}个Sheet写入成功。", context.getWriteSheetHolder().getSheetNo()); // 区间设置 第一列第一行和第二行的数据。由于第一行是头,所以第一、二行的数据实际上是第二三行 CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 2, 0, 0); - DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper(); + DataValidationHelper helper = context.getWriteSheetHolder().getSheet().getDataValidationHelper(); DataValidationConstraint constraint = helper.createExplicitListConstraint(new String[] {"测试1", "测试2"}); DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList); - writeSheetHolder.getSheet().addValidationData(dataValidation); + context.getWriteSheetHolder().getSheet().addValidationData(dataValidation); } } diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/write/DemoStyleData.java b/src/test/java/com/alibaba/easyexcel/test/demo/write/DemoStyleData.java index c73a088b..6dc60ed1 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/write/DemoStyleData.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/write/DemoStyleData.java @@ -2,13 +2,12 @@ package com.alibaba.easyexcel.test.demo.write; import java.util.Date; -import org.apache.poi.ss.usermodel.FillPatternType; - import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ContentFontStyle; import com.alibaba.excel.annotation.write.style.ContentStyle; import com.alibaba.excel.annotation.write.style.HeadFontStyle; import com.alibaba.excel.annotation.write.style.HeadStyle; +import com.alibaba.excel.enums.poi.FillPatternTypeEnum; import lombok.Data; @@ -19,20 +18,20 @@ import lombok.Data; **/ @Data // 头背景设置成红色 IndexedColors.RED.getIndex() -@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 10) +@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 10) // 头字体设置成20 @HeadFontStyle(fontHeightInPoints = 20) // 内容的背景设置成绿色 IndexedColors.GREEN.getIndex() -@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 17) +@ContentStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 17) // 内容字体设置成20 @ContentFontStyle(fontHeightInPoints = 20) public class DemoStyleData { // 字符串的头背景设置成粉红 IndexedColors.PINK.getIndex() - @HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 14) + @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 14) // 字符串的头字体设置成20 @HeadFontStyle(fontHeightInPoints = 30) // 字符串的内容的背景设置成天蓝 IndexedColors.SKY_BLUE.getIndex() - @ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 40) + @ContentStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 40) // 字符串的内容字体设置成20 @ContentFontStyle(fontHeightInPoints = 30) @ExcelProperty("字符串标题") diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java b/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java index 852bc280..251af588 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java @@ -27,7 +27,10 @@ import com.alibaba.excel.metadata.data.ImageData; import com.alibaba.excel.metadata.data.ImageData.ImageType; import com.alibaba.excel.metadata.data.RichTextStringData; import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.util.BooleanUtils; import com.alibaba.excel.util.FileUtils; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.handler.context.CellWriteHandlerContext; import com.alibaba.excel.write.merge.LoopMergeStrategy; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteTable; @@ -36,8 +39,11 @@ import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.streaming.SXSSFSheet; import org.junit.Ignore; import org.junit.Test; @@ -110,7 +116,7 @@ public class WriteTest { // 这里需要注意 在使用ExcelProperty注解的使用,如果想不空列则需要加入order字段,而不是index,order会忽略空列,然后继续往后,而index,不会忽略空列,在第几列就是第几列。 // 根据用户传入字段 假设我们要忽略 date - Set excludeColumnFiledNames = new HashSet(); + Set excludeColumnFiledNames = new HashSet<>(); excludeColumnFiledNames.add("date"); // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 EasyExcel.write(fileName, DemoData.class).excludeColumnFiledNames(excludeColumnFiledNames).sheet("模板") @@ -118,7 +124,7 @@ public class WriteTest { fileName = TestFileUtil.getPath() + "excludeOrIncludeWrite" + System.currentTimeMillis() + ".xlsx"; // 根据用户传入字段 假设我们只要导出 date - Set includeColumnFiledNames = new HashSet(); + Set includeColumnFiledNames = new HashSet<>(); includeColumnFiledNames.add("date"); // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 EasyExcel.write(fileName, DemoData.class).includeColumnFiledNames(includeColumnFiledNames).sheet("模板") @@ -337,7 +343,7 @@ public class WriteTest { * 2. 直接写即可 */ @Test - public void writeCellDataWrite() throws Exception { + public void writeCellDataWrite() { String fileName = TestFileUtil.getPath() + "writeCellDataWrite" + System.currentTimeMillis() + ".xlsx"; WriteCellDemoData writeCellDemoData = new WriteCellDemoData(); @@ -446,6 +452,9 @@ public class WriteTest { */ @Test public void handlerStyleWrite() { + // 方法1 使用已有的策略 推荐 + // HorizontalCellStyleStrategy 每一行的样式都一样 或者隔行一样 + // AbstractVerticalCellStyleStrategy 每一列的样式都一样 需要自己回调每一页 String fileName = TestFileUtil.getPath() + "handlerStyleWrite" + System.currentTimeMillis() + ".xlsx"; // 头的策略 WriteCellStyle headWriteCellStyle = new WriteCellStyle(); @@ -469,7 +478,70 @@ public class WriteTest { new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle); // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 - EasyExcel.write(fileName, DemoData.class).registerWriteHandler(horizontalCellStyleStrategy).sheet("模板") + EasyExcel.write(fileName, DemoData.class) + .registerWriteHandler(horizontalCellStyleStrategy) + .sheet("模板") + .doWrite(data()); + + // 方法2: 使用easyexcel的方式完全自己写 不太推荐 尽量使用已有策略 + // @since 3.0.0-beta2 + fileName = TestFileUtil.getPath() + "handlerStyleWrite" + System.currentTimeMillis() + ".xlsx"; + EasyExcel.write(fileName, DemoData.class) + .registerWriteHandler(new CellWriteHandler() { + @Override + public void afterCellDispose(CellWriteHandlerContext context) { + // 当前事件会在 数据设置到poi的cell里面才会回调 + // 判断不是头的情况 如果是fill 的情况 这里会==null 所以用not true + if (BooleanUtils.isNotTrue(context.getHead())) { + // 第一个单元格 + // 只要不是头 一定会有数据 当然fill的情况 可能要context.getCellDataList() ,这个需要看模板,因为一个单元格会有多个 WriteCellData + WriteCellData cellData = context.getFirstCellData(); + // 这里需要去cellData 获取样式 + // 很重要的一个原因是 WriteCellStyle 和 dataFormatData绑定的 简单的说 比如你加了 DateTimeFormat + // ,已经将writeCellStyle里面的dataFormatData 改了 如果你自己new了一个WriteCellStyle,可能注解的样式就失效了 + // 然后 getOrCreateStyle 用于返回一个样式,如果为空,则创建一个后返回 + WriteCellStyle writeCellStyle = cellData.getOrCreateStyle(); + writeCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex()); + // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND + writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND); + + // 这样样式就设置好了 后面有个FillStyleCellWriteHandler 默认会将 WriteCellStyle 设置到 cell里面去 所以可以不用管了 + } + } + }).sheet("模板") + .doWrite(data()); + + // 方法3: 使用poi的样式完全自己写 不推荐 + // @since 3.0.0-beta2 + // 坑1:style里面有dataformat 用来格式化数据的 所以自己设置可能导致格式化注解不生效 + // 坑2:不要一直去创建style 记得缓存起来 最多创建6W个就挂了 + fileName = TestFileUtil.getPath() + "handlerStyleWrite" + System.currentTimeMillis() + ".xlsx"; + EasyExcel.write(fileName, DemoData.class) + .registerWriteHandler(new CellWriteHandler() { + @Override + public void afterCellDispose(CellWriteHandlerContext context) { + // 当前事件会在 数据设置到poi的cell里面才会回调 + // 判断不是头的情况 如果是fill 的情况 这里会==null 所以用not true + if (BooleanUtils.isNotTrue(context.getHead())) { + Cell cell = context.getCell(); + // 拿到poi的workbook + Workbook workbook = context.getWriteWorkbookHolder().getWorkbook(); + // 这里千万记住 想办法能复用的地方把他缓存起来 一个表格最多创建6W个样式 + // 不同单元格尽量传同一个 cellStyle + CellStyle cellStyle = workbook.createCellStyle(); + cellStyle.setFillForegroundColor(IndexedColors.RED.getIndex()); + // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND + cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + cell.setCellStyle(cellStyle); + + // 由于这里没有指定dataformat 最后展示的数据 格式可能会不太正确 + + // 这里要把 WriteCellData的样式清空, 不然后面还有一个拦截器 FillStyleCellWriteHandler 默认会将 WriteCellStyle 设置到 + // cell里面去 会导致自己设置的不一样 + context.getFirstCellData().setWriteCellStyle(null); + } + } + }).sheet("模板") .doWrite(data()); } @@ -642,7 +714,7 @@ public class WriteTest { } private List dataLong() { - List list = new ArrayList(); + List list = new ArrayList<>(); for (int i = 0; i < 10; i++) { LongestMatchColumnWidthData data = new LongestMatchColumnWidthData(); data.setString("测试很长的字符串测试很长的字符串测试很长的字符串" + i); @@ -654,12 +726,12 @@ public class WriteTest { } private List> variableTitleHead() { - List> list = new ArrayList>(); - List head0 = new ArrayList(); + List> list = new ArrayList<>(); + List head0 = new ArrayList<>(); head0.add("string" + System.currentTimeMillis()); - List head1 = new ArrayList(); + List head1 = new ArrayList<>(); head1.add("number" + System.currentTimeMillis()); - List head2 = new ArrayList(); + List head2 = new ArrayList<>(); head2.add("date" + System.currentTimeMillis()); list.add(head0); list.add(head1); @@ -682,9 +754,9 @@ public class WriteTest { } private List> dataList() { - List> list = new ArrayList>(); + List> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { - List data = new ArrayList(); + List data = new ArrayList<>(); data.add("字符串" + i); data.add(new Date()); data.add(0.56); @@ -694,7 +766,7 @@ public class WriteTest { } private List data() { - List list = new ArrayList(); + List list = new ArrayList<>(); for (int i = 0; i < 10; i++) { DemoData data = new DemoData(); data.setString("字符串" + i); diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java b/src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java index f3f96810..4e258e51 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java @@ -1,22 +1,21 @@ package com.alibaba.easyexcel.test.temp; import java.util.ArrayList; -import java.util.Collections; import java.util.Date; import java.util.List; import com.alibaba.easyexcel.test.demo.write.DemoData; -import com.alibaba.easyexcel.test.demo.write.IndexData; -import com.alibaba.easyexcel.test.temp.data.DataType; -import com.alibaba.easyexcel.test.temp.data.HeadType; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; -import com.alibaba.excel.ExcelWriter; -import com.alibaba.excel.annotation.ExcelProperty; -import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy; -import com.alibaba.excel.write.metadata.WriteSheet; - -import lombok.Data; +import com.alibaba.excel.util.BooleanUtils; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.handler.context.CellWriteHandlerContext; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Workbook; import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; @@ -33,76 +32,102 @@ public class WriteV33Test { private static final Logger LOGGER = LoggerFactory.getLogger(WriteV33Test.class); @Test - public void test() throws Exception { - // 方法2 如果写到不同的sheet 同一个对象 - String fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx"; - OnceAbsoluteMergeStrategy onceAbsoluteMergeStrategy = new OnceAbsoluteMergeStrategy(2, 2, 0, 1); - - // 这里 指定文件 - ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).registerWriteHandler( - onceAbsoluteMergeStrategy).build(); - WriteSheet writeSheet1 = EasyExcel.writerSheet(1, "模板1").build(); - WriteSheet writeSheet2 = EasyExcel.writerSheet(2, "模板2").build(); - WriteSheet writeSheet3 = EasyExcel.writerSheet(3, "模板3").build(); - excelWriter.write(data(2), writeSheet2); - excelWriter.write(data(3), writeSheet3); - excelWriter.write(data(1), writeSheet1); - excelWriter.write(data(3), writeSheet3); - excelWriter.write(data(1), writeSheet1); - /// 千万别忘记finish 会帮忙关闭流 - excelWriter.finish(); + public void handlerStyleWrite() { + // 方法1 使用已有的策略 推荐 + // HorizontalCellStyleStrategy 每一行的样式都一样 或者隔行一样 + // AbstractVerticalCellStyleStrategy 每一列的样式都一样 需要自己回调每一页 + String fileName = TestFileUtil.getPath() + "handlerStyleWrite" + System.currentTimeMillis() + ".xlsx"; + //// 头的策略 + //WriteCellStyle headWriteCellStyle = new WriteCellStyle(); + //// 背景设置为红色 + //headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex()); + //WriteFont headWriteFont = new WriteFont(); + //headWriteFont.setFontHeightInPoints((short)20); + //headWriteCellStyle.setWriteFont(headWriteFont); + //// 内容的策略 + //WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); + //// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定 + //contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND); + //// 背景绿色 + //contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); + //WriteFont contentWriteFont = new WriteFont(); + //// 字体大小 + //contentWriteFont.setFontHeightInPoints((short)20); + //contentWriteCellStyle.setWriteFont(contentWriteFont); + //// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现 + //HorizontalCellStyleStrategy horizontalCellStyleStrategy = + // new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle); + // + //// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + //EasyExcel.write(fileName, DemoData.class) + // .registerWriteHandler(horizontalCellStyleStrategy) + // .sheet("模板") + // .doWrite(data()); + // + // 方法2: 使用easyexcel的方式完全自己写 不太推荐 尽量使用已有策略 + //fileName = TestFileUtil.getPath() + "handlerStyleWrite" + System.currentTimeMillis() + ".xlsx"; + //EasyExcel.write(fileName, DemoData.class) + // .registerWriteHandler(new CellWriteHandler() { + // @Override + // public void afterCellDispose(CellWriteHandlerContext context) { + // // 当前事件会在 数据设置到poi的cell里面才会回调 + // // 判断不是头的情况 如果是fill 的情况 这里会==null 所以用not true + // if (BooleanUtils.isNotTrue(context.getHead())) { + // // 第一个单元格 + // // 只要不是头 一定会有数据 当然fill的情况 可能要context.getCellDataList() ,这个需要看模板,因为一个单元格会有多个 WriteCellData + // WriteCellData cellData = context.getFirstCellData(); + // // 这里需要去cellData 获取样式 + // // 很重要的一个原因是 WriteCellStyle 和 dataFormatData绑定的 简单的说 比如你加了 DateTimeFormat + // // ,已经将writeCellStyle里面的dataFormatData 改了 如果你自己new了一个WriteCellStyle,可能注解的样式就失效了 + // // 然后 getOrCreateStyle 用于返回一个样式,如果为空,则创建一个后返回 + // WriteCellStyle writeCellStyle = cellData.getOrCreateStyle(); + // writeCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex()); + // // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND + // writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND); + // + // // 这样样式就设置好了 后面有个FillStyleCellWriteHandler 默认会将 WriteCellStyle 设置到 cell里面去 所以可以不用管了 + // } + // } + // }).sheet("模板") + // .doWrite(data()); + + // 方法3: 使用poi的样式完全自己写 不推荐 + // 坑1:style里面有dataformat 用来格式化数据的 所以自己设置可能导致格式化注解不生效 + // 坑2:不要一直去创建style 记得缓存起来 最多创建6W个就挂了 + fileName = TestFileUtil.getPath() + "handlerStyleWrite" + System.currentTimeMillis() + ".xlsx"; + EasyExcel.write(fileName, DemoData.class) + .registerWriteHandler(new CellWriteHandler() { + @Override + public void afterCellDispose(CellWriteHandlerContext context) { + // 当前事件会在 数据设置到poi的cell里面才会回调 + // 判断不是头的情况 如果是fill 的情况 这里会==null 所以用not true + if (BooleanUtils.isNotTrue(context.getHead())) { + Cell cell = context.getCell(); + // 拿到poi的workbook + Workbook workbook = context.getWriteWorkbookHolder().getWorkbook(); + // 这里千万记住 想办法能复用的地方把他缓存起来 一个表格最多创建6W个样式 + // 不同单元格尽量传同一个 cellStyle + CellStyle cellStyle = workbook.createCellStyle(); + cellStyle.setFillForegroundColor(IndexedColors.RED.getIndex()); + // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND + cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + cell.setCellStyle(cellStyle); + + // 由于这里没有指定datafrmat 所以格式化出来的数据需要 + + // 这里要把 WriteCellData的样式清空, 不然后面还有一个拦截器 FillStyleCellWriteHandler 默认会将 WriteCellStyle 设置到 + // cell里面去 会导致自己设置的不一样 + context.getFirstCellData().setWriteCellStyle(null); + } + } + }).sheet("模板") + .doWrite(data()); } - private List data(int no) { - List list = new ArrayList(); + private List data() { + List list = new ArrayList<>(); for (int i = 0; i < 10; i++) { DemoData data = new DemoData(); - data.setString("字符串" + no + "---" + i); - list.add(data); - } - return list; - } - - @Test - public void test33() throws Exception { - List data = getData(); - String fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx"; - - ExcelWriter excelWriter = null; - excelWriter = EasyExcel.write(fileName).build(); - WriteSheet writeSheet = EasyExcel.writerSheet(1, "test") - .head(HeadType.class) - .build(); - excelWriter.write(data, writeSheet); - excelWriter.finish(); - } - - private List getData() { - DataType vo = new DataType(); - vo.setId(738); - vo.setFirstRemark("1222"); - vo.setSecRemark("22222"); - return Collections.singletonList(vo); - } - - @Test - public void indexWrite() { - String fileName = TestFileUtil.getPath() + "indexWrite" + System.currentTimeMillis() + ".xlsx"; - - Man man = new Man(); - man.setAddr("武汉"); - man.setName("张三"); - ExcelWriter excelWriter = EasyExcel.write(fileName, Humen.class).build(); - WriteSheet writeSheet = EasyExcel.writerSheet("test").build(); - excelWriter.write(Collections.singletonList(man), writeSheet); - // 千万别忘记finish 会帮忙关闭流 - excelWriter.finish(); - } - - private List indexData() { - List list = new ArrayList(); - for (int i = 0; i < 10; i++) { - IndexData data = new IndexData(); data.setString("字符串" + i); data.setDate(new Date()); data.setDoubleData(0.56); @@ -111,17 +136,4 @@ public class WriteV33Test { return list; } - @Data - static class Humen{ - @ExcelProperty("名字") - private String name; - } - - @Data - static - class Man extends Humen{ - @ExcelProperty("地址") - private String addr; - } - } diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/simple/DemoData1.java b/src/test/java/com/alibaba/easyexcel/test/temp/simple/DemoData1.java index 40b454ec..8de542d1 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/simple/DemoData1.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/simple/DemoData1.java @@ -2,18 +2,17 @@ package com.alibaba.easyexcel.test.temp.simple; import java.util.Date; -import org.apache.poi.ss.usermodel.FillPatternType; - import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.HeadStyle; +import com.alibaba.excel.enums.poi.FillPatternTypeEnum; import lombok.Data; @Data public class DemoData1 { @ExcelProperty("字符串标题") - @HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 42) + @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 42) private String string; @ExcelProperty("日期标题") private Date date; diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/simple/DemoData2.java b/src/test/java/com/alibaba/easyexcel/test/temp/simple/DemoData2.java index a57af8f7..00d99041 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/simple/DemoData2.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/simple/DemoData2.java @@ -2,18 +2,17 @@ package com.alibaba.easyexcel.test.temp.simple; import java.util.Date; -import org.apache.poi.ss.usermodel.FillPatternType; - import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.HeadStyle; +import com.alibaba.excel.enums.poi.FillPatternTypeEnum; import lombok.Data; @Data public class DemoData2 { @ExcelProperty("字符串标题") - @HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 42) + @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 42) private String string; @ExcelProperty("日期标题") private Date date; diff --git a/update.md b/update.md index 4ced0a04..60ce63c5 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,7 @@ +# 3.0.0-beta2 + +* 优化写入样式的 + # 3.0.0-beta1 * 升级jdk8 不再支持jdk6 jdk7 @@ -33,6 +37,7 @@ * 新增部分jdk8特性 # 2.2.11 + * 修复有些xlsx解析失败的bug [Issue #1595](https://github.com/alibaba/easyexcel/issues/1595) # 2.2.10