Repository: wangguanquan/eec
Pull request #181 (2021-05-18 14:52:46)

Feature/header style


Patch:
diff --git a/.travis.yml b/.travis.yml
index afd4c80d..1bd4cb98 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,3 @@
 language: java
 
-script: mvn clean test clean
\ No newline at end of file
+script: mvn clean package test clean
\ No newline at end of file
diff --git a/src/main/java/org/ttzero/excel/annotation/HeaderStyle.java b/src/main/java/org/ttzero/excel/annotation/HeaderStyle.java
index 8314c657..75724af5 100644
--- a/src/main/java/org/ttzero/excel/annotation/HeaderStyle.java
+++ b/src/main/java/org/ttzero/excel/annotation/HeaderStyle.java
@@ -28,8 +28,7 @@ import java.lang.annotation.Target;
 /**
  * Custom header styles
  *
- * @author jialei
- * @date 2021-05-10 17:38
+ * @author jialei2 at 021-05-10 17:38
  */
 @Target({ElementType.FIELD, ElementType.METHOD})
 @Retention(RetentionPolicy.RUNTIME)
@@ -39,15 +38,16 @@ public @interface HeaderStyle {
     /**
      * Set font color.
      *
+     * @return color
      */
-    String fontColor() default "#ffffff";
+    String fontColor() default "white";
 
     /**
-     * Set the background fill color.
+     * Set the foreground color.
      *
      * @see Fill#parse(java.lang.String)
-     *
+     * @return color
      */
-    String fillBgColor() default "#666699";
+    String fillFgColor() default "#666699";
 
 }
diff --git a/src/main/java/org/ttzero/excel/entity/ListSheet.java b/src/main/java/org/ttzero/excel/entity/ListSheet.java
index b5c56c3d..88e5f360 100644
--- a/src/main/java/org/ttzero/excel/entity/ListSheet.java
+++ b/src/main/java/org/ttzero/excel/entity/ListSheet.java
@@ -19,16 +19,9 @@ package org.ttzero.excel.entity;
 import org.ttzero.excel.annotation.ExcelColumn;
 import org.ttzero.excel.annotation.HeaderComment;
 import org.ttzero.excel.annotation.HeaderStyle;
-import org.ttzero.excel.entity.style.Border;
-import org.ttzero.excel.entity.style.Fill;
-import org.ttzero.excel.entity.style.Font;
-import org.ttzero.excel.entity.style.Horizontals;
-import org.ttzero.excel.entity.style.Styles;
-import org.ttzero.excel.entity.style.Verticals;
 import org.ttzero.excel.reader.Cell;
 import org.ttzero.excel.annotation.IgnoreExport;
 
-import java.awt.*;
 import java.beans.IntrospectionException;
 import java.beans.Introspector;
 import java.beans.PropertyDescriptor;
@@ -413,6 +406,11 @@ public class ListSheet<T> extends Sheet {
                             column.name = gs;
                         }
                         list.add(column);
+
+                        // Attach header style
+                        buildHeaderStyle(method, field, column);
+                        // Attach header comment
+                        buildHeaderComment(method, field, column);
                         continue;
                     }
                 }
@@ -432,6 +430,11 @@ public class ListSheet<T> extends Sheet {
                         column.clazz = method.getReturnType();
                         methods[i] = method;
                     } else column.clazz = field.getType();
+
+                    // Attach header style
+                    buildHeaderStyle(method, field, column);
+                    // Attach header comment
+                    buildHeaderComment(method, field, column);
                     continue;
                 }
 
@@ -466,6 +469,11 @@ public class ListSheet<T> extends Sheet {
                         if (isEmpty(column.name)) {
                             column.name = method.getName();
                         }
+
+                        // Attach header style
+                        buildHeaderStyle(method, null, column);
+                        // Attach header comment
+                        buildHeaderComment(method, null, column);
                     }
                 }
             }
@@ -479,8 +487,17 @@ public class ListSheet<T> extends Sheet {
             }
             columns = new Column[list.size()];
             list.toArray(columns);
