Repository: wangguanquan/eec
Pull request #336 (2023-02-24 10:07:38)

Cancel default zebra-line fill
#300


Patch:
diff --git a/src/main/java/org/ttzero/excel/entity/ICellValueAndStyle.java b/src/main/java/org/ttzero/excel/entity/ICellValueAndStyle.java
index d16e6eb3..8476e127 100644
--- a/src/main/java/org/ttzero/excel/entity/ICellValueAndStyle.java
+++ b/src/main/java/org/ttzero/excel/entity/ICellValueAndStyle.java
@@ -51,6 +51,41 @@ public interface ICellValueAndStyle {
      * @param e    the cell value
      * @param hc   the header column
      */
+    default void reset(Row row, Cell cell, Object e, Column hc) {
+        setCellValue(row.index, cell, e, hc, hc.getClazz(), hc.processor != null);
+        // Cell style
+        if (hc.processor == null) {
+            cell.xf = getStyleIndex(row, hc, e);
+        }
+        // Reset row height
+    }
+
+    /**
+     * Returns the cell style index
+     *
+     * @param row the row data
+     * @param hc    the header column
+     * @param o     the cell value
+     * @return the style index in xf
+     */
+    default int getStyleIndex(Row row, Column hc, Object o) {
+        int style = hc.getCellStyle();
+        if (hc.styleProcessor != null) {
+            style = hc.styleProcessor.build(o, style, hc.styles);
+        }
+        return hc.styles.of(style);
+    }
+
+    /**
+     * Setting cell value and cell styles
+     *
+     * @param row  the row number
+     * @param cell the cell
+     * @param e    the cell value
+     * @param hc   the header column
+     * @deprecated Replace with {@link #reset(Row, Cell, Object, Column)}
+     */
+    @Deprecated
     void reset(int row, Cell cell, Object e, Column hc);
 
     /**
@@ -67,7 +102,9 @@ public interface ICellValueAndStyle {
      * @param hc the header column
      * @param o  the cell value
      * @return the style index in xf
+     * @deprecated Replace with {@link #getStyleIndex(Row, Column, Object)}
      */
+    @Deprecated
     int getStyleIndex(int rows, Column hc, Object o);
 
     /**
@@ -79,7 +116,11 @@ public interface ICellValueAndStyle {
      * @param hc the header column
      * @param styleProcessor a customize {@link StyleProcessor}
      */
-    <T> void setStyleDesign(T o, Cell cell, Column hc, StyleProcessor<T> styleProcessor);
+    default <T> void setStyleDesign(T o, Cell cell, Column hc, StyleProcessor<T> styleProcessor) {
+        if (styleProcessor != null && hc.styles != null) {
+            cell.xf = hc.styles.of(styleProcessor.build(o, hc.styles.getStyleByIndex(cell.xf), hc.styles));
+        }
+    }
 
     /**
      * Setting cell value
@@ -135,7 +176,7 @@ public interface ICellValueAndStyle {
         } else if (isLocalTime(clazz)) {
             cell.setTv(DateUtil.toTimeValue((java.time.LocalTime) e));
         } else {
-            cell.setSv(e.toString());
+            unknownType(row, cell, e, hc, clazz);
         }
     }
 
@@ -147,8 +188,8 @@ public interface ICellValueAndStyle {
      * @param hc    the header column
      */
     default void setNullValue(int row, Cell cell, Column hc) {
-        boolean hasIntProcessor = hc.processor != null;
-        if (hasIntProcessor) {
+        boolean hasProcessor = hc.processor != null;
+        if (hasProcessor) {
             conversion(row, cell, 0, hc);
         } else
             cell.blank();
@@ -181,4 +222,17 @@ public interface ICellValueAndStyle {
             cell.blank();
         }
     }
+
+    /**
+     * unknown cell type converter
+     *
+     * @param row the row number
+     * @param cell  the cell
+     * @param e     the cell value
+     * @param hc    the header column
+     * @param clazz the cell value type
+     */
+    default void unknownType(int row, Cell cell, Object e, Column hc, Class<?> clazz) {
+        cell.setSv(e.toString());
+    }
 }
diff --git a/src/main/java/org/ttzero/excel/entity/ListMapSheet.java b/src/main/java/org/ttzero/excel/entity/ListMapSheet.java
index 644ba941..6b8f8ac1 100644
--- a/src/main/java/org/ttzero/excel/entity/ListMapSheet.java
+++ b/src/main/java/org/ttzero/excel/entity/ListMapSheet.java
@@ -175,7 +175,7 @@ public class ListMapSheet extends ListSheet<Map<String, ?>> {
                 Cell cell = cells[i];
                 cell.clear();
 
-                cellValueAndStyle.reset(rows, cell, e, hc);
+                cellValueAndStyle.reset(row, cell, e, hc);
                 if (hasGlobalStyleProcessor) {
                     cellValueAndStyle.setStyleDesign(rowDate, cell, hc, getStyleProcessor());
                 }
diff --git a/src/main/java/org/ttzero/excel/entity/ListSheet.java b/src/main/java/org/ttzero/excel/entity/ListSheet.java
index 16577e17..35961294 100644
--- a/src/main/java/org/ttzero/excel/entity/ListSheet.java
+++ b/src/main/java/org/ttzero/excel/entity/ListSheet.java
@@ -321,7 +321,7 @@ public class ListSheet<T> extends Sheet {
                      */
                     else e = null;
 
-                    cellValueAndStyle.reset(rows, cell, e, column);
+                    cellValueAndStyle.reset(row, cell, e, column);
                     if (hasGlobalStyleProcessor) {
                         cellValueAndStyle.setStyleDesign(o, cell, column, getStyleProcessor());
                     }
diff --git a/src/main/java/org/ttzero/excel/entity/ResultSetSheet.java b/src/main/java/org/ttzero/excel/entity/ResultSetSheet.java
index ebf33e8d..914faea2 100644
--- a/src/main/java/org/ttzero/excel/entity/ResultSetSheet.java
+++ b/src/main/java/org/ttzero/excel/entity/ResultSetSheet.java
@@ -271,7 +271,7 @@ public class ResultSetSheet extends Sheet {
                         }
                     } else e = null;
 
-                    cellValueAndStyle.reset(rows, cell, e, hc);
+                    cellValueAndStyle.reset(row, cell, e, hc);
                     if (hasGlobalStyleProcessor) {
                         cellValueAndStyle.setStyleDesign(rs , cell, hc, getStyleProcessor());
                     }
diff --git a/src/main/java/org/ttzero/excel/entity/Sheet.java b/src/main/java/org/ttzero/excel/entity/Sheet.java
index fb739024..73711e93 100644
--- a/src/main/java/org/ttzero/excel/entity/Sheet.java
+++ b/src/main/java/org/ttzero/excel/entity/Sheet.java
@@ -27,6 +27,7 @@ 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.NumFmt;
+import org.ttzero.excel.entity.style.PatternType;
 import org.ttzero.excel.entity.style.Styles;
 import org.ttzero.excel.entity.style.Verticals;
 import org.ttzero.excel.manager.Const;
@@ -132,11 +133,21 @@ public abstract class Sheet implements Cloneable, Storable {
     /**
      * Automatic interlacing color
      */
+    @Deprecated
     protected int autoOdd = -1;
     /**
      * Odd row's background color
      */
+    @Deprecated
     protected int oddFill;
+    /**
+     * The zebra-line fill style value
+     */
+    protected int zebraFillStyle = -1;
+    /**
+     * The zebra-line fill style
+     */
+    protected Fill zebraFill;
     /**
      * A copy worksheet flag
      */
@@ -226,6 +237,10 @@ public abstract class Sheet implements Cloneable, Storable {
         return this;
     }
 
+    public ICellValueAndStyle getCellValueAndStyle() {
+        return cellValueAndStyle;
+    }
+
     public Sheet() {
         relManager = new RelManager();
     }
@@ -483,19 +498,22 @@ public abstract class Sheet implements Cloneable, Storable {
      * Cancel the odd row's fill style
      *
      * @return current {@link Sheet}
+     * @deprecated rename to {@link #cancelZebraLine()}
      */
+    @Deprecated
     public Sheet cancelOddStyle() {
-        this.autoOdd = 1;
-        return this;
+        return cancelZebraLine();
     }
 
     /**
      * Returns auto setting odd background flag
      *
      * @return 1: auto setting, others none
+     * @deprecated replace with {@code getZebraFill() != null}
      */
+    @Deprecated
     public int getAutoOdd() {
-        return autoOdd;
+        return zebraFill != null ? 1 : 0;
     }
 
     /**
@@ -503,9 +521,13 @@ public abstract class Sheet implements Cloneable, Storable {
      *
      * @param autoOdd 1: setting, others none
      * @return current {@link Sheet}
+     * @deprecated will be delete
      */
+    @Deprecated
     public Sheet setAutoOdd(int autoOdd) {
-        this.autoOdd = autoOdd;
+        if (autoOdd == 1) {
+            if (zebraFill == null) setZebraLine(new Fill(PatternType.solid, new Color(239, 245, 235)));
+        } else setZebraLine(null);
         return this;
     }
 
@@ -514,19 +536,74 @@ public abstract class Sheet implements Cloneable, Storable {
      *
      * @param fill the fill style
      * @return current {@link Sheet}
+     * @deprecated rename to {@link #setZebraLine(Fill)}
      */
+    @Deprecated
     public Sheet setOddFill(Fill fill) {
-        this.oddFill = workbook.getStyles().addFill(fill);
-        return this;
+        return setZebraLine(fill);
     }
 
     /**
      * Returns the odd columns fill style
      *
      * @return the fill style value
+     * @deprecated replace with {@link #getZebraFillStyle()}
      */
+    @Deprecated
     public int getOddFill() {
-        return oddFill;
+        return getZebraFillStyle();
+    }
+
+    /**
+     * Setting the zebra-line fill style, default fill color is #EFF5EB
+     *
+     * @param fill the zebra-line {@link Fill} style
+     * @return current {@link Workbook}
+     */
+    public Sheet setZebraLine(Fill fill) {
+        this.zebraFill = fill;
+        return this;
+    }
+
+    /**
+     * Cancel the zebra-line style
+     *
+     * @return current {@link Sheet}
+     */
+    public Sheet cancelZebraLine() {
+        this.zebraFill = null;
+        this.zebraFillStyle = 0;
+        return this;
+    }
+
+    /**
+     * Returns the zebra-line fill style
+     *
+     * @return the zebra-line {@link Fill} style
+     */
+    public Fill getZebraFill() {
+        return zebraFill;
+    }
+
+    /**
+     * Returns the zebra-line fill style value
+     *
+     * @return the zebra-line {@link Fill} style
+     */
+    public int getZebraFillStyle() {
+        if (zebraFillStyle < 0 && zebraFill != null) {
+            this.zebraFillStyle = workbook.getStyles().addFill(zebraFill);
+        }
+        return zebraFillStyle;
+    }
+
+    /**
+     * Setting zebra-line style, the default fill color is #EFF5EB
+     *
+     * @return current {@link Sheet}
+     */
+    public Sheet defaultZebraLine() {
+        return setZebraLine(new Fill(PatternType.solid, new Color(239, 245, 235)));
     }
 
     /**
@@ -1544,7 +1621,7 @@ public abstract class Sheet implements Cloneable, Storable {
      * Each row-block is multiplexed and will be called to reset
      * the data when a row-block is completely written.
      * Call the {@link #getRowBlockSize()} method to get
-     * the row-block size, call the {@link ICellValueAndStyle#reset(int, Cell, Object, org.ttzero.excel.entity.Column)}
+     * the row-block size, call the {@link ICellValueAndStyle#reset(Row, Cell, Object, org.ttzero.excel.entity.Column)}
      * method to set value and styles.
      */
     protected abstract void resetBlockData();
diff --git a/src/main/java/org/ttzero/excel/entity/Workbook.java b/src/main/java/org/ttzero/excel/entity/Workbook.java
index 07144bbc..9e60f805 100644
--- a/src/main/java/org/ttzero/excel/entity/Workbook.java
+++ b/src/main/java/org/ttzero/excel/entity/Workbook.java
@@ -21,6 +21,7 @@ import org.slf4j.LoggerFactory;
 import org.ttzero.excel.entity.csv.CSVWorkbookWriter;
 import org.ttzero.excel.entity.e7.XMLWorkbookWriter;
 import org.ttzero.excel.entity.style.Fill;
+import org.ttzero.excel.entity.style.PatternType;
 import org.ttzero.excel.entity.style.Styles;
 import org.ttzero.excel.manager.docProps.Core;
 import org.ttzero.excel.processor.ParamProcessor;
@@ -29,6 +30,7 @@ import org.ttzero.excel.util.FileUtil;
 import org.ttzero.excel.util.StringUtil;
 
 import javax.naming.OperationNotSupportedException;
+import java.awt.Color;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -99,10 +101,6 @@ public class Workbook implements Storable {
      * Auto size flag
      */
     private boolean autoSize;
-    /**
-     * Automatic interlacing fill, default fill color is '#E2EDDA'
-     */
-    private int autoOdd = 0;
     /**
      * Author
      */
@@ -113,9 +111,9 @@ public class Workbook implements Storable {
      */
     private String company;
     /**
-     * The fill
+     * The zebra-line fill style
      */
-    private Fill oddFill;
+    private Fill zebraFill;
     /**
      * A windows to debug
      */
@@ -191,9 +189,11 @@ public class Workbook implements Storable {
      * Returns the autoOdd setting
      *
      * @return 1 if odd-fill
+     * @deprecated replace with {@code getZebraFill() != null}
      */
+    @Deprecated
     public int getAutoOdd() {
-        return autoOdd;
+        return hasZebraFill() ? 1 : 0;
     }
 
     /**
@@ -218,9 +218,11 @@ public class Workbook implements Storable {
      * Returns the odd-fill style
      *
      * @return the {@link Fill} style
+     * @deprecated rename to {@link #getZebraFill()}
      */
+    @Deprecated
     public Fill getOddFill() {
-        return oddFill;
+        return getZebraFill();
     }
 
     /**
@@ -416,10 +418,11 @@ public class Workbook implements Storable {
      * Cancel the odd-fill style
      *
      * @return the {@link Workbook}
+     * @deprecated rename to {@link #cancelZebraLine()}
      */
+    @Deprecated
     public Workbook cancelOddFill() {
-        this.autoOdd = 1;
-        return this;
+        return cancelZebraLine();
     }
 
     /**
@@ -427,12 +430,61 @@ public class Workbook implements Storable {
      *
      * @param fill the {@link Fill} style
      * @return the {@link Workbook}
+     * @deprecated rename to {@link #setZebraLine(Fill)}
      */
+    @Deprecated
     public Workbook setOddFill(Fill fill) {
-        this.oddFill = fill;
+        return setZebraLine(fill);
+    }
+
+    /**
+     * Setting the zebra-line fill style
+     *
+     * @param fill the zebra-line {@link Fill} style
+     * @return the {@link Workbook}
+     */
+    public Workbook setZebraLine(Fill fill) {
+        this.zebraFill = fill;
         return this;
     }
 
+    /**
+     * Cancel the zebra-line style
+     *
+     * @return the {@link Workbook}
+     */
+    public Workbook cancelZebraLine() {
+        this.zebraFill = null;
+        return this;
+    }
+
+    /**
+     * Setting zebra-line style, the default fill color is #EFF5EB
+     *
+     * @return the {@link Workbook}
+     */
+    public Workbook defaultZebraLine() {
+        return setZebraLine(new Fill(PatternType.solid, new Color(239, 245, 235)));
+    }
+
+    /**
+     * Returns the zebra-line fill style
+     *
+     * @return the {@link Fill} style
+     */
+    public Fill getZebraFill() {
+        return zebraFill;
+    }
+
+    /**
+     * Returns current workbook has zebra-line
+     *
+     * @return true if zebra-line is not null
+     */
+    public boolean hasZebraFill() {
+        return zebraFill != null && zebraFill.getPatternType() != PatternType.none;
+    }
+
     /**
      * Returns the {@link IWorkbookWriter}
      *
diff --git a/src/main/java/org/ttzero/excel/entity/csv/CSVCellValueAndStyle.java b/src/main/java/org/ttzero/excel/entity/csv/CSVCellValueAndStyle.java
index 08926470..74dd1fab 100644
--- a/src/main/java/org/ttzero/excel/entity/csv/CSVCellValueAndStyle.java
+++ b/src/main/java/org/ttzero/excel/entity/csv/CSVCellValueAndStyle.java
@@ -18,6 +18,7 @@ package org.ttzero.excel.entity.csv;
 
 import org.ttzero.excel.entity.Column;
 import org.ttzero.excel.entity.ICellValueAndStyle;
+import org.ttzero.excel.entity.Row;
 import org.ttzero.excel.manager.Const;
 import org.ttzero.excel.processor.StyleProcessor;
 import org.ttzero.excel.reader.Cell;
@@ -54,6 +55,7 @@ public class CSVCellValueAndStyle implements ICellValueAndStyle {
      * @param e    the cell value
      * @param hc   the header column
      */
+    @Deprecated
     @Override
     public void reset(int row, Cell cell, Object e, Column hc) {
         setCellValue(row, cell, e, hc, hc.getClazz(), hc.processor != null);
@@ -138,11 +140,25 @@ public class CSVCellValueAndStyle implements ICellValueAndStyle {
     /**
      * Returns the cell style index
      *
+     * @param row the row data
      * @param hc the header column
      * @param o  the cell value
      * @return const zero (general style)
      */
     @Override
+    public int getStyleIndex(Row row, Column hc, Object o) {
+        return 0;
+    }
+
+    /**
+     * Returns the cell style index
+     *
+     * @param hc the header column
+     * @param o  the cell value
+     * @return const zero (general style)
+     */
+    @Deprecated
+    @Override
     public int getStyleIndex(int rows, Column hc, Object o) {
         return 0;
     }
diff --git a/src/main/java/org/ttzero/excel/entity/e7/XMLCellValueAndStyle.java b/src/main/java/org/ttzero/excel/entity/e7/XMLCellValueAndStyle.java
index 073fbdf2..fb2192bc 100644
--- a/src/main/java/org/ttzero/excel/entity/e7/XMLCellValueAndStyle.java
+++ b/src/main/java/org/ttzero/excel/entity/e7/XMLCellValueAndStyle.java
@@ -18,7 +18,6 @@ package org.ttzero.excel.entity.e7;
 
 import org.ttzero.excel.entity.Column;
 import org.ttzero.excel.entity.ICellValueAndStyle;
-import org.ttzero.excel.entity.style.Styles;
 import org.ttzero.excel.manager.Const;
 import org.ttzero.excel.processor.StyleProcessor;
 import org.ttzero.excel.reader.Cell;
@@ -31,19 +30,6 @@ import static org.ttzero.excel.entity.IWorksheetWriter.isShort;
  * @author guanquan.wang at 2019-09-25 11:25
  */
 public class XMLCellValueAndStyle implements ICellValueAndStyle {
-    /**
-     * Automatic interlacing color
-     */
-    private final int autoOdd;
-    /**
-     * Odd row's background color
-     */
-    private final int oddFill;
-
-    public XMLCellValueAndStyle(int autoOdd, int oddFill) {
-        this.autoOdd = autoOdd;
-        this.oddFill = oddFill;
-    }
 
     /**
      * Int value conversion to others
@@ -85,6 +71,7 @@ public class XMLCellValueAndStyle implements ICellValueAndStyle {
      * @param e    the cell value
      * @param hc   the header column
      */
+    @Deprecated
     @Override
     public void reset(int row, Cell cell, Object e, Column hc) {
         setCellValue(row, cell, e, hc, hc.getClazz(), hc.processor != null);
@@ -101,17 +88,12 @@ public class XMLCellValueAndStyle implements ICellValueAndStyle {
      * @param style the default style
      * @return the style index in xf
      */
-    private int getStyleIndex(int rows, Column hc, Object o, int style) {
-        // Interlaced discoloration
-        if (autoOdd == 0 && isOdd(rows) && !Styles.hasFill(style)) {
-            style |= oddFill;
-        }
-        int styleIndex = hc.styles.of(style);
+    @Deprecated
+    protected int getStyleIndex(int rows, Column hc, Object o, int style) {
         if (hc.styleProcessor != null) {
             style = hc.styleProcessor.build(o, style, hc.styles);
-            styleIndex = hc.styles.of(style);
         }
-        return styleIndex;
+        return hc.styles.of(style);
     }
 
     /**
@@ -121,37 +103,13 @@ public class XMLCellValueAndStyle implements ICellValueAndStyle {
      * @param o  the cell value
      * @return the style index in xf
      */
+    @Deprecated
     @Override
     public int getStyleIndex(int rows, Column hc, Object o) {
         int style = hc.getCellStyle();
         return getStyleIndex(rows, hc, o, style);
     }
 
-    /**
-     * Setting all cell style of the specified row
-     *
-     * @param <T> the row's class
-     * @param o the row data
-     * @param cell the cell of row
-     * @param hc the header column
-     * @param styleProcessor a customize {@link StyleProcessor}
-     */
-    @Override
-    public <T> void setStyleDesign(T o, Cell cell, Column hc, StyleProcessor<T> styleProcessor) {
-        if (styleProcessor != null && hc.styles != null) {
-            cell.xf = hc.styles.of(styleProcessor.build(o, hc.styles.getStyleByIndex(cell.xf), hc.styles));
-        }
-    }
-
-    /**
-     * Check the odd rows
-     *
-     * @return true if odd rows
-     */
-    private boolean isOdd(int rows) {
-        return (rows & 1) == 1;
-    }
-
     /**
      * Returns the worksheet name
      *
diff --git a/src/main/java/org/ttzero/excel/entity/e7/XMLWorkbookWriter.java b/src/main/java/org/ttzero/excel/entity/e7/XMLWorkbookWriter.java
index 38980164..535fb184 100644
--- a/src/main/java/org/ttzero/excel/entity/e7/XMLWorkbookWriter.java
+++ b/src/main/java/org/ttzero/excel/entity/e7/XMLWorkbookWriter.java
@@ -24,6 +24,7 @@ import org.dom4j.QName;
 import org.ttzero.excel.annotation.TopNS;
 import org.ttzero.excel.entity.Comments;
 import org.ttzero.excel.entity.ExcelWriteException;
+import org.ttzero.excel.entity.ICellValueAndStyle;
 import org.ttzero.excel.entity.IWorkbookWriter;
 import org.ttzero.excel.entity.IWorksheetWriter;
 import org.ttzero.excel.entity.Relationship;
@@ -31,8 +32,6 @@ import org.ttzero.excel.entity.SharedStrings;
 import org.ttzero.excel.entity.Sheet;
 import org.ttzero.excel.entity.WaterMark;
 import org.ttzero.excel.entity.Workbook;
-import org.ttzero.excel.entity.style.Fill;
-import org.ttzero.excel.entity.style.PatternType;
 import org.ttzero.excel.manager.Const;
 import org.ttzero.excel.manager.RelManager;
 import org.ttzero.excel.manager.docProps.App;
@@ -41,7 +40,6 @@ import org.ttzero.excel.util.FileUtil;
 import org.ttzero.excel.util.StringUtil;
 import org.ttzero.excel.util.ZipUtil;
 
-import java.awt.Color;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -377,13 +375,9 @@ public class XMLWorkbookWriter implements IWorkbookWriter {
                     sheet.fixSize();
                 }
             }
-            if (sheet.getAutoOdd() == -1) {
-                sheet.setAutoOdd(workbook.getAutoOdd());
-            }
-            // Interlace changes color as default
-            if (sheet.getAutoOdd() == 0) {
-                sheet.setOddFill(workbook.getOddFill() == null
-                    ? new Fill(PatternType.solid, new Color(239, 245, 235)) : workbook.getOddFill());
+
+            if (workbook.getZebraFill() != null && sheet.getZebraFillStyle() < 0) {
+                sheet.setZebraLine(workbook.getZebraFill());
             }
             sheet.setId(i + 1);
             // default worksheet name
@@ -391,7 +385,11 @@ public class XMLWorkbookWriter implements IWorkbookWriter {
                 sheet.setName("Sheet" + (i + 1));
             }
             // Set cell value and style processor
-            sheet.setCellValueAndStyle(new XMLCellValueAndStyle(sheet.getAutoOdd(), sheet.getOddFill()));
+            if (sheet.getCellValueAndStyle() == null) {
+                int zebraFillStyle = sheet.getZebraFillStyle();
+                ICellValueAndStyle cvas = zebraFillStyle > 0 ? new XMLZebraLineCellValueAndStyle(zebraFillStyle) : new XMLCellValueAndStyle();
+                sheet.setCellValueAndStyle(cvas);
+            }
 
             // Force export all fields
             if (workbook.getForceExport() > sheet.getForceExport()) {
diff --git a/src/main/java/org/ttzero/excel/entity/e7/XMLZebraLineCellValueAndStyle.java b/src/main/java/org/ttzero/excel/entity/e7/XMLZebraLineCellValueAndStyle.java
new file mode 100644
index 00000000..f5f42e67
--- /dev/null
+++ b/src/main/java/org/ttzero/excel/entity/e7/XMLZebraLineCellValueAndStyle.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017-2023, guanquan.wang@yandex.com All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.ttzero.excel.entity.e7;
+
+import org.ttzero.excel.entity.Column;
+import org.ttzero.excel.entity.Row;
+import org.ttzero.excel.entity.style.Fill;
+import org.ttzero.excel.entity.style.Styles;
+
+/**
+ * @author guanquan.wang at 2023-02-24 11:12
+ */
+public class XMLZebraLineCellValueAndStyle extends XMLCellValueAndStyle {
+
+    /**
+     * The zebra-line fill style value
+     */
+    protected int zebraFillStyle = -1;
+    /**
+     * The zebra-line fill style
+     */
+    protected Fill zebraFill;
+
+    public XMLZebraLineCellValueAndStyle(int zebraFillStyle) {
+        this.zebraFillStyle = zebraFillStyle;
+    }
+
+    public XMLZebraLineCellValueAndStyle(Fill zebraFill) {
+        this.zebraFill = zebraFill;
+    }
+
+    /**
+     * Returns the cell style index
+     *
+     * @param row   the row data
+     * @param hc    the header column
+     * @param o     the cell value
+     * @return the style index in xf
+     */
+    @Override
+    public int getStyleIndex(Row row, Column hc, Object o) {
+        if (zebraFillStyle == -1 && zebraFill != null)
+            zebraFillStyle = hc.styles.addFill(zebraFill);
+        // Default style
+        int style = hc.getCellStyle();
+        // Interlaced discoloration
+        if (isOdd(row.getIndex()) && !Styles.hasFill(style)) style |= zebraFillStyle;
+        // Dynamic style
+        if (hc.styleProcessor != null) {
+            style = hc.styleProcessor.build(o, style, hc.styles);
+        }
+        return hc.styles.of(style);
+    }
+
+
+    /**
+     * Check the odd rows
+     *
+     * @return true if odd rows
+     */
+    static boolean isOdd(int rows) {
+        return (rows & 1) == 1;
+    }
+
+}


Test patch:
diff --git a/src/test/java/org/ttzero/excel/entity/ListMapSheetTest.java b/src/test/java/org/ttzero/excel/entity/ListMapSheetTest.java
index 3a1596b7..aab00b03 100644
--- a/src/test/java/org/ttzero/excel/entity/ListMapSheetTest.java
+++ b/src/test/java/org/ttzero/excel/entity/ListMapSheetTest.java
@@ -38,6 +38,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
@@ -377,14 +378,14 @@ public class ListMapSheetTest extends WorkbookTest {
         list.add(0, null);
         list.add(3, null);
         list.add(null);
-        new Workbook("Null in list map").addSheet(new ListSheet<>(list)).writeTo(defaultTestPath);
+        new Workbook("Null in list map").addSheet(new ListMapSheet(list)).writeTo(defaultTestPath);
     }
 
     @Test public void testLargeColumns() throws IOException {
         int len = 1436;
         List<Map<String, ?>> list = new ArrayList<>(len);
         for (int i = 0; i < len; i++) {
-            Map<String, String> map = new HashMap<>();
+            Map<String, String> map = new LinkedHashMap<>();
             for (int j = 0; j < 500; j++) {
                 map.put("key" + j, getRandomString());
             }
diff --git a/src/test/java/org/ttzero/excel/entity/ResultSetPagingTest.java b/src/test/java/org/ttzero/excel/entity/ResultSetPagingTest.java
index b5f29372..49072966 100644
--- a/src/test/java/org/ttzero/excel/entity/ResultSetPagingTest.java
+++ b/src/test/java/org/ttzero/excel/entity/ResultSetPagingTest.java
@@ -21,7 +21,7 @@ import org.ttzero.excel.entity.style.Fill;
 import org.ttzero.excel.entity.style.PatternType;
 import org.ttzero.excel.entity.style.Styles;
 
-import java.awt.*;
+import java.awt.Color;
 import java.io.IOException;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
diff --git a/src/test/java/org/ttzero/excel/entity/ResultSetSheetTest.java b/src/test/java/org/ttzero/excel/entity/ResultSetSheetTest.java
index b80a9433..00710fd3 100644
--- a/src/test/java/org/ttzero/excel/entity/ResultSetSheetTest.java
+++ b/src/test/java/org/ttzero/excel/entity/ResultSetSheetTest.java
@@ -22,7 +22,7 @@ import org.ttzero.excel.entity.style.Fill;
 import org.ttzero.excel.entity.style.PatternType;
 import org.ttzero.excel.entity.style.Styles;
 
-import java.awt.*;
+import java.awt.Color;
 import java.io.IOException;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
diff --git a/src/test/java/org/ttzero/excel/entity/XMLCellValueAndStyleTest.java b/src/test/java/org/ttzero/excel/entity/XMLCellValueAndStyleTest.java
new file mode 100644
index 00000000..4de3b823
--- /dev/null
+++ b/src/test/java/org/ttzero/excel/entity/XMLCellValueAndStyleTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2017-2023, guanquan.wang@yandex.com All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.ttzero.excel.entity;
+
+import org.junit.Test;
+import org.ttzero.excel.entity.e7.XMLCellValueAndStyle;
+import org.ttzero.excel.entity.e7.XMLZebraLineCellValueAndStyle;
+import org.ttzero.excel.entity.style.Fill;
+import org.ttzero.excel.entity.style.PatternType;
+
+import java.awt.Color;
+import java.io.IOException;
+
+/**
+ * @author guanquan.wang at 2023-02-24 17:26
+ */
+public class XMLCellValueAndStyleTest extends WorkbookTest {
+    @Test public void testDefaultZebraLineWrite() throws IOException {
+        new Workbook("test default zebra-line")
+            .defaultZebraLine()
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData()))
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData()))
+            .writeTo(defaultTestPath);
+    }
+
+    @Test public void testCustomZebraLineWrite() throws IOException {
+        new Workbook("test orange zebra-line")
+            .setZebraLine(new Fill(PatternType.solid, Color.orange))
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData()))
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData()))
+            .writeTo(defaultTestPath);
+    }
+
+    @Test public void testCustomZebraLineCancelPartWrite() throws IOException {
+        new Workbook("test none origin zebra-line cancel part")
+            .setZebraLine(new Fill(PatternType.solid, Color.orange))
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData()).cancelZebraLine())
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData()))
+            .writeTo(defaultTestPath);
+    }
+
+    @Test public void testCustomZebraLineCancelAllWrite() throws IOException {
+        new Workbook("test none zebra-line cancel all")
+            .setZebraLine(new Fill(PatternType.solid, Color.orange))
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData()).cancelZebraLine())
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData()).cancelZebraLine())
+            .writeTo(defaultTestPath);
+    }
+
+    @Test public void testCustom2ZebraLineWrite() throws IOException {
+        new Workbook("test origin none zebra-line")
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData()).setZebraLine(new Fill(PatternType.solid, Color.orange)))
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData()))
+            .writeTo(defaultTestPath);
+    }
+
+    @Test public void testCustom3ZebraLineWrite() throws IOException {
+        new Workbook("test orange default zebra-line")
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData()).setZebraLine(new Fill(PatternType.solid, Color.orange)))
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData()).defaultZebraLine())
+            .writeTo(defaultTestPath);
+    }
+
+    @Test public void testCustom4ZebraLineWrite() throws IOException {
+        new Workbook("test cancel origin default zebra-line")
+            .cancelZebraLine()
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData()).setZebraLine(new Fill(PatternType.solid, Color.orange)))
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData()).defaultZebraLine())
+            .writeTo(defaultTestPath);
+    }
+
+    @Test public void testCustomCellValueAndStyleWrite() throws IOException {
+        new Workbook("test orange ZebraLineCellValueAndStyle")
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData())
+                .setCellValueAndStyle(new XMLZebraLineCellValueAndStyle(new Fill(PatternType.solid, Color.orange))))
+            .writeTo(defaultTestPath);
+    }
+
+    @Test public void testCustomCellValueAndStyle2Write() throws IOException {
+        new Workbook("test custom CellValueAndStyle")
+            .addSheet(new ListSheet<>(ListObjectSheetTest.Item.randomTestData()).setCellValueAndStyle(new XMLCellValueAndStyle()))
+            .writeTo(defaultTestPath);
+    }
+}