diff --git a/src/main/java/com/alibaba/excel/ExcelReader.java b/src/main/java/com/alibaba/excel/ExcelReader.java
index cefe92fb..154233ce 100644
--- a/src/main/java/com/alibaba/excel/ExcelReader.java
+++ b/src/main/java/com/alibaba/excel/ExcelReader.java
@@ -8,7 +8,6 @@ import com.alibaba.excel.analysis.ExcelAnalyserImpl;
 import com.alibaba.excel.context.AnalysisContext;
 import com.alibaba.excel.converters.Converter;
 import com.alibaba.excel.event.AnalysisEventListener;
-import com.alibaba.excel.metadata.BaseRowModel;
 import com.alibaba.excel.metadata.Sheet;
 import com.alibaba.excel.parameter.AnalysisParam;
 import com.alibaba.excel.support.ExcelTypeEnum;
@@ -155,7 +154,7 @@ public class ExcelReader {
      * @param sheet Read sheet
      * @param clazz object parsed into each row of value
      */
-    public void read(Sheet sheet, Class<? extends BaseRowModel> clazz) {
+    public void read(Sheet sheet, Class clazz) {
         analyser.beforeAnalysis();
         if (sheet != null) {
             sheet.setClazz(clazz);
diff --git a/src/main/java/com/alibaba/excel/ExcelWriter.java b/src/main/java/com/alibaba/excel/ExcelWriter.java
index 0b508574..3a7edbf6 100644
--- a/src/main/java/com/alibaba/excel/ExcelWriter.java
+++ b/src/main/java/com/alibaba/excel/ExcelWriter.java
@@ -7,14 +7,15 @@ import java.util.List;
 import java.util.Map;
 
 import com.alibaba.excel.converters.Converter;
-import com.alibaba.excel.event.WriteHandler;
-import com.alibaba.excel.metadata.BaseRowModel;
 import com.alibaba.excel.metadata.Sheet;
 import com.alibaba.excel.metadata.Table;
+import com.alibaba.excel.metadata.Workbook;
+import com.alibaba.excel.parameter.GenerateParam;
 import com.alibaba.excel.support.ExcelTypeEnum;
 import com.alibaba.excel.write.ExcelBuilder;
 import com.alibaba.excel.write.ExcelBuilderImpl;
 import com.alibaba.excel.write.handler.WriteHandler;
+import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy;
 
 /**
  * Excel Writer This tool is used to write value out to Excel via POI. This object can perform the following two
@@ -46,8 +47,14 @@ public class ExcelWriter {
      */
     public ExcelWriter(InputStream templateInputStream, OutputStream outputStream, ExcelTypeEnum excelType,
         boolean needHead, Map<Class, Converter> customConverterMap, List<WriteHandler> customWriteHandlerList) {
-        excelBuilder = new ExcelBuilderImpl(templateInputStream, outputStream, excelType, needHead, customConverterMap,
-            customWriteHandlerList);
+        Workbook workbook = new Workbook();
+        workbook.setTemplateInputStream(templateInputStream);
+        workbook.setOutputStream(outputStream);
+        workbook.setExcelType(excelType);
+        workbook.setNeedHead(needHead);
+        workbook.setCustomConverterMap(customConverterMap);
+        workbook.setCustomWriteHandlerList(customWriteHandlerList);
+        excelBuilder = new ExcelBuilderImpl(workbook);
     }
 
     /**
@@ -118,8 +125,22 @@ public class ExcelWriter {
         Boolean needHead, WriteHandler writeHandler) {
         List<WriteHandler> customWriteHandlerList = new ArrayList<WriteHandler>();
         customWriteHandlerList.add(writeHandler);
-        excelBuilder =
-            new ExcelBuilderImpl(templateInputStream, outputStream, typeEnum, needHead, null, customWriteHandlerList);
+        Workbook workbook = new Workbook();
+        workbook.setTemplateInputStream(templateInputStream);
+        workbook.setOutputStream(outputStream);
+        workbook.setExcelType(typeEnum);
+        workbook.setNeedHead(needHead);
+        workbook.setCustomWriteHandlerList(customWriteHandlerList);
+        excelBuilder = new ExcelBuilderImpl(workbook);
+    }
+
+    /**
+     * @param generateParam
+     * @deprecated please use {@link com.alibaba.excel.write.builder.ExcelWriterBuilder} build ExcelWriter
+     */
+    @Deprecated
+    public ExcelWriter(GenerateParam generateParam) {
+        this(generateParam.getOutputStream(), generateParam.getType(), true);
     }
 
     /**
@@ -131,9 +152,8 @@ public class ExcelWriter {
      *            Write to this sheet
      * @return this current writer
      */
-    public ExcelWriter write(List<? extends BaseRowModel> data, Sheet sheet) {
-        excelBuilder.addContent(data, sheet);
-        return this;
+    public ExcelWriter write(List data, Sheet sheet) {
+        return write(data, sheet, null);
     }
 
     /**
@@ -147,7 +167,7 @@ public class ExcelWriter {
      *            Write to this table
      * @return this
      */
-    public ExcelWriter write(List<? extends BaseRowModel> data, Sheet sheet, Table table) {
+    public ExcelWriter write(List data, Sheet sheet, Table table) {
         excelBuilder.addContent(data, sheet, table);
         return this;
     }
@@ -161,7 +181,9 @@ public class ExcelWriter {
      * @param sheet
      *            Write to this sheet
      * @return this
+     * @deprecated please use {@link ExcelWriter#write(List, Sheet)}
      */
+    @Deprecated
     public ExcelWriter write1(List<List<Object>> data, Sheet sheet) {
         excelBuilder.addContent(data, sheet);
         return this;
@@ -174,8 +196,9 @@ public class ExcelWriter {
      *            Data to be written
      * @param sheet
      *            Write to this sheet
-     * @return this
+     * @deprecated please use {@link ExcelWriter#write(List, Sheet)}
      */
+    @Deprecated
     public ExcelWriter write0(List<List<String>> data, Sheet sheet) {
         excelBuilder.addContent(data, sheet);
         return this;
@@ -190,8 +213,9 @@ public class ExcelWriter {
      *            Write to this sheet
      * @param table
      *            Write to this table
-     * @return this
+     * @deprecated please use {@link ExcelWriter#write(List, Sheet,Table)}
      */
+    @Deprecated
     public ExcelWriter write0(List<List<String>> data, Sheet sheet, Table table) {
         excelBuilder.addContent(data, sheet, table);
         return this;
@@ -206,13 +230,33 @@ public class ExcelWriter {
      *            Write to this sheet
      * @param table
      *            Write to this table
-     * @return
+     * @deprecated please use {@link ExcelWriter#write(List, Sheet,Table)}
      */
+    @Deprecated
     public ExcelWriter write1(List<List<Object>> data, Sheet sheet, Table table) {
         excelBuilder.addContent(data, sheet, table);
         return this;
     }
 
+    /**
+     * Merge Cells,Indexes are zero-based.
+     *
+     * @param firstRow
+     *            Index of first row
+     * @param lastRow
+     *            Index of last row (inclusive), must be equal to or larger than {@code firstRow}
+     * @param firstCol
+     *            Index of first column
+     * @param lastCol
+     *            Index of last column (inclusive), must be equal to or larger than {@code firstCol}
+     * @deprecated please use{@link OnceAbsoluteMergeStrategy}
+     */
+    @Deprecated
+    public ExcelWriter merge(int firstRow, int lastRow, int firstCol, int lastCol) {
+        excelBuilder.merge(firstRow, lastRow, firstCol, lastCol);
+        return this;
+    }
+
     /**
      * Close IO
      */
diff --git a/src/main/java/com/alibaba/excel/context/WriteContext.java b/src/main/java/com/alibaba/excel/context/WriteContext.java
index 17d978d6..639413bb 100644
--- a/src/main/java/com/alibaba/excel/context/WriteContext.java
+++ b/src/main/java/com/alibaba/excel/context/WriteContext.java
@@ -1,11 +1,10 @@
 package com.alibaba.excel.context;
 
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.usermodel.Workbook;
-
-import com.alibaba.excel.metadata.ExcelHeadProperty;
 import com.alibaba.excel.metadata.Table;
 import com.alibaba.excel.metadata.holder.ConfigurationSelector;
+import com.alibaba.excel.metadata.holder.SheetHolder;
+import com.alibaba.excel.metadata.holder.TableHolder;
+import com.alibaba.excel.metadata.holder.WorkbookHolder;
 
 /**
  * Write context
@@ -32,13 +31,28 @@ public interface WriteContext {
      * 
      * @return
      */
-    ConfigurationSelector configurationSelector();
+    ConfigurationSelector currentConfigurationSelector();
 
-    Sheet getCurrentSheet();
+    /**
+     * All information about the workbook you are currently working on
+     * 
+     * @return
+     */
+    WorkbookHolder currentWorkbookHolder();
 
-    ExcelHeadProperty getExcelHeadProperty();
+    /**
+     * All information about the sheet you are currently working on
+     * 
+     * @return
+     */
+    SheetHolder currentSheetHolder();
 
-    Workbook getWorkbook();
+    /**
+     * All information about the table you are currently working on
+     * 
+     * @return
+     */
+    TableHolder currentTableHolder();
 
     /**
      * close
diff --git a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java
index b543b670..f8fad84c 100644
--- a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java
+++ b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java
@@ -1,8 +1,6 @@
 package com.alibaba.excel.context;
 
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -15,13 +13,11 @@ import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.IndexedColors;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.alibaba.excel.converters.Converter;
-import com.alibaba.excel.converters.ConverterRegistryCenter;
 import com.alibaba.excel.converters.bigdecimal.BigDecimalNumberConverter;
 import com.alibaba.excel.converters.date.DateStringConverter;
 import com.alibaba.excel.event.NotRepeatExecutor;
@@ -32,14 +28,15 @@ import com.alibaba.excel.metadata.ExcelHeadProperty;
 import com.alibaba.excel.metadata.Font;
 import com.alibaba.excel.metadata.Head;
 import com.alibaba.excel.metadata.Table;
+import com.alibaba.excel.metadata.TableStyle;
 import com.alibaba.excel.metadata.holder.ConfigurationSelector;
 import com.alibaba.excel.metadata.holder.SheetHolder;
 import com.alibaba.excel.metadata.holder.TableHolder;
 import com.alibaba.excel.metadata.holder.WorkbookHolder;
-import com.alibaba.excel.support.ExcelTypeEnum;
 import com.alibaba.excel.util.WorkBookUtil;
 import com.alibaba.excel.write.handler.WriteHandler;
 import com.alibaba.excel.write.style.RowCellStyleStrategy;
+import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy;
 import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
 
 /**
@@ -67,30 +64,17 @@ public class WriteContextImpl implements WriteContext {
      * Configuration of currently operated cell
      */
     private ConfigurationSelector currentConfigurationSelector;
-    /**
-     * Excel type
-     */
-    private ExcelTypeEnum excelType;
-    /**
-     * Final output stream
-     */
-    private OutputStream outputStream;
-    /**
-     * Final output stream
-     */
-    private InputStream templateInputStream;
 
-    public WriteContextImpl(InputStream templateInputStream, OutputStream outputStream, ExcelTypeEnum excelType,
-        Boolean needHead, Map<Class, Converter> customConverterMap, List<WriteHandler> customWriteHandlerList) {
+    public WriteContextImpl(com.alibaba.excel.metadata.Workbook workbook) {
+        if (workbook == null) {
+            throw new IllegalArgumentException("Workbook argument cannot be null");
+        }
         if (LOGGER.isDebugEnabled()) {
             LOGGER.debug("Begin to Initialization 'WriteContextImpl'");
         }
-        initCurrentWorkbookHolder(needHead, customConverterMap, customWriteHandlerList);
-        this.excelType = excelType;
-        this.outputStream = outputStream;
-        this.templateInputStream = templateInputStream;
+        initCurrentWorkbookHolder(workbook);
         try {
-            currentWorkbookHolder.setWorkbook(WorkBookUtil.createWorkBook(templateInputStream, excelType));
+            currentWorkbookHolder.setWorkbook(WorkBookUtil.createWorkBook(workbook));
         } catch (IOException e) {
             throw new ExcelGenerateException("Create workbook failure", e);
         }
@@ -99,23 +83,30 @@ public class WriteContextImpl implements WriteContext {
         }
     }
 
-    private void initCurrentWorkbookHolder(Boolean needHead, Map<Class, Converter> customConverterMap,
-        List<WriteHandler> customWriteHandlerList) {
+    private void initCurrentWorkbookHolder(com.alibaba.excel.metadata.Workbook workbook) {
         currentWorkbookHolder = new WorkbookHolder();
-        if (needHead == null) {
+        currentWorkbookHolder.setWorkbookParam(workbook);
+        currentWorkbookHolder.setTemplateInputStream(workbook.getTemplateInputStream());
+        currentWorkbookHolder.setOutputStream(workbook.getOutputStream());
+        if (workbook.getNeedHead() == null) {
             currentWorkbookHolder.setNeedHead(Boolean.TRUE);
         } else {
-            currentWorkbookHolder.setNeedHead(needHead);
+            currentWorkbookHolder.setNeedHead(workbook.getNeedHead());
+        }
+        if (workbook.getWriteRelativeHeadRowIndex() == null) {
+            currentWorkbookHolder.setWriteRelativeHeadRowIndex(0);
+        } else {
+            currentWorkbookHolder.setWriteRelativeHeadRowIndex(workbook.getWriteRelativeHeadRowIndex());
         }
         List<WriteHandler> handlerList = new ArrayList<WriteHandler>();
-        if (customWriteHandlerList != null && !customWriteHandlerList.isEmpty()) {
-            handlerList.addAll(customWriteHandlerList);
+        if (workbook.getCustomWriteHandlerList() != null && !workbook.getCustomWriteHandlerList().isEmpty()) {
+            handlerList.addAll(workbook.getCustomWriteHandlerList());
         }
         handlerList.addAll(loadDefaultHandler());
         currentWorkbookHolder.setWriteHandlerList(sortAndClearUpHandler(handlerList));
         Map<Class, Converter> converterMap = loadDefaultConverter();
-        if (customConverterMap != null && !customConverterMap.isEmpty()) {
-            converterMap.putAll(customConverterMap);
+        if (workbook.getCustomConverterMap() != null && !workbook.getCustomConverterMap().isEmpty()) {
+            converterMap.putAll(workbook.getCustomConverterMap());
         }
         currentWorkbookHolder.setConverterMap(converterMap);
         currentWorkbookHolder.setHasBeenInitializedSheet(new HashMap<Integer, SheetHolder>());
@@ -127,8 +118,7 @@ public class WriteContextImpl implements WriteContext {
 
     private List<WriteHandler> sortAndClearUpHandler(List<WriteHandler> handlerList) {
         // sort
-        Map<Integer, List<WriteHandler>> orderExcelWriteHandlerMap =
-            new TreeMap<Integer, List<WriteHandler>>();
+        Map<Integer, List<WriteHandler>> orderExcelWriteHandlerMap = new TreeMap<Integer, List<WriteHandler>>();
         for (WriteHandler handler : handlerList) {
             int order = Integer.MIN_VALUE;
             if (handler instanceof Order) {
@@ -198,6 +188,7 @@ public class WriteContextImpl implements WriteContext {
                 LOGGER.debug("Sheet:{} is already existed", sheet.getSheetNo());
             }
             currentSheetHolder = currentWorkbookHolder.getHasBeenInitializedSheet().get(sheet.getSheetNo());
+            currentTableHolder = null;
             currentConfigurationSelector = currentSheetHolder;
             if (LOGGER.isDebugEnabled()) {
                 LOGGER.debug("CurrentConfigurationSelector is currentSheetHolder");
@@ -206,12 +197,13 @@ public class WriteContextImpl implements WriteContext {
         }
         initCurrentSheetHolder(sheet);
         // Initialization current sheet
-        initCurrentSheet(sheet);
+        initSheet(sheet);
     }
 
     private void initCurrentSheetHolder(com.alibaba.excel.metadata.Sheet sheet) {
         currentSheetHolder = new SheetHolder();
         currentSheetHolder.setSheetParam(sheet);
+        currentSheetHolder.setParentWorkBook(currentWorkbookHolder);
         if (sheet.getNeedHead() == null) {
             currentSheetHolder.setNeedHead(currentConfigurationSelector.needHead());
         } else {
@@ -220,30 +212,66 @@ public class WriteContextImpl implements WriteContext {
         if (sheet.getWriteRelativeHeadRowIndex() == null) {
             currentSheetHolder.setWriteRelativeHeadRowIndex(currentConfigurationSelector.writeRelativeHeadRowIndex());
         } else {
-            currentSheetHolder.setNeedHead(sheet.getWriteRelativeHeadRowIndex());
+            currentSheetHolder.setWriteRelativeHeadRowIndex(sheet.getWriteRelativeHeadRowIndex());
         }
-
+        // Compatible with old code
+        compatibleOldCode(sheet);
         List<WriteHandler> handlerList = new ArrayList<WriteHandler>();
         if (sheet.getCustomWriteHandlerList() != null && !sheet.getCustomWriteHandlerList().isEmpty()) {
             handlerList.addAll(sheet.getCustomWriteHandlerList());
         }
         handlerList.addAll(currentConfigurationSelector.writeHandlerList());
         currentSheetHolder.setWriteHandlerList(sortAndClearUpHandler(handlerList));
-
         Map<Class, Converter> converterMap = new HashMap<Class, Converter>(currentConfigurationSelector.converterMap());
         if (sheet.getCustomConverterMap() != null && !sheet.getCustomConverterMap().isEmpty()) {
             converterMap.putAll(sheet.getCustomConverterMap());
         }
-        currentWorkbookHolder.setConverterMap(converterMap);
+        currentSheetHolder.setConverterMap(converterMap);
         currentSheetHolder.setHasBeenInitializedTable(new HashMap<Integer, TableHolder>());
         currentWorkbookHolder.getHasBeenInitializedSheet().put(sheet.getSheetNo(), currentSheetHolder);
+        currentTableHolder = null;
         currentConfigurationSelector = currentSheetHolder;
         if (LOGGER.isDebugEnabled()) {
             LOGGER.debug("CurrentConfigurationSelector is currentSheetHolder");
         }
     }
 
-    private void initCurrentSheet(com.alibaba.excel.metadata.Sheet sheet) {
+    /**
+     * Compatible with old code
+     */
+    @Deprecated
+    private void compatibleOldCode(com.alibaba.excel.metadata.Sheet sheet) {
+        if (sheet.getColumnWidthMap() != null && !sheet.getColumnWidthMap().isEmpty()) {
+            final Map<Integer, Integer> columnWidthMap = sheet.getColumnWidthMap();
+            if (sheet.getCustomWriteHandlerList() == null) {
+                sheet.setCustomWriteHandlerList(new ArrayList<WriteHandler>());
+            }
+            sheet.getCustomWriteHandlerList().add(new AbstractHeadColumnWidthStyleStrategy() {
+                @Override
+                protected int columnWidth(Head head) {
+                    if (columnWidthMap.containsKey(head.getColumnIndex())) {
+                        columnWidthMap.get(head.getColumnIndex());
+                    }
+                    return 20;
+                }
+            });
+        }
+        if (sheet.getTableStyle() != null) {
+            final TableStyle tableStyle = sheet.getTableStyle();
+            if (sheet.getCustomWriteHandlerList() == null) {
+                sheet.setCustomWriteHandlerList(new ArrayList<WriteHandler>());
+            }
+            CellStyle headCellStyle = new CellStyle();
+            headCellStyle.setFont(tableStyle.getTableHeadFont());
+            headCellStyle.setIndexedColors(tableStyle.getTableContentBackGroundColor());
+            CellStyle contentCellStyle = new CellStyle();
+            contentCellStyle.setFont(tableStyle.getTableContentFont());
+            contentCellStyle.setIndexedColors(tableStyle.getTableContentBackGroundColor());
+            sheet.getCustomWriteHandlerList().add(new RowCellStyleStrategy(headCellStyle, contentCellStyle));
+        }
+    }
+
+    private void initSheet(com.alibaba.excel.metadata.Sheet sheet) {
         Sheet currentSheet;
         try {
             currentSheet = currentWorkbookHolder.getWorkbook().getSheetAt(sheet.getSheetNo());
@@ -257,57 +285,26 @@ public class WriteContextImpl implements WriteContext {
         // Initialization head
         currentSheetHolder.setExcelHeadProperty(new ExcelHeadProperty(sheet.getClazz(), sheet.getHead()));
         // Initialization head
-        initHead();
+        initHead(currentSheetHolder.getExcelHeadProperty());
     }
 
-    public void initHead(ExcelHeadProperty excelHeadPropert) {
+    public void initHead(ExcelHeadProperty excelHeadProperty) {
         if (!currentConfigurationSelector.needHead() || !currentSheetHolder.getExcelHeadProperty().hasHead()) {
             return;
         }
-        int startRow = getCurrentSheet().getLastRowNum();
+        int startRow = currentSheetHolder.getSheet().getLastRowNum();
         startRow += currentConfigurationSelector.writeRelativeHeadRowIndex();
         // Combined head
-        addMergedRegionToCurrentSheet(startRow);
-        for (int i = startRow; i < currentSheetHolder.getExcelHeadProperty().getHeadRowNumber() + startRow; i++) {
-            Row row = WorkBookUtil.createRow(getCurrentSheet(), i);
-            // Set the row height of the header
-            currentSheetHolder.getRowHighStyleStrategy().headColumnHigh(i);
-            if (null != writeHandler) {
-                this.writeHandler.row(i, row);
-            }
-            addOneRowOfHeadDataToExcel(row, i, currentSheetHolder.getExcelHeadProperty().getHeadList());
-        }
-    }
-
-    public void initTableHead() {
-        if (!currentTableHolder.isNeedHead() || !currentTableHolder.getExcelHeadProperty().hasHead()) {
-            return;
-        }
-        int startRow = getCurrentSheet().getLastRowNum();
-        if (startRow > 0) {
-            startRow += 4;
-        } else {
-            startRow = getCurrentSheetParam().getStartRow();
-        }
-        // Combined head
-        addMergedRegionToCurrentSheet(startRow);
-        for (int i = startRow; i < currentTableHolder.getExcelHeadProperty().getHeadRowNumber() + startRow; i++) {
-            Row row = WorkBookUtil.createRow(getCurrentSheet(), i);
-            // Set the row height of the header
-            currentTableHolder.getRowHighStyleStrategy().headColumnHigh(i);
-            if (null != writeHandler) {
-                this.writeHandler.row(i, row);
-            }
-            addOneRowOfHeadDataToExcel(row, i, currentTableHolder.getExcelHeadProperty().getHeadList());
+        addMergedRegionToCurrentSheet(excelHeadProperty, startRow);
+        for (int i = startRow; i < excelHeadProperty.getHeadRowNumber() + startRow; i++) {
+            Row row = WorkBookUtil.createRow(currentSheetHolder.getSheet(), i);
+            addOneRowOfHeadDataToExcel(row, i, excelHeadProperty.getHeadList());
         }
-        // Initialization sheet column width
-        initSheetColumnWidth();
     }
 
-    private void addMergedRegionToCurrentSheet(int startRow) {
-        for (com.alibaba.excel.metadata.CellRange cellRangeModel : currentSheetHolder.getExcelHeadProperty()
-            .getCellRangeModels()) {
-            currentSheet.addMergedRegion(new CellRangeAddress(cellRangeModel.getFirstRow() + startRow,
+    private void addMergedRegionToCurrentSheet(ExcelHeadProperty excelHeadProperty, int startRow) {
+        for (com.alibaba.excel.metadata.CellRange cellRangeModel : excelHeadProperty.getCellRangeModels()) {
+            currentSheetHolder.getSheet().addMergedRegion(new CellRangeAddress(cellRangeModel.getFirstRow() + startRow,
                 cellRangeModel.getLastRow() + startRow, cellRangeModel.getFirstCol(), cellRangeModel.getLastCol()));
         }
     }
@@ -315,127 +312,121 @@ public class WriteContextImpl implements WriteContext {
     private void addOneRowOfHeadDataToExcel(Row row, int rowIndex, List<Head> headList) {
         for (int i = 0; i < headList.size(); i++) {
             Head head = headList.get(i);
-            Cell cell = WorkBookUtil.createCell(row, i,
-                currentSheetHolder.getCellStyleStrategy().headCellStyle(rowIndex, headList.get(i)),
-                head.getHeadName(i));
-            if (null != writeHandler) {
-                this.writeHandler.cell(i, cell);
-            }
+            // TODO 创建cell
+            Cell cell = WorkBookUtil.createCell(row, i, null, head.getHeadName(i));
         }
     }
 
-    private void cleanCurrentTable() {
-        this.excelHeadProperty = null;
-        this.currentHeadCellStyle = null;
-        this.currentContentCellStyle = null;
-        this.currentTable = null;
-
-    }
-
     @Override
     public void currentTable(Table table) {
         if (table == null) {
             return;
         }
-        if (currentSheetHolder == null) {
-            throw new IllegalStateException("Must first call WriteContextImpl#currentSheet");
+        if (table.getTableNo() == null || table.getTableNo() <= 0) {
+            table.setTableNo(0);
         }
-        if(currentSheetHolder.getHasBeenInitializedTable().containsKey(table.getTableNo())){
-            currentTableHolder=currentSheetHolder.getHasBeenInitializedTable().get(table.getTableNo());
+        if (currentSheetHolder.getHasBeenInitializedTable().containsKey(table.getTableNo())) {
+            if (LOGGER.isDebugEnabled()) {
+                LOGGER.debug("Table:{} is already existed", table.getTableNo());
+            }
+            currentTableHolder = currentSheetHolder.getHasBeenInitializedTable().get(table.getTableNo());
+            currentConfigurationSelector = currentTableHolder;
+            if (LOGGER.isDebugEnabled()) {
+                LOGGER.debug("CurrentConfigurationSelector is currentTableHolder");
+            }
             return;
         }
+        initCurrentTableHolder(table);
+        // Initialization head
+        currentTableHolder.setExcelHeadProperty(new ExcelHeadProperty(table.getClazz(), table.getHead()));
 
+        initHead(currentTableHolder.getExcelHeadProperty());
+    }
 
-        
-        
-        currentTable.getTableNo()
-
-
-        if (null == currentTable || currentTable.getTableNo() != table.getTableNo()) {
-            cleanCurrentTable();
-            this.currentTable = table;
-            this.initExcelHeadProperty(table.getHead(), table.getClazz());
-            this.initTableStyle(table.getTableStyle());
-            this.initTableHead();
+    private void initCurrentTableHolder(com.alibaba.excel.metadata.Table table) {
+        currentTableHolder = new TableHolder();
+        currentTableHolder.setTableParam(table);
+        currentTableHolder.setParentSheet(currentSheetHolder);
+        currentTableHolder.setTableNo(table.getTableNo());
+        if (table.getNeedHead() == null) {
+            currentTableHolder.setNeedHead(currentConfigurationSelector.needHead());
+        } else {
+            currentTableHolder.setNeedHead(table.getNeedHead());
+        }
+        if (table.getWriteRelativeHeadRowIndex() == null) {
+            currentTableHolder.setWriteRelativeHeadRowIndex(currentConfigurationSelector.writeRelativeHeadRowIndex());
+        } else {
+            currentTableHolder.setWriteRelativeHeadRowIndex(table.getWriteRelativeHeadRowIndex());
+        }
+        // Compatible with old code
+        compatibleOldCode(table);
+        List<WriteHandler> handlerList = new ArrayList<WriteHandler>();
+        if (table.getCustomWriteHandlerList() != null && !table.getCustomWriteHandlerList().isEmpty()) {
+            handlerList.addAll(table.getCustomWriteHandlerList());
+        }
+        handlerList.addAll(currentConfigurationSelector.writeHandlerList());
+        currentTableHolder.setWriteHandlerList(sortAndClearUpHandler(handlerList));
+        Map<Class, Converter> converterMap = new HashMap<Class, Converter>(currentConfigurationSelector.converterMap());
+        if (table.getCustomConverterMap() != null && !table.getCustomConverterMap().isEmpty()) {
+            converterMap.putAll(table.getCustomConverterMap());
+        }
+        currentTableHolder.setConverterMap(converterMap);
+        currentConfigurationSelector = currentTableHolder;
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug("CurrentConfigurationSelector is currentTableHolder");
         }
-
     }
 
-    @Override
-    public ExcelHeadProperty getExcelHeadProperty() {
-        return currentSheetHolder.getExcelHeadProperty();
+    /**
+     * Compatible with old code
+     */
+    @Deprecated
+    private void compatibleOldCode(com.alibaba.excel.metadata.Table table) {
+        if (table.getTableStyle() != null) {
+            final TableStyle tableStyle = table.getTableStyle();
+            if (table.getCustomWriteHandlerList() == null) {
+                table.setCustomWriteHandlerList(new ArrayList<WriteHandler>());
+            }
+            CellStyle headCellStyle = new CellStyle();
+            headCellStyle.setFont(tableStyle.getTableHeadFont());
+            headCellStyle.setIndexedColors(tableStyle.getTableContentBackGroundColor());
+            CellStyle contentCellStyle = new CellStyle();
+            contentCellStyle.setFont(tableStyle.getTableContentFont());
+            contentCellStyle.setIndexedColors(tableStyle.getTableContentBackGroundColor());
+            table.getCustomWriteHandlerList().add(new RowCellStyleStrategy(headCellStyle, contentCellStyle));
+        }
     }
 
     @Override
-    public boolean needHead() {
-        return this.needHead;
-    }
-
-    public String getCurrentSheetName() {
-        return currentSheetHolder.getCurrentSheetParam();
-    }
-
-    public void setCurrentSheetName(String currentSheetName) {
-        this.currentSheetName = currentSheetName;
-    }
-
-    public ExcelTypeEnum getExcelType() {
-        return excelType;
-    }
-
-    public void setExcelType(ExcelTypeEnum excelType) {
-        this.excelType = excelType;
+    public ConfigurationSelector currentConfigurationSelector() {
+        return currentConfigurationSelector;
     }
 
     @Override
-    public OutputStream getOutputStream() {
-        return outputStream;
-    }
-
-    public CellStyle getCurrentHeadCellStyle() {
-        return this.currentHeadCellStyle == null ? defaultCellStyle : this.currentHeadCellStyle;
-    }
-
-    public CellStyle getCurrentContentStyle() {
-        return this.currentContentCellStyle;
+    public WorkbookHolder currentWorkbookHolder() {
+        return currentWorkbookHolder;
     }
 
     @Override
-    public Workbook getWorkbook() {
-        return workbook;
-    }
-
-    public com.alibaba.excel.metadata.Sheet getCurrentSheetParam() {
-        return currentSheetHolder.getCurrentSheetParam();
-    }
-
-    public void setCurrentSheetParam(com.alibaba.excel.metadata.Sheet currentSheetParam) {
-        this.currentSheetParam = currentSheetParam;
-    }
-
-    public Table getCurrentTableParam() {
-        return currentTableHolder.getCurrentTableParam();
-    }
-
-    public Table getCurrentTable() {
-        return currentTable;
+    public SheetHolder currentSheetHolder() {
+        return currentSheetHolder;
     }
 
     @Override
-    public ConverterRegistryCenter getConverterRegistryCenter() {
-        return registryCenter;
+    public TableHolder currentTableHolder() {
+        return currentTableHolder;
     }
 
     @Override
     public void finish() {
         try {
-            workbook.write(outputStream);
-            workbook.close();
-            if (outputStream != null) {
-                outputStream.close();
+            currentWorkbookHolder.getWorkbook().write(currentWorkbookHolder.getOutputStream());
+            currentWorkbookHolder.getWorkbook().close();
+            if (currentWorkbookHolder.getOutputStream() != null) {
+                currentWorkbookHolder.getOutputStream().close();
             }
-            if (templateInputStream != null) {
-                templateInputStream.close();
+            if (currentWorkbookHolder.getTemplateInputStream() != null) {
+                currentWorkbookHolder.getTemplateInputStream().close();
             }
         } catch (IOException e) {
             throw new ExcelGenerateException("Can not close IO", e);
diff --git a/src/main/java/com/alibaba/excel/converters/Converter.java b/src/main/java/com/alibaba/excel/converters/Converter.java
index 7a9a11bb..5443cbd5 100644
--- a/src/main/java/com/alibaba/excel/converters/Converter.java
+++ b/src/main/java/com/alibaba/excel/converters/Converter.java
@@ -4,6 +4,7 @@ import com.alibaba.excel.enums.CellDataTypeEnum;
 import com.alibaba.excel.metadata.CellData;
 import com.alibaba.excel.metadata.ExcelColumnProperty;
 import com.sun.istack.internal.NotNull;
+import com.sun.istack.internal.Nullable;
 
 public interface Converter<T> {
 
@@ -11,7 +12,7 @@ public interface Converter<T> {
 
     CellDataTypeEnum supportExcelTypeKey();
 
-    T convertToJavaData(@NotNull CellData cellData, ExcelColumnProperty columnProperty) throws Exception;
+    T convertToJavaData(@NotNull CellData cellData, @Nullable ExcelColumnProperty columnProperty) throws Exception;
 
-    CellData convertToExcelData(@NotNull T value, ExcelColumnProperty columnProperty) throws Exception;
+    CellData convertToExcelData(@NotNull T value, @Nullable ExcelColumnProperty columnProperty) throws Exception;
 }
diff --git a/src/main/java/com/alibaba/excel/converters/string/StringStringConverter.java b/src/main/java/com/alibaba/excel/converters/string/StringStringConverter.java
new file mode 100644
index 00000000..0fb7e30e
--- /dev/null
+++ b/src/main/java/com/alibaba/excel/converters/string/StringStringConverter.java
@@ -0,0 +1,34 @@
+package com.alibaba.excel.converters.string;
+
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.CellData;
+import com.alibaba.excel.metadata.ExcelColumnProperty;
+
+/**
+ * String and string converter
+ *
+ * @author zhuangjiaju
+ */
+public class StringStringConverter implements Converter<String> {
+    @Override
+    public Class supportJavaTypeKey() {
+        return String.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public String convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) {
+        return cellData.getStringValue();
+    }
+
+    @Override
+    public CellData convertToExcelData(String value, ExcelColumnProperty columnProperty) {
+        return new CellData(value);
+    }
+
+}
diff --git a/src/main/java/com/alibaba/excel/event/WriteHandler.java b/src/main/java/com/alibaba/excel/event/WriteHandler.java
new file mode 100644
index 00000000..37dcc5ea
--- /dev/null
+++ b/src/main/java/com/alibaba/excel/event/WriteHandler.java
@@ -0,0 +1,38 @@
+package com.alibaba.excel.event;
+
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+
+/**
+ *
+ * @author jipengfei
+ * @deprecated please use {@ com.alibaba.excel.write.handler.WriteHandler}
+ */
+@Deprecated
+public interface WriteHandler {
+
+    /**
+     * Custom operation after creating each sheet
+     *
+     * @param sheetNo
+     * @param sheet
+     */
+    void sheet(int sheetNo, Sheet sheet);
+
+    /**
+     * Custom operation after creating each row
+     *
+     * @param rowNum
+     * @param row
+     */
+    void row(int rowNum, Row row);
+
+    /**
+     * Custom operation after creating each cell
+     * 
+     * @param cellNum
+     * @param cell
+     */
+    void cell(int cellNum, Cell cell);
+}
diff --git a/src/main/java/com/alibaba/excel/metadata/Sheet.java b/src/main/java/com/alibaba/excel/metadata/Sheet.java
index d8cf0e45..0df6aeca 100644
--- a/src/main/java/com/alibaba/excel/metadata/Sheet.java
+++ b/src/main/java/com/alibaba/excel/metadata/Sheet.java
@@ -1,10 +1,14 @@
 package com.alibaba.excel.metadata;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
 import com.alibaba.excel.write.handler.WriteHandler;
+import com.alibaba.excel.write.style.RowCellStyleStrategy;
+import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
 
 /**
  * sheet
@@ -28,7 +32,6 @@ public class Sheet {
      * <li>2 - This Sheet has two row head ,since the third row is the data
      */
     private Integer readHeadRowNumber;
-
     /**
      * Writes the head relative to the existing contents of the sheet. Indexes are zero-based.
      */
@@ -54,6 +57,79 @@ public class Sheet {
      */
     private List<WriteHandler> customWriteHandlerList;
 
+    /**
+     * column with
+     * 
+     * @deprecated please use {@link SimpleColumnWidthStyleStrategy}
+     */
+    @Deprecated
+    private Map<Integer, Integer> columnWidthMap = new HashMap<Integer, Integer>();
+
+    /**
+     *
+     * @deprecated please use{@link RowCellStyleStrategy}
+     */
+    @Deprecated
+    private TableStyle tableStyle;
+
+    public Sheet() {}
+
+    /**
+     * It was 'sheetNo' starting from 1 and now it is starting from 0
+     * 
+     * @param sheetNo
+     * @param readHeadRowNumber
+     * @deprecated please use {@link ExcelWriterSheetBuilder#build()}
+     */
+    @Deprecated
+    public Sheet(int sheetNo, int readHeadRowNumber) {
+        this.sheetNo = sheetNo - 1;
+        this.readHeadRowNumber = readHeadRowNumber;
+    }
+
+    /**
+     * It was 'sheetNo' starting from 1 and now it is starting from 0
+     *
+     * @param sheetNo
+     * @deprecated please use {@link ExcelWriterSheetBuilder#build()}
+     */
+    @Deprecated
+    public Sheet(int sheetNo) {
+        this.sheetNo = sheetNo - 1;
+    }
+
+    /**
+     * It was 'sheetNo' starting from 1 and now it is starting from 0
+     * 
+     * @param sheetNo
+     * @param readHeadRowNumber
+     * @param clazz
+     * @deprecated please use {@link ExcelWriterSheetBuilder#build()}
+     */
+    @Deprecated
+    public Sheet(int sheetNo, int readHeadRowNumber, Class clazz) {
+        this.sheetNo = sheetNo - 1;
+        this.readHeadRowNumber = readHeadRowNumber;
+        this.clazz = clazz;
+    }
+
+    /**
+     * It was 'sheetNo' starting from 1 and now it is starting from 0
+     *
+     * @param sheetNo
+     * @param readHeadRowNumber
+     * @param clazz
+     * @deprecated please use {@link ExcelWriterSheetBuilder#build()}
+     */
+    @Deprecated
+    public Sheet(int sheetNo, int readHeadRowNumber, Class clazz, String sheetName, List<List<String>> head) {
+        this.sheetNo = sheetNo - 1;
+        this.clazz = clazz;
+        this.readHeadRowNumber = readHeadRowNumber;
+        this.sheetName = sheetName;
+        this.head = head;
+    }
+
     public Integer getSheetNo() {
         return sheetNo;
     }
@@ -126,6 +202,42 @@ public class Sheet {
         this.customWriteHandlerList = customWriteHandlerList;
     }
 
+    public Map<Integer, Integer> getColumnWidthMap() {
+        return columnWidthMap;
+    }
+
+    public void setColumnWidthMap(Map<Integer, Integer> columnWidthMap) {
+        this.columnWidthMap = columnWidthMap;
+    }
+
+    public TableStyle getTableStyle() {
+        return tableStyle;
+    }
+
+    public void setTableStyle(TableStyle tableStyle) {
+        this.tableStyle = tableStyle;
+    }
+
+    /**
+     * 
+     * @param writeRelativeHeadRowIndex
+     * @deprecated please use {@link Sheet#setWriteRelativeHeadRowIndex(Integer)}
+     */
+    @Deprecated
+    public void setStartRow(int writeRelativeHeadRowIndex) {
+        this.writeRelativeHeadRowIndex = writeRelativeHeadRowIndex;
+    }
+
+    /**
+     * 
+     * @param readHeadRowNumber
+     * @deprecated please use {@link Sheet#setReadHeadRowNumber(Integer)} )}
+     */
+    @Deprecated
+    public void setHeadLineMun(int readHeadRowNumber) {
+        this.readHeadRowNumber = readHeadRowNumber;
+    }
+
     @Override
     public String toString() {
         return "Sheet{" + "sheetNo=" + sheetNo + ", sheetName='" + sheetName + '\'' + '}';
diff --git a/src/main/java/com/alibaba/excel/metadata/Table.java b/src/main/java/com/alibaba/excel/metadata/Table.java
index 6fb9c684..f0b4a3cf 100644
--- a/src/main/java/com/alibaba/excel/metadata/Table.java
+++ b/src/main/java/com/alibaba/excel/metadata/Table.java
@@ -1,8 +1,9 @@
 package com.alibaba.excel.metadata;
 
 import java.util.List;
+import java.util.Map;
 
-import com.alibaba.excel.event.Handler;
+import com.alibaba.excel.converters.Converter;
 import com.alibaba.excel.write.handler.WriteHandler;
 
 /**
@@ -12,11 +13,11 @@ import com.alibaba.excel.write.handler.WriteHandler;
  */
 public class Table {
     /**
-     * Starting from 1
+     * Starting from 0
      */
     private Integer tableNo;
     /**
-     * Writes the header relative to the existing contents of the sheet. Indexes are zero-based.
+     * Writes the head relative to the existing contents of the sheet. Indexes are zero-based.
      */
     private Integer writeRelativeHeadRowIndex;
     /**
@@ -28,47 +29,27 @@ public class Table {
      */
     private Class clazz;
     /**
-     * Need head
+     * Custom type conversions override the default
+     */
+    private Map<Class, Converter> customConverterMap;
+    /**
+     * Need Head
      */
     private Boolean needHead;
     /**
-     * Handle some extra logic. So far only for writing purposes {@link WriteHandler}
-     *
+     * Custom type handler override the default
      */
-    private List<Handler> handler;
-
-    public Table(Integer sheetNo) {
-        this(sheetNo, 0, null, null, Boolean.TRUE);
-    }
-
-    public Table(Integer sheetNo, List<List<String>> head) {
-        this(sheetNo, 0, head, null, Boolean.TRUE);
-    }
+    private List<WriteHandler> customWriteHandlerList;
 
-    public Table(Integer sheetNo, Class clazz) {
-        this(sheetNo, 0, null, clazz, Boolean.TRUE);
-    }
+    /**
+     *
+     * @deprecated please use{@link RowCellStyleStrategy}
+     */
+    @Deprecated
+    private TableStyle tableStyle;
 
-    public Table(Integer tableNo, Integer writeRelativeHeadRowIndex, List<List<String>> head, Class clazz,
-        Boolean needHead) {
-        if (tableNo == null || tableNo < 1) {
-            throw new IllegalArgumentException("SheetNo must greater than 0");
-        }
-        if (writeRelativeHeadRowIndex == null || writeRelativeHeadRowIndex < 0) {
-            throw new IllegalArgumentException("WriteRelativeHeadRowIndex must greater than -1");
-        }
-        if (head != null && !head.isEmpty() && clazz != null) {
-            throw new IllegalArgumentException("Head and clazz fill in no more than one");
-        }
-        if (needHead == null) {
-            throw new IllegalArgumentException("NeedHead can not be null");
-        }
+    public Table(Integer tableNo) {
         this.tableNo = tableNo;
-        this.writeRelativeHeadRowIndex = writeRelativeHeadRowIndex;
-        this.head = head;
-        this.clazz = clazz;
-        this.needHead = needHead;
-
     }
 
     public Integer getTableNo() {
@@ -103,6 +84,14 @@ public class Table {
         this.clazz = clazz;
     }
 
+    public Map<Class, Converter> getCustomConverterMap() {
+        return customConverterMap;
+    }
+
+    public void setCustomConverterMap(Map<Class, Converter> customConverterMap) {
+        this.customConverterMap = customConverterMap;
+    }
+
     public Boolean getNeedHead() {
         return needHead;
     }
@@ -111,12 +100,20 @@ public class Table {
         this.needHead = needHead;
     }
 
-    public List<Handler> getHandler() {
-        return handler;
+    public List<WriteHandler> getCustomWriteHandlerList() {
+        return customWriteHandlerList;
+    }
+
+    public void setCustomWriteHandlerList(List<WriteHandler> customWriteHandlerList) {
+        this.customWriteHandlerList = customWriteHandlerList;
+    }
+
+    public TableStyle getTableStyle() {
+        return tableStyle;
     }
 
-    public void setHandler(List<Handler> handler) {
-        this.handler = handler;
+    public void setTableStyle(TableStyle tableStyle) {
+        this.tableStyle = tableStyle;
     }
 
     @Override
diff --git a/src/main/java/com/alibaba/excel/metadata/TableStyle.java b/src/main/java/com/alibaba/excel/metadata/TableStyle.java
new file mode 100644
index 00000000..dd512844
--- /dev/null
+++ b/src/main/java/com/alibaba/excel/metadata/TableStyle.java
@@ -0,0 +1,63 @@
+package com.alibaba.excel.metadata;
+
+import org.apache.poi.ss.usermodel.IndexedColors;
+
+/**
+ * @author jipengfei
+ * @deprecated please use {@link RowCellStyleStrategy}
+ */
+@Deprecated
+public class TableStyle {
+
+    /**
+     * 表头背景颜色
+     */
+    private IndexedColors tableHeadBackGroundColor;
+
+    /**
+     * 表头字体样式
+     */
+    private Font tableHeadFont;
+
+    /**
+     * 表格内容字体样式
+     */
+    private Font tableContentFont;
+
+    /**
+     * 表格内容背景颜色
+     */
+    private IndexedColors tableContentBackGroundColor;
+
+    public IndexedColors getTableHeadBackGroundColor() {
+        return tableHeadBackGroundColor;
+    }
+
+    public void setTableHeadBackGroundColor(IndexedColors tableHeadBackGroundColor) {
+        this.tableHeadBackGroundColor = tableHeadBackGroundColor;
+    }
+
+    public Font getTableHeadFont() {
+        return tableHeadFont;
+    }
+
+    public void setTableHeadFont(Font tableHeadFont) {
+        this.tableHeadFont = tableHeadFont;
+    }
+
+    public Font getTableContentFont() {
+        return tableContentFont;
+    }
+
+    public void setTableContentFont(Font tableContentFont) {
+        this.tableContentFont = tableContentFont;
+    }
+
+    public IndexedColors getTableContentBackGroundColor() {
+        return tableContentBackGroundColor;
+    }
+
+    public void setTableContentBackGroundColor(IndexedColors tableContentBackGroundColor) {
+        this.tableContentBackGroundColor = tableContentBackGroundColor;
+    }
+}
diff --git a/src/main/java/com/alibaba/excel/metadata/Workbook.java b/src/main/java/com/alibaba/excel/metadata/Workbook.java
new file mode 100644
index 00000000..f0ea98cf
--- /dev/null
+++ b/src/main/java/com/alibaba/excel/metadata/Workbook.java
@@ -0,0 +1,144 @@
+package com.alibaba.excel.metadata;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import com.alibaba.excel.write.handler.WriteHandler;
+
+/**
+ * Workbook
+ *
+ * @author zhuangjiaju
+ **/
+public class Workbook {
+    /**
+     * Excel type
+     */
+    private ExcelTypeEnum excelType;
+    /**
+     * Final output stream
+     */
+    private OutputStream outputStream;
+    /**
+     * Template input stream
+     */
+    private InputStream templateInputStream;
+    /**
+     * Count the number of added heads when read sheet.
+     *
+     * <li>0 - This Sheet has no head ,since the first row are the data
+     * <li>1 - This Sheet has one row head , this is the default
+     * <li>2 - This Sheet has two row head ,since the third row is the data
+     */
+    private Integer readHeadRowNumber;
+    /**
+     * Writes the head relative to the existing contents of the sheet. Indexes are zero-based.
+     */
+    private Integer writeRelativeHeadRowIndex;
+    /**
+     * You can only choose one of the {@link Workbook#head} and {@link Workbook#clazz}
+     */
+    private List<List<String>> head;
+    /**
+     * You can only choose one of the {@link Workbook#head} and {@link Workbook#clazz}
+     */
+    private Class clazz;
+    /**
+     * Need Head
+     */
+    private Boolean needHead;
+    /**
+     * Custom type conversions override the default
+     */
+    private Map<Class, Converter> customConverterMap = new HashMap<Class, Converter>();
+    /**
+     * Custom type handler override the default
+     */
+    private List<WriteHandler> customWriteHandlerList = new ArrayList<WriteHandler>();
+
+    public ExcelTypeEnum getExcelType() {
+        return excelType;
+    }
+
+    public void setExcelType(ExcelTypeEnum excelType) {
+        this.excelType = excelType;
+    }
+
+    public OutputStream getOutputStream() {
+        return outputStream;
+    }
+
+    public void setOutputStream(OutputStream outputStream) {
+        this.outputStream = outputStream;
+    }
+
+    public InputStream getTemplateInputStream() {
+        return templateInputStream;
+    }
+
+    public void setTemplateInputStream(InputStream templateInputStream) {
+        this.templateInputStream = templateInputStream;
+    }
+
+    public Integer getReadHeadRowNumber() {
+        return readHeadRowNumber;
+    }
+
+    public void setReadHeadRowNumber(Integer readHeadRowNumber) {
+        this.readHeadRowNumber = readHeadRowNumber;
+    }
+
+    public Integer getWriteRelativeHeadRowIndex() {
+        return writeRelativeHeadRowIndex;
+    }
+
+    public void setWriteRelativeHeadRowIndex(Integer writeRelativeHeadRowIndex) {
+        this.writeRelativeHeadRowIndex = writeRelativeHeadRowIndex;
+    }
+
+    public List<List<String>> getHead() {
+        return head;
+    }
+
+    public void setHead(List<List<String>> head) {
+        this.head = head;
+    }
+
+    public Class getClazz() {
+        return clazz;
+    }
+
+    public void setClazz(Class clazz) {
+        this.clazz = clazz;
+    }
+
+    public Boolean getNeedHead() {
+        return needHead;
+    }
+
+    public void setNeedHead(Boolean needHead) {
+        this.needHead = needHead;
+    }
+
+    public Map<Class, Converter> getCustomConverterMap() {
+        return customConverterMap;
+    }
+
+    public void setCustomConverterMap(Map<Class, Converter> customConverterMap) {
+        this.customConverterMap = customConverterMap;
+    }
+
+    public List<WriteHandler> getCustomWriteHandlerList() {
+        return customWriteHandlerList;
+    }
+
+    public void setCustomWriteHandlerList(List<WriteHandler> customWriteHandlerList) {
+        this.customWriteHandlerList = customWriteHandlerList;
+    }
+}
diff --git a/src/main/java/com/alibaba/excel/metadata/holder/ConfigurationSelector.java b/src/main/java/com/alibaba/excel/metadata/holder/ConfigurationSelector.java
index 6ffba34f..1de3db0e 100644
--- a/src/main/java/com/alibaba/excel/metadata/holder/ConfigurationSelector.java
+++ b/src/main/java/com/alibaba/excel/metadata/holder/ConfigurationSelector.java
@@ -4,6 +4,7 @@ import java.util.List;
 import java.util.Map;
 
 import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.metadata.ExcelHeadProperty;
 import com.alibaba.excel.write.handler.WriteHandler;
 
 /**
@@ -40,4 +41,16 @@ public interface ConfigurationSelector {
      */
     int writeRelativeHeadRowIndex();
 
+    /**
+     * What 'ExcelHeadProperty' does the currently operated cell need to execute
+     */
+    ExcelHeadProperty excelHeadProperty();
+
+    /**
+     * 
+     * Record whether it's new or from cache
+     * 
+     * @return
+     */
+    boolean isNew();
 }
diff --git a/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java b/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java
index 3136badc..ae8a9afb 100644
--- a/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java
+++ b/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java
@@ -15,11 +15,23 @@ import com.alibaba.excel.write.handler.WriteHandler;
  * @author zhuangjiaju
  */
 public class SheetHolder implements ConfigurationSelector {
+
     /***
      * poi sheet
      */
     private Sheet sheet;
-
+    /***
+     * sheetNo
+     */
+    private Integer sheetNo;
+    /***
+     * sheetName
+     */
+    private String sheetName;
+    /***
+     * poi sheet
+     */
+    private WorkbookHolder parentWorkBook;
     /***
      * has been initialized table
      */
@@ -49,6 +61,10 @@ public class SheetHolder implements ConfigurationSelector {
      * Writes the head relative to the existing contents of the sheet. Indexes are zero-based.
      */
     private Integer writeRelativeHeadRowIndex;
+    /**
+     * Record whether it's new or from cache
+     */
+    private Boolean newInitialization;
 
     public Sheet getSheet() {
         return sheet;
@@ -58,6 +74,30 @@ public class SheetHolder implements ConfigurationSelector {
         this.sheet = sheet;
     }
 
+    public Integer getSheetNo() {
+        return sheetNo;
+    }
+
+    public void setSheetNo(Integer sheetNo) {
+        this.sheetNo = sheetNo;
+    }
+
+    public String getSheetName() {
+        return sheetName;
+    }
+
+    public void setSheetName(String sheetName) {
+        this.sheetName = sheetName;
+    }
+
+    public WorkbookHolder getParentWorkBook() {
+        return parentWorkBook;
+    }
+
+    public void setParentWorkBook(WorkbookHolder parentWorkBook) {
+        this.parentWorkBook = parentWorkBook;
+    }
+
     public Map<Integer, TableHolder> getHasBeenInitializedTable() {
         return hasBeenInitializedTable;
     }
@@ -114,6 +154,14 @@ public class SheetHolder implements ConfigurationSelector {
         this.writeRelativeHeadRowIndex = writeRelativeHeadRowIndex;
     }
 
+    public Boolean getNewInitialization() {
+        return newInitialization;
+    }
+
+    public void setNewInitialization(Boolean newInitialization) {
+        this.newInitialization = newInitialization;
+    }
+
     @Override
     public List<WriteHandler> writeHandlerList() {
         return getWriteHandlerList();
@@ -128,4 +176,20 @@ public class SheetHolder implements ConfigurationSelector {
     public boolean needHead() {
         return getNeedHead();
     }
+
+    @Override
+    public int writeRelativeHeadRowIndex() {
+        return getWriteRelativeHeadRowIndex();
+    }
+
+    @Override
+    public ExcelHeadProperty excelHeadProperty() {
+        return getExcelHeadProperty();
+    }
+
+    @Override
+    public boolean isNew() {
+        return getNewInitialization();
+    }
+
 }
diff --git a/src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java b/src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java
index dfff6edd..2ccb9f8a 100644
--- a/src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java
+++ b/src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java
@@ -1,45 +1,56 @@
 package com.alibaba.excel.metadata.holder;
 
+import java.util.List;
+import java.util.Map;
+
+import com.alibaba.excel.converters.Converter;
 import com.alibaba.excel.metadata.ExcelHeadProperty;
 import com.alibaba.excel.metadata.Table;
-import com.alibaba.excel.write.style.CellStyleStrategy;
-import com.alibaba.excel.write.style.column.ColumnWidthStyleStrategy;
-import com.alibaba.excel.write.style.row.RowHighStyleStrategy;
+import com.alibaba.excel.write.handler.WriteHandler;
 
 /**
  * sheet holder
  *
  * @author zhuangjiaju
  */
-public class TableHolder implements ConfigurationSelector{
+public class TableHolder implements ConfigurationSelector {
     /***
      * poi sheet
      */
     private SheetHolder parentSheet;
+    /***
+     * tableNo
+     */
+    private Integer tableNo;
+    /**
+     * Need Head
+     */
+    private Boolean needHead;
+    /**
+     * Write handler for workbook
+     */
+    private List<WriteHandler> writeHandlerList;
+    /**
+     * Converter for workbook
+     */
+    private Map<Class, Converter> converterMap;
     /**
-     * the header attribute of excel
+     * Excel head property
      */
     private ExcelHeadProperty excelHeadProperty;
-
-    private CellStyleStrategy cellStyleStrategy;
-
-    private ColumnWidthStyleStrategy columnWidthStyleStrategy;
-    private RowHighStyleStrategy rowHighStyleStrategy;
-
-    private boolean needHead = true;
+    /**
+     * Writes the head relative to the existing contents of the sheet. Indexes are zero-based.
+     */
+    private Integer writeRelativeHeadRowIndex;
 
     /**
      * current table param
      */
-    private Table currentTableParam;
-
-    public Table getCurrentTableParam() {
-        return currentTableParam;
-    }
-
-    public void setCurrentTableParam(Table currentTableParam) {
-        this.currentTableParam = currentTableParam;
-    }
+    private com.alibaba.excel.metadata.Table tableParam;
+    /**
+     * Record whether it's new or from cache
+     */
+    private Boolean newInitialization;
 
     public SheetHolder getParentSheet() {
         return parentSheet;
@@ -49,6 +60,38 @@ public class TableHolder implements ConfigurationSelector{
         this.parentSheet = parentSheet;
     }
 
+    public Integer getTableNo() {
+        return tableNo;
+    }
+
+    public void setTableNo(Integer tableNo) {
+        this.tableNo = tableNo;
+    }
+
+    public Boolean getNeedHead() {
+        return needHead;
+    }
+
+    public void setNeedHead(Boolean needHead) {
+        this.needHead = needHead;
+    }
+
+    public List<WriteHandler> getWriteHandlerList() {
+        return writeHandlerList;
+    }
+
+    public void setWriteHandlerList(List<WriteHandler> writeHandlerList) {
+        this.writeHandlerList = writeHandlerList;
+    }
+
+    public Map<Class, Converter> getConverterMap() {
+        return converterMap;
+    }
+
+    public void setConverterMap(Map<Class, Converter> converterMap) {
+        this.converterMap = converterMap;
+    }
+
     public ExcelHeadProperty getExcelHeadProperty() {
         return excelHeadProperty;
     }
@@ -57,35 +100,57 @@ public class TableHolder implements ConfigurationSelector{
         this.excelHeadProperty = excelHeadProperty;
     }
 
-    public CellStyleStrategy getCellStyleStrategy() {
-        return cellStyleStrategy;
+    public Integer getWriteRelativeHeadRowIndex() {
+        return writeRelativeHeadRowIndex;
     }
 
-    public void setCellStyleStrategy(CellStyleStrategy cellStyleStrategy) {
-        this.cellStyleStrategy = cellStyleStrategy;
+    public void setWriteRelativeHeadRowIndex(Integer writeRelativeHeadRowIndex) {
+        this.writeRelativeHeadRowIndex = writeRelativeHeadRowIndex;
     }
 
-    public ColumnWidthStyleStrategy getColumnWidthStyleStrategy() {
-        return columnWidthStyleStrategy;
+    public Table getTableParam() {
+        return tableParam;
     }
 
-    public void setColumnWidthStyleStrategy(ColumnWidthStyleStrategy columnWidthStyleStrategy) {
-        this.columnWidthStyleStrategy = columnWidthStyleStrategy;
+    public void setTableParam(Table tableParam) {
+        this.tableParam = tableParam;
     }
 
-    public RowHighStyleStrategy getRowHighStyleStrategy() {
-        return rowHighStyleStrategy;
+    public Boolean getNewInitialization() {
+        return newInitialization;
     }
 
-    public void setRowHighStyleStrategy(RowHighStyleStrategy rowHighStyleStrategy) {
-        this.rowHighStyleStrategy = rowHighStyleStrategy;
+    public void setNewInitialization(Boolean newInitialization) {
+        this.newInitialization = newInitialization;
     }
 
-    public boolean isNeedHead() {
-        return needHead;
+    @Override
+    public List<WriteHandler> writeHandlerList() {
+        return getWriteHandlerList();
     }
 
-    public void setNeedHead(boolean needHead) {
-        this.needHead = needHead;
+    @Override
+    public Map<Class, Converter> converterMap() {
+        return getConverterMap();
+    }
+
+    @Override
+    public boolean needHead() {
+        return getNeedHead();
+    }
+
+    @Override
+    public int writeRelativeHeadRowIndex() {
+        return getWriteRelativeHeadRowIndex();
+    }
+
+    @Override
+    public ExcelHeadProperty excelHeadProperty() {
+        return getExcelHeadProperty();
+    }
+
+    @Override
+    public boolean isNew() {
+        return getNewInitialization();
     }
 }
diff --git a/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java b/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java
index 209db631..fdecf03b 100644
--- a/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java
+++ b/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java
@@ -1,11 +1,14 @@
 package com.alibaba.excel.metadata.holder;
 
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.poi.ss.usermodel.Workbook;
 
 import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.metadata.ExcelHeadProperty;
 import com.alibaba.excel.write.handler.WriteHandler;
 
 /**
@@ -34,6 +37,22 @@ public class WorkbookHolder implements ConfigurationSelector {
      * prevent duplicate creation of sheet objects
      */
     private Map<Integer, SheetHolder> hasBeenInitializedSheet;
+    /**
+     * Writes the head relative to the existing contents of the sheet. Indexes are zero-based.
+     */
+    private Integer writeRelativeHeadRowIndex;
+    /**
+     * current param
+     */
+    private com.alibaba.excel.metadata.Workbook workbookParam;
+    /**
+     * Final output stream
+     */
+    private OutputStream outputStream;
+    /**
+     * Template input stream
+     */
+    private InputStream templateInputStream;
 
     public Workbook getWorkbook() {
         return workbook;
@@ -75,6 +94,38 @@ public class WorkbookHolder implements ConfigurationSelector {
         this.hasBeenInitializedSheet = hasBeenInitializedSheet;
     }
 
+    public Integer getWriteRelativeHeadRowIndex() {
+        return writeRelativeHeadRowIndex;
+    }
+
+    public void setWriteRelativeHeadRowIndex(Integer writeRelativeHeadRowIndex) {
+        this.writeRelativeHeadRowIndex = writeRelativeHeadRowIndex;
+    }
+
+    public com.alibaba.excel.metadata.Workbook getWorkbookParam() {
+        return workbookParam;
+    }
+
+    public void setWorkbookParam(com.alibaba.excel.metadata.Workbook workbookParam) {
+        this.workbookParam = workbookParam;
+    }
+
+    public OutputStream getOutputStream() {
+        return outputStream;
+    }
+
+    public void setOutputStream(OutputStream outputStream) {
+        this.outputStream = outputStream;
+    }
+
+    public InputStream getTemplateInputStream() {
+        return templateInputStream;
+    }
+
+    public void setTemplateInputStream(InputStream templateInputStream) {
+        this.templateInputStream = templateInputStream;
+    }
+
     @Override
     public List<WriteHandler> writeHandlerList() {
         return getWriteHandlerList();
@@ -89,4 +140,19 @@ public class WorkbookHolder implements ConfigurationSelector {
     public boolean needHead() {
         return getNeedHead();
     }
+
+    @Override
+    public int writeRelativeHeadRowIndex() {
+        return getWriteRelativeHeadRowIndex();
+    }
+
+    @Override
+    public ExcelHeadProperty excelHeadProperty() {
+        return null;
+    }
+
+    @Override
+    public boolean isNew() {
+        return true;
+    }
 }
diff --git a/src/main/java/com/alibaba/excel/parameter/GenerateParam.java b/src/main/java/com/alibaba/excel/parameter/GenerateParam.java
index a98ad712..0760007e 100644
--- a/src/main/java/com/alibaba/excel/parameter/GenerateParam.java
+++ b/src/main/java/com/alibaba/excel/parameter/GenerateParam.java
@@ -6,7 +6,10 @@ import com.alibaba.excel.support.ExcelTypeEnum;
 
 /**
  * Created by jipengfei on 17/2/19.
+ * 
+ * @deprecated please use {@link com.alibaba.excel.write.builder.ExcelWriterBuilder} build ExcelWriter
  */
+@Deprecated
 public class GenerateParam {
 
     private OutputStream outputStream;
@@ -33,7 +36,6 @@ public class GenerateParam {
         this.outputStream = outputStream;
     }
 
-
     public String getSheetName() {
         return sheetName;
     }
diff --git a/src/main/java/com/alibaba/excel/util/StyleUtil.java b/src/main/java/com/alibaba/excel/util/StyleUtil.java
index c4faa124..9a864ac4 100644
--- a/src/main/java/com/alibaba/excel/util/StyleUtil.java
+++ b/src/main/java/com/alibaba/excel/util/StyleUtil.java
@@ -37,6 +37,21 @@ public class StyleUtil {
         return newCellStyle;
     }
 
+    /**
+     * Build style
+     * 
+     * @param workbook
+     * @param cs
+     * @return
+     */
+    public static CellStyle buildHeadCellStyle(Workbook workbook, com.alibaba.excel.metadata.CellStyle cs) {
+        CellStyle cellStyle = workbook.createCellStyle();
+        if (cs == null) {
+            return cellStyle;
+        }
+        return buildCellStyle(workbook, cellStyle, cs.getFont(), cs.getIndexedColors());
+    }
+
     /**
      *
      * @param workbook
@@ -50,6 +65,21 @@ public class StyleUtil {
         return buildCellStyle(workbook, cellStyle, f, indexedColors);
     }
 
+    /**
+     * Build style
+     *
+     * @param workbook
+     * @param cs
+     * @return
+     */
+    public static CellStyle buildContentCellStyle(Workbook workbook, com.alibaba.excel.metadata.CellStyle cs) {
+        CellStyle cellStyle = buildDefaultCellStyle(workbook);
+        if (cs == null) {
+            return cellStyle;
+        }
+        return buildCellStyle(workbook, cellStyle, cs.getFont(), cs.getIndexedColors());
+    }
+
     /**
      *
      * @param workbook
diff --git a/src/main/java/com/alibaba/excel/util/WorkBookUtil.java b/src/main/java/com/alibaba/excel/util/WorkBookUtil.java
index e97a4ff4..987972b6 100644
--- a/src/main/java/com/alibaba/excel/util/WorkBookUtil.java
+++ b/src/main/java/com/alibaba/excel/util/WorkBookUtil.java
@@ -1,16 +1,18 @@
 package com.alibaba.excel.util;
 
-import com.alibaba.excel.support.ExcelTypeEnum;
+import java.io.IOException;
+
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
-import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.xssf.streaming.SXSSFWorkbook;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
-import java.io.IOException;
-import java.io.InputStream;
-
-import static com.alibaba.excel.util.StyleUtil.buildSheetStyle;
+import com.alibaba.excel.support.ExcelTypeEnum;
 
 /**
  * 
@@ -18,19 +20,18 @@ import static com.alibaba.excel.util.StyleUtil.buildSheetStyle;
  */
 public class WorkBookUtil {
 
-    public static Workbook createWorkBook(InputStream templateInputStream, ExcelTypeEnum excelType) throws IOException {
+    public static Workbook createWorkBook(com.alibaba.excel.metadata.Workbook workbookParam) throws IOException {
         Workbook workbook;
-        if (ExcelTypeEnum.XLS.equals(excelType)) {
-            workbook = (templateInputStream == null) ? new HSSFWorkbook() : new HSSFWorkbook(
-                new POIFSFileSystem(templateInputStream));
+        if (ExcelTypeEnum.XLS.equals(workbookParam.getExcelType())) {
+            workbook = (workbookParam.getTemplateInputStream() == null) ? new HSSFWorkbook()
+                : new HSSFWorkbook(new POIFSFileSystem(workbookParam.getTemplateInputStream()));
         } else {
-            workbook = (templateInputStream == null) ? new SXSSFWorkbook(500) : new SXSSFWorkbook(
-                new XSSFWorkbook(templateInputStream));
+            workbook = (workbookParam.getTemplateInputStream() == null) ? new SXSSFWorkbook(500)
+                : new SXSSFWorkbook(new XSSFWorkbook(workbookParam.getTemplateInputStream()));
         }
         return workbook;
     }
 
-
     public static Sheet createSheet(Workbook workbook, com.alibaba.excel.metadata.Sheet sheet) {
         return workbook.createSheet(sheet.getSheetName() != null ? sheet.getSheetName() : sheet.getSheetNo() + "");
     }
@@ -38,13 +39,13 @@ public class WorkBookUtil {
     public static Row createRow(Sheet sheet, int rowNum) {
         return sheet.createRow(rowNum);
     }
-    
+
     public static Cell createCell(Row row, int colNum, CellStyle cellStyle) {
         Cell cell = row.createCell(colNum);
         cell.setCellStyle(cellStyle);
         return cell;
     }
-    
+
     public static Cell createCell(Row row, int colNum, CellStyle cellStyle, String cellValue) {
         Cell cell = createCell(row, colNum, cellStyle);
         cell.setCellValue(cellValue);
diff --git a/src/main/java/com/alibaba/excel/write/ExcelBuilder.java b/src/main/java/com/alibaba/excel/write/ExcelBuilder.java
index ddb20c34..28e09731 100644
--- a/src/main/java/com/alibaba/excel/write/ExcelBuilder.java
+++ b/src/main/java/com/alibaba/excel/write/ExcelBuilder.java
@@ -4,6 +4,7 @@ import java.util.List;
 
 import com.alibaba.excel.metadata.Sheet;
 import com.alibaba.excel.metadata.Table;
+import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy;
 
 /**
  * @author jipengfei
@@ -13,27 +14,39 @@ public interface ExcelBuilder {
     /**
      * WorkBook increase value
      *
-     * @param data       java basic type or java model extend BaseModel
-     * @param sheetParam Write the sheet
+     * @param data
+     *            java basic type or java model extend BaseModel
+     * @param sheetParam
+     *            Write the sheet
+     * @deprecated please use{@link ExcelBuilder#addContent(List, Sheet, Table)}
      */
+    @Deprecated
     void addContent(List data, Sheet sheetParam);
 
     /**
      * WorkBook increase value
      *
-     * @param data       java basic type or java model extend BaseModel
-     * @param sheetParam Write the sheet
-     * @param table      Write the table
+     * @param data
+     *            java basic type or java model extend BaseModel
+     * @param sheetParam
+     *            Write the sheet
+     * @param table
+     *            Write the table
      */
     void addContent(List data, Sheet sheetParam, Table table);
 
     /**
      * Creates new cell range. Indexes are zero-based.
      *
-     * @param firstRow Index of first row
-     * @param lastRow  Index of last row (inclusive), must be equal to or larger than {@code firstRow}
-     * @param firstCol Index of first column
-     * @param lastCol  Index of last column (inclusive), must be equal to or larger than {@code firstCol}
+     * @param firstRow
+     *            Index of first row
+     * @param lastRow
+     *            Index of last row (inclusive), must be equal to or larger than {@code firstRow}
+     * @param firstCol
+     *            Index of first column
+     * @param lastCol
+     *            Index of last column (inclusive), must be equal to or larger than {@code firstCol}
+     * @deprecated please use{@link OnceAbsoluteMergeStrategy}
      */
     @Deprecated
     void merge(int firstRow, int lastRow, int firstCol, int lastCol);
diff --git a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
index a520732a..5ac5bf40 100644
--- a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
+++ b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
@@ -1,28 +1,23 @@
 package com.alibaba.excel.write;
 
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.util.List;
-import java.util.Map;
 
 import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.CellStyle;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.util.CellRangeAddress;
 
 import com.alibaba.excel.context.WriteContext;
 import com.alibaba.excel.context.WriteContextImpl;
 import com.alibaba.excel.converters.Converter;
-import com.alibaba.excel.metadata.BaseRowModel;
+import com.alibaba.excel.exception.ExcelDataConvertException;
 import com.alibaba.excel.metadata.CellData;
 import com.alibaba.excel.metadata.ExcelColumnProperty;
 import com.alibaba.excel.metadata.Sheet;
 import com.alibaba.excel.metadata.Table;
-import com.alibaba.excel.support.ExcelTypeEnum;
+import com.alibaba.excel.metadata.holder.ConfigurationSelector;
 import com.alibaba.excel.util.CollectionUtils;
 import com.alibaba.excel.util.POITempFile;
 import com.alibaba.excel.util.WorkBookUtil;
-import com.alibaba.excel.write.handler.WriteHandler;
 
 import net.sf.cglib.beans.BeanMap;
 
@@ -33,29 +28,20 @@ public class ExcelBuilderImpl implements ExcelBuilder {
 
     private WriteContext context;
 
-    public ExcelBuilderImpl(InputStream templateInputStream, OutputStream out, ExcelTypeEnum excelType,
-        boolean needHead, Map<Class, Converter> customConverterMap, List<WriteHandler> customWriteHandlerList) {
+    public ExcelBuilderImpl(com.alibaba.excel.metadata.Workbook workbook) {
         // 初始化时候创建临时缓存目录,用于规避POI在并发写bug
         POITempFile.createPOIFilesDirectory();
-        context = new WriteContextImpl(templateInputStream, out, excelType, needHead, customConverterMap,
-            customWriteHandlerList);
+        context = new WriteContextImpl(workbook);
     }
 
-    private void doAddContent(List data, int startRow) {
+    private void doAddContent(List data) {
         if (CollectionUtils.isEmpty(data)) {
             return;
         }
-        int rowNum = context.getCurrentSheet().getLastRowNum();
-        if (rowNum == 0) {
-            Row row = context.getCurrentSheet().getRow(0);
-            if (row == null) {
-                if (context.getExcelHeadProperty() == null || !context.needHead()) {
-                    rowNum = -1;
-                }
-            }
-        }
-        if (rowNum < startRow) {
-            rowNum = startRow;
+        org.apache.poi.ss.usermodel.Sheet currentSheet = context.currentSheetHolder().getSheet();
+        int rowNum = currentSheet.getLastRowNum();
+        if (context.currentConfigurationSelector().isNew()) {
+            rowNum += context.currentConfigurationSelector().writeRelativeHeadRowIndex();
         }
         for (int i = 0; i < data.size(); i++) {
             int n = i + rowNum + 1;
@@ -65,15 +51,14 @@ public class ExcelBuilderImpl implements ExcelBuilder {
 
     @Override
     public void addContent(List data, Sheet sheetParam) {
-        context.currentSheet(sheetParam);
-        doAddContent(data, sheetParam.getWriteRelativeHeadRowIndex());
+        addContent(data, sheetParam, null);
     }
 
     @Override
     public void addContent(List data, Sheet sheetParam, Table table) {
         context.currentSheet(sheetParam);
         context.currentTable(table);
-        doAddContent(data, sheetParam.getWriteRelativeHeadRowIndex());
+        doAddContent(data);
     }
 
     @Override
@@ -84,7 +69,16 @@ public class ExcelBuilderImpl implements ExcelBuilder {
     @Override
     public void merge(int firstRow, int lastRow, int firstCol, int lastCol) {
         CellRangeAddress cra = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
-        context.getCurrentSheet().addMergedRegion(cra);
+        context.currentSheetHolder().getSheet().addMergedRegion(cra);
+    }
+
+    private void addOneRowOfDataToExcel(Object oneRowData, int n) {
+        Row row = WorkBookUtil.createRow(context.currentSheetHolder().getSheet(), n);
+        if (oneRowData instanceof List) {
+            addBasicTypeToExcel((List)oneRowData, row);
+        } else {
+            addJavaObjectToExcel(oneRowData, row);
+        }
     }
 
     private void addBasicTypeToExcel(List<Object> oneRowData, Row row) {
@@ -92,57 +86,61 @@ public class ExcelBuilderImpl implements ExcelBuilder {
             return;
         }
         for (int i = 0; i < oneRowData.size(); i++) {
-            Object cellValue = oneRowData.get(i);
-            Cell cell = WorkBookUtil.createCell(row, i, context.getCurrentContentStyle());
-            cell = convertValue(cell, cellValue, null);
-            if (null != context.getWriteHandler()) {
-                context.getWriteHandler().cell(i, cell);
-            }
+            Cell cell = WorkBookUtil.createCell(row, i, null);
+            Object value = oneRowData.get(i);
+            converterAndSet(context.currentConfigurationSelector(), value.getClass(), cell, value, null);
         }
     }
 
     private void addJavaObjectToExcel(Object oneRowData, Row row) {
+        ConfigurationSelector currentConfigurationSelector = context.currentConfigurationSelector();
         int i = 0;
         BeanMap beanMap = BeanMap.create(oneRowData);
-        for (ExcelColumnProperty excelHeadProperty : context.getExcelHeadProperty().getColumnPropertyList()) {
-            BaseRowModel baseRowModel = (BaseRowModel)oneRowData;
-            CellStyle cellStyle =
-                baseRowModel.getStyle(i) != null ? baseRowModel.getStyle(i) : context.getCurrentContentStyle();
+        for (ExcelColumnProperty excelHeadProperty : currentConfigurationSelector.excelHeadProperty()
+            .getColumnPropertyList()) {
+            Cell cell = WorkBookUtil.createCell(row, i, null);
             Object value = beanMap.get(excelHeadProperty.getField().getName());
-            // excelHeadProperty.getField().getType();
-
-            Cell cell = WorkBookUtil.createCell(row, i, cellStyle);
-            cell.setCL cell = convertValue(cell, value, excelHeadProperty);
-            if (null != context.getWriteHandler()) {
-                context.getWriteHandler().cell(i, cell);
-            }
+            converterAndSet(currentConfigurationSelector, excelHeadProperty.getField().getType(), cell, value,
+                excelHeadProperty);
             i++;
         }
     }
 
-    private Cell convertValue(Cell cell, Object value, ExcelColumnProperty excelHeadProperty) {
-        if (!CollectionUtils.isEmpty(this.converters)) {
-            for (Converter c : this.converters) {
-              CellData c.convertToExcelData(excelHeadProperty);
-
-                if (value != null && c.support(value)) {
-                    return c.convert(cell, value, excelHeadProperty);
-                }
-            }
+    private void converterAndSet(ConfigurationSelector currentConfigurationSelector, Class clazz, Cell cell,
+        Object value, ExcelColumnProperty excelHeadProperty) {
+        if (value == null) {
+            return;
+        }
+        Converter converter = currentConfigurationSelector.converterMap().get(excelHeadProperty.getField().getType());
+        if (converter == null) {
+            throw new ExcelDataConvertException(
+                "Can not find 'Converter' support class " + clazz.getSimpleName() + ".");
         }
-        return cell;
-    }
 
-    private void addOneRowOfDataToExcel(Object oneRowData, int n) {
-        Row row = WorkBookUtil.createRow(context.getCurrentSheet(), n);
-        if (null != context.getWriteHandler()) {
-            context.getWriteHandler().row(n, row);
+        CellData cellData = null;
+        try {
+            cellData = converter.convertToExcelData(value, excelHeadProperty);
+        } catch (Exception e) {
+            throw new ExcelDataConvertException("Convert data:" + value + " error,at row:" + cell.getRow().getRowNum(),
+                e);
         }
-        if (oneRowData instanceof List) {
-            addBasicTypeToExcel((List)oneRowData, row);
-        } else {
-            addJavaObjectToExcel(oneRowData, row);
+        if (cellData == null || cellData.getType() == null) {
+            throw new ExcelDataConvertException(
+                "Convert data:" + value + " return null,at row:" + cell.getRow().getRowNum());
+        }
+        switch (cellData.getType()) {
+            case STRING:
+                cell.setCellValue(cell.getStringCellValue());
+                return;
+            case BOOLEAN:
+                cell.setCellValue(cell.getBooleanCellValue());
+                return;
+            case NUMBER:
+                cell.setCellValue(cell.getNumericCellValue());
+                return;
+            default:
+                throw new ExcelDataConvertException("Not supported data:" + value + " return type:" + cell.getCellType()
+                    + "at row:" + cell.getRow().getRowNum());
         }
     }
-
 }
diff --git a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java
index 20ecc322..09cbb0da 100644
--- a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java
+++ b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java
@@ -108,8 +108,8 @@ public class ExcelWriterBuilder {
         return this;
     }
 
-    public ExcelWriterBuilder registerWriteHandler(WriteHandler excelWriteHandler) {
-        this.customWriteHandlerList.add(excelWriteHandler);
+    public ExcelWriterBuilder registerWriteHandler(WriteHandler writeHandler) {
+        this.customWriteHandlerList.add(writeHandler);
         return this;
     }
 
diff --git a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java
new file mode 100644
index 00000000..e99baa14
--- /dev/null
+++ b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java
@@ -0,0 +1,120 @@
+package com.alibaba.excel.write.builder;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import com.alibaba.excel.write.handler.WriteHandler;
+
+/**
+ * Build sheet
+ * 
+ * @author zhuangjiaju
+ */
+public class ExcelWriterSheetBuilder {
+    /**
+     * Excel type
+     */
+    private ExcelTypeEnum excelType;
+    /**
+     * Final output stream
+     */
+    private OutputStream outputStream;
+    /**
+     * Template input stream
+     */
+    private InputStream templateInputStream;
+    /**
+     * Custom type conversions override the default
+     */
+    private Map<Class, Converter> customConverterMap = new HashMap<Class, Converter>();
+    /**
+     * Need Head
+     */
+    private Boolean needHead;
+    /**
+     * Custom type handler override the default
+     */
+    private List<WriteHandler> customWriteHandlerList = new ArrayList<WriteHandler>();
+
+    public ExcelWriterSheetBuilder excelType(ExcelTypeEnum excelType) {
+        this.excelType = excelType;
+        return this;
+    }
+
+    public ExcelWriterSheetBuilder outputFile(OutputStream outputStream) {
+        this.outputStream = outputStream;
+        return this;
+    }
+
+    public ExcelWriterSheetBuilder outputFile(File outputFile) throws FileNotFoundException {
+        return outputFile(new FileOutputStream(outputFile));
+    }
+
+    public ExcelWriterSheetBuilder outputFile(String outputPathName) throws FileNotFoundException {
+        return outputFile(new File(outputPathName));
+    }
+
+    public ExcelWriterSheetBuilder outputFile(URI outputUri) throws FileNotFoundException {
+        return outputFile(new File(outputUri));
+    }
+
+    public ExcelWriterSheetBuilder withTemplate(InputStream templateInputStream) {
+        this.templateInputStream = templateInputStream;
+        return this;
+    }
+
+    public ExcelWriterSheetBuilder withTemplate(File templateFile) throws FileNotFoundException {
+        return withTemplate(new FileInputStream(templateFile));
+    }
+
+    public ExcelWriterSheetBuilder withTemplate(String templatePathName) throws FileNotFoundException {
+        return withTemplate(new File(templatePathName));
+    }
+
+    public ExcelWriterSheetBuilder withTemplate(URI templateUri) throws FileNotFoundException {
+        return withTemplate(new File(templateUri));
+    }
+
+    /**
+     * Custom type conversions override the default.
+     * 
+     * @param converter
+     * @return
+     */
+    public ExcelWriterSheetBuilder registerConverter(Converter converter) {
+        this.customConverterMap.put(converter.supportJavaTypeKey(), converter);
+        return this;
+    }
+
+    /**
+     * Default required header
+     * 
+     * @return
+     */
+    public ExcelWriterSheetBuilder doNotNeedHead() {
+        this.needHead = Boolean.FALSE;
+        return this;
+    }
+
+    public ExcelWriterSheetBuilder registerWriteHandler(WriteHandler writeHandler) {
+        this.customWriteHandlerList.add(writeHandler);
+        return this;
+    }
+
+    public ExcelWriter build() {
+        return new ExcelWriter(templateInputStream, outputStream, excelType, needHead, customConverterMap,
+            customWriteHandlerList);
+    }
+}
diff --git a/src/main/java/com/alibaba/excel/write/handler/WookbookExcelWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/WookbookExcelWriteHandler.java
deleted file mode 100644
index 1441747b..00000000
--- a/src/main/java/com/alibaba/excel/write/handler/WookbookExcelWriteHandler.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.alibaba.excel.write.handler;
-
-import org.apache.poi.ss.usermodel.Workbook;
-
-/**
- * intercepts handle Wookbook creation
- * 
- * @author zhuangjiaju
- */
-public interface WookbookExcelWriteHandler extends ExcelWriteHandler {
-
-    /**
-     * called before create the sheet
-     * 
-     * @param writeContext
-     */
-    void beforeWookbookCreate();
-
-    /**
-     * called after the sheet is created
-     *
-     * @param writeContext
-     */
-    void afterWookbookCreate(Workbook workbook);
-}
diff --git a/src/main/java/com/alibaba/excel/write/style/AbstractColumnCellStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/AbstractColumnCellStyleStrategy.java
index a257e43e..5a842660 100644
--- a/src/main/java/com/alibaba/excel/write/style/AbstractColumnCellStyleStrategy.java
+++ b/src/main/java/com/alibaba/excel/write/style/AbstractColumnCellStyleStrategy.java
@@ -33,7 +33,7 @@ public abstract class AbstractColumnCellStyleStrategy extends AbstractCellStyleS
         if (headCellStyleCache.containsKey(columnIndex)) {
             cell.setCellStyle(headCellStyleCache.get(columnIndex));
         }
-        CellStyle cellStyle = StyleUtil.buildCellStyle(workbook, headCellStyle(head));
+        CellStyle cellStyle = StyleUtil.buildHeadCellStyle(workbook, headCellStyle(head));
         headCellStyleCache.put(columnIndex, cellStyle);
         cell.setCellStyle(cellStyle);
     }
@@ -44,7 +44,7 @@ public abstract class AbstractColumnCellStyleStrategy extends AbstractCellStyleS
         if (contentCellStyleCache.containsKey(columnIndex)) {
             cell.setCellStyle(contentCellStyleCache.get(columnIndex));
         }
-        CellStyle cellStyle = StyleUtil.buildCellStyle(workbook, contentCellStyle(head));
+        CellStyle cellStyle = StyleUtil.buildContentCellStyle(workbook, contentCellStyle(head));
         contentCellStyleCache.put(columnIndex, cellStyle);
         cell.setCellStyle(cellStyle);
     }
diff --git a/src/main/java/com/alibaba/excel/write/style/RowCellStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/RowCellStyleStrategy.java
index 4778a1b0..3ae5d89b 100644
--- a/src/main/java/com/alibaba/excel/write/style/RowCellStyleStrategy.java
+++ b/src/main/java/com/alibaba/excel/write/style/RowCellStyleStrategy.java
@@ -38,12 +38,12 @@ public class RowCellStyleStrategy extends AbstractCellStyleStrategy {
     @Override
     protected void initCellStyle(Workbook workbook) {
         if (headCellStyle != null) {
-            poiHeadCellStyle = StyleUtil.buildCellStyle(workbook, headCellStyle);
+            poiHeadCellStyle = StyleUtil.buildHeadCellStyle(workbook, headCellStyle);
         }
         if (contentCellStyleList != null && !contentCellStyleList.isEmpty()) {
             poiContentCellStyleList = new ArrayList<org.apache.poi.ss.usermodel.CellStyle>();
             for (CellStyle cellStyle : contentCellStyleList) {
-                poiContentCellStyleList.add(StyleUtil.buildCellStyle(workbook, cellStyle));
+                poiContentCellStyleList.add(StyleUtil.buildContentCellStyle(workbook, cellStyle));
             }
         }
     }
diff --git a/src/test/java/com/alibaba/easyexcel/test/ReadTest.java b/src/test/java/com/alibaba/easyexcel/test/ReadTest.java
index e2293286..f92fedeb 100644
--- a/src/test/java/com/alibaba/easyexcel/test/ReadTest.java
+++ b/src/test/java/com/alibaba/easyexcel/test/ReadTest.java
@@ -161,13 +161,13 @@ public class ReadTest {
     public void saxReadSheetsV2003() throws IOException {
         InputStream inputStream = FileUtil.getResourcesFileInputStream("2003.xls");
         ExcelListener excelListener = new ExcelListener();
-        ExcelReader excelReader = EasyExcelFactory.getReader(inputStream, excelListener);
+        ExcelReader excelReader = EasyExcelFactory.getReader(inputStream,excelListener);
         List<Sheet> sheets = excelReader.getSheets();
         System.out.println();
-        for (Sheet sheet : sheets) {
-            if (sheet.getSheetNo() == 1) {
+        for (Sheet sheet:sheets) {
+            if(sheet.getSheetNo() == 1) {
                 excelReader.read(sheet);
-            } else {
+            }else {
                 sheet.setHeadLineMun(2);
                 sheet.setClazz(ReadModel.class);
                 excelReader.read(sheet);
diff --git a/src/test/java/com/alibaba/easyexcel/test/WriteTest.java b/src/test/java/com/alibaba/easyexcel/test/WriteTest.java
index 074c584d..86d7214c 100644
--- a/src/test/java/com/alibaba/easyexcel/test/WriteTest.java
+++ b/src/test/java/com/alibaba/easyexcel/test/WriteTest.java
@@ -1,23 +1,6 @@
 package com.alibaba.easyexcel.test;
 
-import static com.alibaba.easyexcel.test.util.DataUtil.createTableStyle;
-import static com.alibaba.easyexcel.test.util.DataUtil.createTestListJavaMode;
-import static com.alibaba.easyexcel.test.util.DataUtil.createTestListObject;
-import static com.alibaba.easyexcel.test.util.DataUtil.createTestListStringHead;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.junit.Test;
-
-import com.alibaba.easyexcel.test.listen.AfterWriteHandlerImpl;
+import com.alibaba.easyexcel.test.listen.AfterExcelWriteHandlerImpl;
 import com.alibaba.easyexcel.test.model.WriteModel;
 import com.alibaba.easyexcel.test.util.FileUtil;
 import com.alibaba.excel.EasyExcelFactory;
@@ -25,69 +8,49 @@ import com.alibaba.excel.ExcelWriter;
 import com.alibaba.excel.metadata.Sheet;
 import com.alibaba.excel.metadata.Table;
 import com.alibaba.excel.support.ExcelTypeEnum;
-import com.alibaba.excel.write.merge.MergeStrategy;
+import org.junit.Test;
+
+import java.io.*;
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.alibaba.easyexcel.test.util.DataUtil.*;
 
 public class WriteTest {
 
     @Test
     public void writeV2007() throws IOException {
-        OutputStream out = new FileOutputStream(new File(FileUtil.getPath(), "write_2007"+System.currentTimeMillis()+".xlsx"));
+        OutputStream out = new FileOutputStream("/Users/jipengfei/2007.xlsx");
         ExcelWriter writer = EasyExcelFactory.getWriter(out);
-        // 写第一个sheet, sheet1 数据全是List<String> 无模型映射关系
+        //写第一个sheet, sheet1  数据全是List<String> 无模型映射关系
         Sheet sheet1 = new Sheet(1, 3);
         sheet1.setSheetName("第一个sheet");
 
-        // 设置列宽 设置每列的宽度
+        //设置列宽 设置每列的宽度
         Map columnWidth = new HashMap();
-        columnWidth.put(0, 10000);
-        columnWidth.put(1, 40000);
-        columnWidth.put(2, 10000);
-        columnWidth.put(3, 10000);
+        columnWidth.put(0,10000);columnWidth.put(1,40000);columnWidth.put(2,10000);columnWidth.put(3,10000);
         sheet1.setColumnWidthMap(columnWidth);
         sheet1.setHead(createTestListStringHead());
-        // or 设置自适应宽度
-        // sheet1.setAutoWidth(Boolean.TRUE);
+        //or 设置自适应宽度
+        //sheet1.setAutoWidth(Boolean.TRUE);
         writer.write1(createTestListObject(), sheet1);
 
-        // 写第二个sheet sheet2 模型上打有表头的注解,合并单元格
+        //写第二个sheet sheet2  模型上打有表头的注解,合并单元格
         Sheet sheet2 = new Sheet(2, 3, WriteModel.class, "第二个sheet", null);
         sheet2.setTableStyle(createTableStyle());
-        // writer.write1(null, sheet2);
+        //writer.write1(null, sheet2);
         writer.write(createTestListJavaMode(), sheet2);
-        List<MergeStrategy> strategies = new ArrayList<MergeStrategy>();
-        strategies.add(new MergeStrategy() {
-            @Override
-            public int getFirstRow() {
-                return 5;
-            }
-
-            @Override
-            public int getLastRow() {
-                return 20;
-            }
-
-            @Override
-            public int getFirstCol() {
-                return 1;
-            }
-
-            @Override
-            public int getLastCol() {
-                return 1;
-            }
-
-        });
-        // 需要合并单元格
-        writer.merge(strategies);
-
-        // 写第三个sheet包含多个table情况
+        //需要合并单元格
+        writer.merge(5,20,1,1);
+
+        //写第三个sheet包含多个table情况
         Sheet sheet3 = new Sheet(3, 0);
         sheet3.setSheetName("第三个sheet");
         Table table1 = new Table(1);
         table1.setHead(createTestListStringHead());
         writer.write1(createTestListObject(), sheet3, table1);
 
-        // 写sheet2 模型上打有表头的注解
+        //写sheet2  模型上打有表头的注解
         Table table2 = new Table(2);
         table2.setTableStyle(createTableStyle());
         table2.setClazz(WriteModel.class);
@@ -102,32 +65,29 @@ public class WriteTest {
     @Test
     public void writeV2007WithTemplate() throws IOException {
         InputStream inputStream = FileUtil.getResourcesFileInputStream("temp.xlsx");
-        OutputStream out = new FileOutputStream(new File(FileUtil.getPath(), "write_2007_1.xlsx"));
-        ExcelWriter writer = EasyExcelFactory.getWriterWithTemp(inputStream, out, ExcelTypeEnum.XLSX, true);
-        // 写第一个sheet, sheet1 数据全是List<String> 无模型映射关系
+        OutputStream out = new FileOutputStream("/Users/jipengfei/2007.xlsx");
+        ExcelWriter writer = EasyExcelFactory.getWriterWithTemp(inputStream,out,ExcelTypeEnum.XLSX,true);
+        //写第一个sheet, sheet1  数据全是List<String> 无模型映射关系
         Sheet sheet1 = new Sheet(1, 3);
         sheet1.setSheetName("第一个sheet");
         sheet1.setStartRow(20);
 
-        // 设置列宽 设置每列的宽度
+        //设置列宽 设置每列的宽度
         Map columnWidth = new HashMap();
-        columnWidth.put(0, 10000);
-        columnWidth.put(1, 40000);
-        columnWidth.put(2, 10000);
-        columnWidth.put(3, 10000);
+        columnWidth.put(0,10000);columnWidth.put(1,40000);columnWidth.put(2,10000);columnWidth.put(3,10000);
         sheet1.setColumnWidthMap(columnWidth);
         sheet1.setHead(createTestListStringHead());
-        // or 设置自适应宽度
-        // sheet1.setAutoWidth(Boolean.TRUE);
+        //or 设置自适应宽度
+        //sheet1.setAutoWidth(Boolean.TRUE);
         writer.write1(createTestListObject(), sheet1);
 
-        // 写第二个sheet sheet2 模型上打有表头的注解,合并单元格
+        //写第二个sheet sheet2  模型上打有表头的注解,合并单元格
         Sheet sheet2 = new Sheet(2, 3, WriteModel.class, "第二个sheet", null);
         sheet2.setTableStyle(createTableStyle());
         sheet2.setStartRow(20);
         writer.write(createTestListJavaMode(), sheet2);
 
-        // 写第三个sheet包含多个table情况
+        //写第三个sheet包含多个table情况
         Sheet sheet3 = new Sheet(3, 0);
         sheet3.setSheetName("第三个sheet");
         sheet3.setStartRow(30);
@@ -135,7 +95,7 @@ public class WriteTest {
         table1.setHead(createTestListStringHead());
         writer.write1(createTestListObject(), sheet3, table1);
 
-        // 写sheet2 模型上打有表头的注解
+        //写sheet2  模型上打有表头的注解
         Table table2 = new Table(2);
         table2.setTableStyle(createTableStyle());
         table2.setClazz(WriteModel.class);
@@ -149,33 +109,30 @@ public class WriteTest {
     @Test
     public void writeV2007WithTemplateAndHandler() throws IOException {
         InputStream inputStream = FileUtil.getResourcesFileInputStream("temp.xlsx");
-        OutputStream out = new FileOutputStream(new File(FileUtil.getPath(), "write_2007_2.xlsx"));
-        ExcelWriter writer = EasyExcelFactory.getWriterWithTempAndHandler(inputStream, out, ExcelTypeEnum.XLSX, true,
-                        new AfterWriteHandlerImpl());
-        // 写第一个sheet, sheet1 数据全是List<String> 无模型映射关系
+        OutputStream out = new FileOutputStream("/Users/jipengfei/2007.xlsx");
+        ExcelWriter writer = EasyExcelFactory.getWriterWithTempAndHandler(inputStream,out,ExcelTypeEnum.XLSX,true,
+            new AfterExcelWriteHandlerImpl());
+        //写第一个sheet, sheet1  数据全是List<String> 无模型映射关系
         Sheet sheet1 = new Sheet(1, 3);
         sheet1.setSheetName("第一个sheet");
         sheet1.setStartRow(20);
 
-        // 设置列宽 设置每列的宽度
+        //设置列宽 设置每列的宽度
         Map columnWidth = new HashMap();
-        columnWidth.put(0, 10000);
-        columnWidth.put(1, 40000);
-        columnWidth.put(2, 10000);
-        columnWidth.put(3, 10000);
+        columnWidth.put(0,10000);columnWidth.put(1,40000);columnWidth.put(2,10000);columnWidth.put(3,10000);
         sheet1.setColumnWidthMap(columnWidth);
         sheet1.setHead(createTestListStringHead());
-        // or 设置自适应宽度
-        // sheet1.setAutoWidth(Boolean.TRUE);
+        //or 设置自适应宽度
+        //sheet1.setAutoWidth(Boolean.TRUE);
         writer.write1(createTestListObject(), sheet1);
 
-        // 写第二个sheet sheet2 模型上打有表头的注解,合并单元格
+        //写第二个sheet sheet2  模型上打有表头的注解,合并单元格
         Sheet sheet2 = new Sheet(2, 3, WriteModel.class, "第二个sheet", null);
         sheet2.setTableStyle(createTableStyle());
         sheet2.setStartRow(20);
         writer.write(createTestListJavaMode(), sheet2);
 
-        // 写第三个sheet包含多个table情况
+        //写第三个sheet包含多个table情况
         Sheet sheet3 = new Sheet(3, 0);
         sheet3.setSheetName("第三个sheet");
         sheet3.setStartRow(30);
@@ -183,7 +140,7 @@ public class WriteTest {
         table1.setHead(createTestListStringHead());
         writer.write1(createTestListObject(), sheet3, table1);
 
-        // 写sheet2 模型上打有表头的注解
+        //写sheet2  模型上打有表头的注解
         Table table2 = new Table(2);
         table2.setTableStyle(createTableStyle());
         table2.setClazz(WriteModel.class);
@@ -198,37 +155,34 @@ public class WriteTest {
 
     @Test
     public void writeV2003() throws IOException {
-        OutputStream out = new FileOutputStream(new File(FileUtil.getPath(), "write_2003.xlsx"));
-        ExcelWriter writer = EasyExcelFactory.getWriter(out, ExcelTypeEnum.XLS, true);
-        // 写第一个sheet, sheet1 数据全是List<String> 无模型映射关系
+        OutputStream out = new FileOutputStream("/Users/jipengfei/2003.xls");
+        ExcelWriter writer = EasyExcelFactory.getWriter(out, ExcelTypeEnum.XLS,true);
+        //写第一个sheet, sheet1  数据全是List<String> 无模型映射关系
         Sheet sheet1 = new Sheet(1, 3);
         sheet1.setSheetName("第一个sheet");
 
-        // 设置列宽 设置每列的宽度
+        //设置列宽 设置每列的宽度
         Map columnWidth = new HashMap();
-        columnWidth.put(0, 10000);
-        columnWidth.put(1, 40000);
-        columnWidth.put(2, 10000);
-        columnWidth.put(3, 10000);
+        columnWidth.put(0,10000);columnWidth.put(1,40000);columnWidth.put(2,10000);columnWidth.put(3,10000);
         sheet1.setColumnWidthMap(columnWidth);
         sheet1.setHead(createTestListStringHead());
-        // or 设置自适应宽度
-        // sheet1.setAutoWidth(Boolean.TRUE);
+        //or 设置自适应宽度
+        //sheet1.setAutoWidth(Boolean.TRUE);
         writer.write1(createTestListObject(), sheet1);
 
-        // 写第二个sheet sheet2 模型上打有表头的注解,合并单元格
+        //写第二个sheet sheet2  模型上打有表头的注解,合并单元格
         Sheet sheet2 = new Sheet(2, 3, WriteModel.class, "第二个sheet", null);
         sheet2.setTableStyle(createTableStyle());
         writer.write(createTestListJavaMode(), sheet2);
 
-        // 写第三个sheet包含多个table情况
+        //写第三个sheet包含多个table情况
         Sheet sheet3 = new Sheet(3, 0);
         sheet3.setSheetName("第三个sheet");
         Table table1 = new Table(1);
         table1.setHead(createTestListStringHead());
         writer.write1(createTestListObject(), sheet3, table1);
 
-        // 写sheet2 模型上打有表头的注解
+        //写sheet2  模型上打有表头的注解
         Table table2 = new Table(2);
         table2.setTableStyle(createTableStyle());
         table2.setClazz(WriteModel.class);
diff --git a/src/test/java/com/alibaba/easyexcel/test/listen/AfterWriteHandlerImpl.java b/src/test/java/com/alibaba/easyexcel/test/listen/AfterExcelWriteHandlerImpl.java
similarity index 97%
rename from src/test/java/com/alibaba/easyexcel/test/listen/AfterWriteHandlerImpl.java
rename to src/test/java/com/alibaba/easyexcel/test/listen/AfterExcelWriteHandlerImpl.java
index fd7c38fb..a83c2827 100644
--- a/src/test/java/com/alibaba/easyexcel/test/listen/AfterWriteHandlerImpl.java
+++ b/src/test/java/com/alibaba/easyexcel/test/listen/AfterExcelWriteHandlerImpl.java
@@ -5,7 +5,7 @@ import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
 import org.apache.poi.xssf.usermodel.XSSFRichTextString;
 
-public class AfterWriteHandlerImpl implements WriteHandler {
+public class AfterExcelWriteHandlerImpl implements WriteHandler {
 
     //
     CellStyle cellStyle;
diff --git a/src/test/java/com/alibaba/easyexcel/test/read/ReadTest.java b/src/test/java/com/alibaba/easyexcel/test/read/ReadTest.java
new file mode 100644
index 00000000..d6ea8670
--- /dev/null
+++ b/src/test/java/com/alibaba/easyexcel/test/read/ReadTest.java
@@ -0,0 +1,189 @@
+package com.alibaba.easyexcel.test.read;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.alibaba.easyexcel.test.listen.ExcelListener;
+import com.alibaba.easyexcel.test.model.ReadModel;
+import com.alibaba.easyexcel.test.model.ReadModel2;
+import com.alibaba.easyexcel.test.util.FileUtil;
+import com.alibaba.excel.EasyExcelFactory;
+import com.alibaba.excel.ExcelReader;
+import com.alibaba.excel.metadata.Sheet;
+
+public class ReadTest {
+
+
+    /**
+     * 07版本excel读数据量少于1千行数据,内部采用回调方法.
+     *
+     * @throws IOException 简单抛出异常,真实环境需要catch异常,同时在finally中关闭流
+     */
+    @Test
+    public void simpleReadListStringV2007() throws IOException {
+        InputStream inputStream = FileUtil.getResourcesFileInputStream("2007.xlsx");
+        List<Object> data = EasyExcelFactory.read(inputStream, new Sheet(1, 0));
+        inputStream.close();
+        print(data);
+    }
+
+
+    /**
+     * 07版本excel读数据量少于1千行数据自动转成javamodel,内部采用回调方法.
+     *
+     * @throws IOException 简单抛出异常,真实环境需要catch异常,同时在finally中关闭流
+     */
+    @Test
+    public void simpleReadJavaModelV2007() throws IOException {
+        InputStream inputStream = FileUtil.getResourcesFileInputStream("2007.xlsx");
+        List<Object> data = EasyExcelFactory.read(inputStream, new Sheet(2, 1, ReadModel.class));
+        inputStream.close();
+        print(data);
+    }
+
+    /**
+     * 07版本excel读数据量大于1千行,内部采用回调方法.
+     *
+     * @throws IOException 简单抛出异常,真实环境需要catch异常,同时在finally中关闭流
+     */
+    @Test
+    public void saxReadListStringV2007() throws IOException {
+        InputStream inputStream = FileUtil.getResourcesFileInputStream("2007.xlsx");
+        ExcelListener excelListener = new ExcelListener();
+        EasyExcelFactory.readBySax(inputStream, new Sheet(1, 1), excelListener);
+        inputStream.close();
+
+    }
+    /**
+     * 07版本excel读数据量大于1千行,内部采用回调方法.
+     *
+     * @throws IOException 简单抛出异常,真实环境需要catch异常,同时在finally中关闭流
+     */
+    @Test
+    public void saxReadJavaModelV2007() throws IOException {
+        InputStream inputStream = FileUtil.getResourcesFileInputStream("2007.xlsx");
+        ExcelListener excelListener = new ExcelListener();
+        EasyExcelFactory.readBySax(inputStream, new Sheet(2, 1, ReadModel.class), excelListener);
+        inputStream.close();
+    }
+
+    /**
+     * 07版本excel读取sheet
+     *
+     * @throws IOException 简单抛出异常,真实环境需要catch异常,同时在finally中关闭流
+     */
+    @Test
+    public void saxReadSheetsV2007() throws IOException {
+        InputStream inputStream = FileUtil.getResourcesFileInputStream("2007.xlsx");
+        ExcelListener excelListener = new ExcelListener();
+        ExcelReader excelReader = EasyExcelFactory.getReader(inputStream,excelListener);
+        List<Sheet> sheets = excelReader.getSheets();
+        System.out.println("llll****"+sheets);
+        System.out.println();
+        for (Sheet sheet:sheets) {
+            if(sheet.getSheetNo() ==1) {
+                excelReader.read(sheet);
+            }else if(sheet.getSheetNo() ==2){
+                sheet.setHeadLineMun(1);
+                sheet.setClazz(ReadModel.class);
+                excelReader.read(sheet);
+            }else if(sheet.getSheetNo() ==3){
+                sheet.setHeadLineMun(1);
+                sheet.setClazz(ReadModel2.class);
+                excelReader.read(sheet);
+            }
+        }
+        inputStream.close();
+    }
+
+
+
+    /**
+     * 03版本excel读数据量少于1千行数据,内部采用回调方法.
+     *
+     * @throws IOException 简单抛出异常,真实环境需要catch异常,同时在finally中关闭流
+     */
+    @Test
+    public void simpleReadListStringV2003() throws IOException {
+        InputStream inputStream = FileUtil.getResourcesFileInputStream("2003.xls");
+        List<Object> data = EasyExcelFactory.read(inputStream, new Sheet(1, 0));
+        inputStream.close();
+        print(data);
+    }
+
+    /**
+     * 03版本excel读数据量少于1千行数据转成javamodel,内部采用回调方法.
+     *
+     * @throws IOException 简单抛出异常,真实环境需要catch异常,同时在finally中关闭流
+     */
+    @Test
+    public void simpleReadJavaModelV2003() throws IOException {
+        InputStream inputStream = FileUtil.getResourcesFileInputStream("2003.xls");
+        List<Object> data = EasyExcelFactory.read(inputStream, new Sheet(2, 1, ReadModel.class));
+        inputStream.close();
+        print(data);
+    }
+
+    /**
+     * 03版本excel读数据量大于1千行数据,内部采用回调方法.
+     *
+     * @throws IOException 简单抛出异常,真实环境需要catch异常,同时在finally中关闭流
+     */
+    @Test
+    public void saxReadListStringV2003() throws IOException {
+        InputStream inputStream = FileUtil.getResourcesFileInputStream("2003.xls");
+        ExcelListener excelListener = new ExcelListener();
+        EasyExcelFactory.readBySax(inputStream, new Sheet(2, 1), excelListener);
+        inputStream.close();
+    }
+
+    /**
+     * 03版本excel读数据量大于1千行数据转成javamodel,内部采用回调方法.
+     *
+     * @throws IOException 简单抛出异常,真实环境需要catch异常,同时在finally中关闭流
+     */
+    @Test
+    public void saxReadJavaModelV2003() throws IOException {
+        InputStream inputStream = FileUtil.getResourcesFileInputStream("2003.xls");
+        ExcelListener excelListener = new ExcelListener();
+        EasyExcelFactory.readBySax(inputStream, new Sheet(2, 1, ReadModel.class), excelListener);
+        inputStream.close();
+    }
+
+    /**
+     * 00版本excel读取sheet
+     *
+     * @throws IOException 简单抛出异常,真实环境需要catch异常,同时在finally中关闭流
+     */
+    @Test
+    public void saxReadSheetsV2003() throws IOException {
+        InputStream inputStream = FileUtil.getResourcesFileInputStream("2003.xls");
+        ExcelListener excelListener = new ExcelListener();
+        ExcelReader excelReader = EasyExcelFactory.getReader(inputStream, excelListener);
+        List<Sheet> sheets = excelReader.getSheets();
+        System.out.println();
+        for (Sheet sheet : sheets) {
+            if (sheet.getSheetNo() == 1) {
+                excelReader.read(sheet);
+            } else {
+                sheet.setHeadLineMun(2);
+                sheet.setClazz(ReadModel.class);
+                excelReader.read(sheet);
+            }
+        }
+        inputStream.close();
+    }
+
+
+    public void print(List<Object> datas){
+        int i=0;
+        for (Object ob:datas) {
+            System.out.println(i++);
+            System.out.println(ob);
+        }
+    }
+
+}
diff --git a/src/test/java/com/alibaba/easyexcel/test/wirte/WriteTest.java b/src/test/java/com/alibaba/easyexcel/test/wirte/WriteTest.java
new file mode 100644
index 00000000..e8267d73
--- /dev/null
+++ b/src/test/java/com/alibaba/easyexcel/test/wirte/WriteTest.java
@@ -0,0 +1,13 @@
+package com.alibaba.easyexcel.test.wirte;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+public class WriteTest {
+
+    @Test
+    public void writeV2007() throws IOException {
+
+    }
+}