+
+            // Merge Header Style
+            HeaderStyle headerStyle = clazz.getDeclaredAnnotation(HeaderStyle.class);
+            int style = 0;
+            if (headerStyle != null) {
+                style = buildHeadStyle(headerStyle.fontColor(), headerStyle.fillFgColor());
+            }
             for (i = 0; i < columns.length; i++) {
                 columns[i].styles = workbook.getStyles();
+                if (columns[i].headerStyle == 0)
+                    columns[i].headerStyle |= style;
             }
 
             // Clean
@@ -533,13 +550,8 @@ public class ListSheet<T> extends Sheet {
         ExcelColumn ec = ao.getAnnotation(ExcelColumn.class);
         if (ec != null) {
             Column column = new Column(ec.value(), EMPTY, ec.share());
-            // 解析自定义头样式
-            HeaderStyle hs = ao.getAnnotation(HeaderStyle.class);
-            if (hs != null) {
-                column.setHeaderStyle(this.buildHeadStyle(hs.fontColor(), hs.fillBgColor()));
-            }
             // Comment
-            column.headerComment = createComment(ao.getAnnotation(HeaderComment.class), ec.comment());
+//            column.headerComment = createComment(ao.getAnnotation(HeaderComment.class), ec.comment());
             // Number format
             if (isNotEmpty(ec.format())) {
                 column.setNumFmt(ec.format());
@@ -551,12 +563,38 @@ public class ListSheet<T> extends Sheet {
         return null;
     }
 
-    private Comment createComment(HeaderComment precedence, HeaderComment normal) {
-        HeaderComment comment = precedence != null ? precedence : normal;
+    private void buildHeaderStyle(AccessibleObject main, AccessibleObject sub, Column column) {
+        HeaderStyle hs = null;
+        if (main != null) {
+            hs = main.getAnnotation(HeaderStyle.class);
+        }
+        if (hs == null && sub != null) {
+            hs = sub.getAnnotation(HeaderStyle.class);
+        }
+        if (hs != null) {
+            column.setHeaderStyle(this.buildHeadStyle(hs.fontColor(), hs.fillFgColor()));
+        }
+    }
+
+    private void buildHeaderComment(AccessibleObject main, AccessibleObject sub, Column column) {
+        HeaderComment comment = null;
+        if (main != null) {
+            comment = main.getAnnotation(HeaderComment.class);
+            if (comment == null) {
+                ExcelColumn ec = main.getAnnotation(ExcelColumn.class);
+                if (ec != null) comment = ec.comment();
+            }
+        }
+        if (comment == null && sub != null) {
+            comment = sub.getAnnotation(HeaderComment.class);
+            if (comment == null) {
+                ExcelColumn ec = sub.getAnnotation(ExcelColumn.class);
+                if (ec != null) comment = ec.comment();
+            }
+        }
         if (comment != null && (isNotEmpty(comment.value()) || isNotEmpty(comment.title()))) {
-            return new Comment(comment.title(), comment.value());
+            column.headerComment = new Comment(comment.title(), comment.value());
         }
-        return null;
     }
 
     /**
diff --git a/src/main/java/org/ttzero/excel/entity/Sheet.java b/src/main/java/org/ttzero/excel/entity/Sheet.java
index 53f3e958..f642d945 100644
--- a/src/main/java/org/ttzero/excel/entity/Sheet.java
+++ b/src/main/java/org/ttzero/excel/entity/Sheet.java
@@ -472,7 +472,9 @@ public abstract class Sheet implements Cloneable, Storable {
          *
          * @param type the cell type
          * @return the {@link Sheet.Column}
+         * @deprecated Do not use
          */
+        @Deprecated
         public Column setType(int type) {
             this.type = type;
             return this;
@@ -1294,18 +1296,17 @@ public abstract class Sheet implements Cloneable, Storable {
     /**
      * Custom header style according to parameters
      *
-     * @param fontColor
-     * @param fillBgColor
+     * @param fontColor the font color
+     * @param fillBgColor the fill background color
      * @return headStyle
      */
     public int buildHeadStyle(String fontColor, String fillBgColor) {
         if (headStyle == 0) {
             Styles styles = workbook.getStyles();
             Font font = new Font(workbook.getI18N().getOrElse("local-font-family", "Arial")
-                    , 12, Font.Style.BOLD, Color.decode(fontColor));
+                    , 12, Font.Style.BOLD, Styles.toColor(fontColor));
             headStyle = styles.of(styles.addFont(font)
-                    | styles.addFill(Fill.parse(String.join(" ",
-                    fillBgColor, "solid")))
+                    | styles.addFill(Fill.parse(fillBgColor))
                     | styles.addBorder(Border.parse("thin black"))
                     | Verticals.CENTER
                     | Horizontals.CENTER);
diff --git a/src/main/java/org/ttzero/excel/entity/style/Fill.java b/src/main/java/org/ttzero/excel/entity/style/Fill.java
index 6ed5746c..5ba3836b 100644
--- a/src/main/java/org/ttzero/excel/entity/style/Fill.java
+++ b/src/main/java/org/ttzero/excel/entity/style/Fill.java
@@ -126,17 +126,7 @@ public class Fill implements Cloneable {
                     patternType = null;
                 }
                 if (patternType == null) {
-                    Color color;
-                    if (v.charAt(0) == '#') {
-                        color = Color.decode(v);
-                    } else {
-                        try {
-                            Field field = Color.class.getDeclaredField(v);
-                            color = (Color) field.get(null);
-                        } catch (NoSuchFieldException | IllegalAccessException e) {
-                            throw new ColorParseException("Color \"" + v + "\" not support.");
-                        }
-                    }
+                    Color color = Styles.toColor(v);
                     if (fill.fgColor == null) {
                         fill.fgColor = color;
                     } else {
@@ -147,9 +137,9 @@ public class Fill implements Cloneable {
                 }
             }
         }
-        if (fill.patternType == null) {
-            fill.patternType = PatternType.solid;
-        }
+//        if (fill.patternType == null) {
+//            fill.patternType = PatternType.solid;
+//        }
         return fill;
     }
 
diff --git a/src/main/java/org/ttzero/excel/entity/style/Font.java b/src/main/java/org/ttzero/excel/entity/style/Font.java
index 30892388..55f27c28 100644
--- a/src/main/java/org/ttzero/excel/entity/style/Font.java
+++ b/src/main/java/org/ttzero/excel/entity/style/Font.java
@@ -392,7 +392,7 @@ public class Font implements Cloneable {
         public static final int UNDERLINE = 1;
 
         public static int valueOf(String name) throws NoSuchFieldException, IllegalAccessException {
-            Field field = Style.class.getDeclaredField(name);
+            Field field = Style.class.getDeclaredField(name.toUpperCase());
             return field.getInt(null);
         }
     }
diff --git a/src/main/java/org/ttzero/excel/entity/style/Horizontals.java b/src/main/java/org/ttzero/excel/entity/style/Horizontals.java
index 5f2ae5a4..b5c8f6a9 100644
--- a/src/main/java/org/ttzero/excel/entity/style/Horizontals.java
+++ b/src/main/java/org/ttzero/excel/entity/style/Horizontals.java
@@ -23,13 +23,13 @@ public class Horizontals {
     // General Horizontal Alignment( Text data is left-aligned. Numbers
     // , dates, and times are right-aligned.Boolean types are centered)
     public static final int GENERAL = 0
-        , LEFT = 1 // Left Horizontal Alignment
-        , RIGHT = 2 // Right Horizontal Alignment
-        , CENTER = 3 // Centered Horizontal Alignment
-        , CENTER_CONTINUOUS = 4 // (Center Continuous Horizontal Alignment
-        , FILL = 5 // Fill
-        , JUSTIFY = 6 // Justify
-        , DISTRIBUTED = 7 // Distributed Horizontal Alignment
+        , LEFT = 1 << Styles.INDEX_HORIZONTAL // Left Horizontal Alignment
+        , RIGHT = 2 << Styles.INDEX_HORIZONTAL // Right Horizontal Alignment
+        , CENTER = 3 << Styles.INDEX_HORIZONTAL // Centered Horizontal Alignment
+        , CENTER_CONTINUOUS = 4 << Styles.INDEX_HORIZONTAL // (Center Continuous Horizontal Alignment
+        , FILL = 5 << Styles.INDEX_HORIZONTAL // Fill
+        , JUSTIFY = 6 << Styles.INDEX_HORIZONTAL // Justify
+        , DISTRIBUTED = 7 << Styles.INDEX_HORIZONTAL // Distributed Horizontal Alignment
         ;
 
     private static final String[] _names = {
diff --git a/src/main/java/org/ttzero/excel/entity/style/Styles.java b/src/main/java/org/ttzero/excel/entity/style/Styles.java
index 4343f83c..6e56cd76 100644
--- a/src/main/java/org/ttzero/excel/entity/style/Styles.java
+++ b/src/main/java/org/ttzero/excel/entity/style/Styles.java
@@ -31,6 +31,7 @@ import org.dom4j.io.SAXReader;
 import java.awt.Color;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.reflect.Field;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
@@ -830,4 +831,32 @@ public class Styles implements Storable {
         if (dateFmtCache == null) dateFmtCache = new HashSet<>();
         dateFmtCache.add(xf);
     }
+
+    /**
+     * Converts a <code>String</code> to an integer and returns the
+     * specified opaque <code>Color</code>. This method handles string
+     * formats that are used to represent octal and hexadecimal numbers.
+     *
+     * @param v hexadecimal numbers or color name
+     * @return the new <code>Color</code> object.
+     * @throws ColorParseException if convert failed.
+     */
+    public static Color toColor(String v) {
+        Color color;
+        if (v.charAt(0) == '#') {
+            try {
+                color = Color.decode(v);
+            } catch (NumberFormatException e) {
+                throw new ColorParseException("Color \"" + v + "\" not support.");
+            }
+        } else {
+            try {
+                Field field = Color.class.getDeclaredField(v);
+                color = (Color) field.get(null);
+            } catch (NoSuchFieldException | IllegalAccessException e) {
+                throw new ColorParseException("Color \"" + v + "\" not support.");
+            }
+        }
+        return color;
+    }
 }
diff --git a/src/main/java/org/ttzero/excel/reader/Drawings.java b/src/main/java/org/ttzero/excel/reader/Drawings.java
index ffbd8fb9..2079f1e9 100644
--- a/src/main/java/org/ttzero/excel/reader/Drawings.java
+++ b/src/main/java/org/ttzero/excel/reader/Drawings.java
@@ -39,6 +39,7 @@ public interface Drawings {
     /**
      * List all picture in specify worksheet
      *
+     * @param sheet Specifies witch {@code Worksheet} to get the picture from
      * @return list of {@link Picture}, or null if not exists.
      */
     default List<Picture> listPictures(final Sheet sheet) {


Test patch:
diff --git a/src/test/java/org/ttzero/excel/annotation/HeaderStyleTest.java b/src/test/java/org/ttzero/excel/annotation/HeaderStyleTest.java
index ba0c492a..a31930e3 100644
--- a/src/test/java/org/ttzero/excel/annotation/HeaderStyleTest.java
+++ b/src/test/java/org/ttzero/excel/annotation/HeaderStyleTest.java
@@ -34,7 +34,7 @@ public class HeaderStyleTest extends WorkbookTest {
 
     }
 
-    static class Head {
+    private static class Head {
 
         /**
          * errorMsg
@@ -44,18 +44,18 @@ public class HeaderStyleTest extends WorkbookTest {
 
     }
 
-    static class Head1 {
+    private static class Head1 {
 
         /**
          * errorMsg
          */
         @ExcelColumn(value = "错误信息")
-        @HeaderStyle(fillBgColor = "#ff0000")
+        @HeaderStyle(fillFgColor = "#ff0000")
         private String errorMsg;
 
     }
 
-    static class Head2 {
+    private static class Head2 {
 
         /**
          * errorMsg