feature1:支持excel转换为PDF
diff --git a/doc/font/SimHei.ttf b/doc/font/SimHei.ttf
new file mode 100644
index 0000000..8d3f158
--- /dev/null
+++ b/doc/font/SimHei.ttf
Binary files differ
diff --git a/fastexcel-core/pom.xml b/fastexcel-core/pom.xml
index 7cc2e8e..3ba486e 100644
--- a/fastexcel-core/pom.xml
+++ b/fastexcel-core/pom.xml
@@ -16,6 +16,10 @@
     <name>fastexcel-core</name>
     <version>${revision}</version>
 
+    <properties>
+        <itext.version>7.1.15</itext.version>
+    </properties>
+
     <dependencies>
         <dependency>
             <groupId>org.apache.commons</groupId>
@@ -61,5 +65,47 @@
             <artifactId>fastexcel-support</artifactId>
             <version>0.0.1</version>
         </dependency>
+        <!-- itext7 -->
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itext7-core</artifactId>
+            <version>${itext.version}</version>
+            <type>pom</type>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>kernel</artifactId>
+            <version>${itext.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>io</artifactId>
+            <version>${itext.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>layout</artifactId>
+            <version>${itext.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>forms</artifactId>
+            <version>${itext.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>pdfa</artifactId>
+            <version>${itext.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>pdftest</artifactId>
+            <version>${itext.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>font-asian</artifactId>
+            <version>${itext.version}</version>
+        </dependency>
     </dependencies>
 </project>
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/FastExcel.java b/fastexcel-core/src/main/java/cn/idev/excel/FastExcel.java
index 3859fc1..08a7d5f 100644
--- a/fastexcel-core/src/main/java/cn/idev/excel/FastExcel.java
+++ b/fastexcel-core/src/main/java/cn/idev/excel/FastExcel.java
@@ -1,5 +1,10 @@
 package cn.idev.excel;
 
+import cn.idev.excel.fileconvertor.ExcelConverter;
+import cn.idev.excel.fileconvertor.FileConverterContext;
+
+import java.io.File;
+
 /**
  * This is actually {@link FastExcelFactory}, and short names look better.
  *
@@ -7,4 +12,18 @@
  */
 public class FastExcel extends FastExcelFactory {
 
+    /**
+     * Convert excel to pdf
+     *
+     * @param excelFile excel file
+     * @param pdfFile   pdf file
+     * @param fontPath  font path for pdf can be null
+     * @param sheets    sheet index to convert, if null convert all sheets
+     */
+    public static void convertToPdf(File excelFile, File pdfFile, String fontPath, int[] sheets) {
+        FileConverterContext context = new FileConverterContext(excelFile, pdfFile, fontPath, sheets);
+        ExcelConverter excelConverter = context.getExcelConverter();
+        excelConverter.convertToPdf();
+    }
+
 }
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/FastExcelFactory.java b/fastexcel-core/src/main/java/cn/idev/excel/FastExcelFactory.java
index a165c05..6cb6b80 100644
--- a/fastexcel-core/src/main/java/cn/idev/excel/FastExcelFactory.java
+++ b/fastexcel-core/src/main/java/cn/idev/excel/FastExcelFactory.java
@@ -353,4 +353,25 @@
         }
         return excelReaderSheetBuilder;
     }
+
+    /**
+     * Build excel the 'readSheet'
+     * @param sheetNo Index of sheet,0 base.
+     * @param sheetName The name of sheet.
+     * @param numRows The number of rows to read, the default is all, start with 0.
+     * @return
+     */
+    public static ExcelReaderSheetBuilder readSheet(Integer sheetNo, String sheetName,Integer numRows) {
+        ExcelReaderSheetBuilder excelReaderSheetBuilder = new ExcelReaderSheetBuilder();
+        if (sheetNo != null) {
+            excelReaderSheetBuilder.sheetNo(sheetNo);
+        }
+        if (sheetName != null) {
+            excelReaderSheetBuilder.sheetName(sheetName);
+        }
+        if (numRows !=null) {
+            excelReaderSheetBuilder.numRows(numRows);
+        }
+        return excelReaderSheetBuilder;
+    }
 }
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/BaseExcelConverter.java b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/BaseExcelConverter.java
new file mode 100644
index 0000000..a0d1a01
--- /dev/null
+++ b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/BaseExcelConverter.java
@@ -0,0 +1,172 @@
+package cn.idev.excel.fileconvertor;
+
+import com.itextpdf.layout.element.Table;
+import com.itextpdf.layout.property.TextAlignment;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+
+import java.io.IOException;
+import java.util.List;
+
+public abstract class BaseExcelConverter implements ExcelConverter {
+
+    private final FileConverterContext context;
+
+    public BaseExcelConverter(FileConverterContext context) {
+        this.context = context;
+    }
+
+    @Override
+    public void convertToPdf() {
+        try {
+            for (int sheetIndex : context.getSheets()) {
+                processSheet(sheetIndex);
+            }
+            context.getDocument().close();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void processSheet(int sheetIndex) throws IOException {
+        Sheet sheet = context.getWorkbook().getSheetAt(sheetIndex);
+        if (sheet == null || sheet.getRow(0) == null) {
+            return;
+        }
+        float[] columnWidths = getColumnWidths(sheet);
+        Table table = new Table(columnWidths);
+
+        addRowsToTable(table, sheet, columnWidths, context.getFountPath());
+//        addPicsToTable(table, sheet);
+
+        context.getDocument().add(table);
+    }
+
+    protected abstract void addPicsToTable(Table table, Sheet sheet);
+
+    private void addRowsToTable(Table table, Sheet sheet, float[] columnWidths, String fontPath) throws IOException {
+        int lastRowNum = sheet.getLastRowNum() + 1;
+        int lastCellNum = sheet.getRow(0).getLastCellNum();
+        for (int i = 0; i < lastRowNum; i++) {
+            Row row = sheet.getRow(i);
+            addRowToTable(table, row, lastCellNum, columnWidths, fontPath);
+        }
+    }
+
+    private void addRowToTable(Table table, Row row, int lastCellNum, float[] columnWidths, String fontPath) throws IOException {
+        if (row == null) {
+            addEmptyCells(table, lastCellNum); // 0 for empty row
+            return;
+        }
+
+        for (int j = 0; j < lastCellNum; j++) {
+            Cell cell = row.getCell(j);
+            if (cell != null && !isCellProcessed(cell)) {
+//                addCellToTable(table, cell, columnWidths, fontPath);
+                CellRangeAddress cellRange = getCellRangeAddress(cell);
+                int rowspan = (cellRange != null) ? (cellRange.getLastRow() - cellRange.getFirstRow() + 1) : 1;
+                int colspan = (cellRange != null) ? (cellRange.getLastColumn() - cellRange.getFirstColumn() + 1) : 1;
+                if ((cellRange != null)) {
+                    j = cellRange.getLastColumn();
+                }
+                float maxWidth = (cellRange != null) ? calculateMaxWidth(columnWidths, cellRange) : columnWidths[j];
+
+                com.itextpdf.layout.element.Cell pdfCell = convertCell(cell, rowspan, colspan, maxWidth, fontPath);
+                table.addCell(pdfCell);
+            } else if (cell == null) {
+                addEmptyCell(table);
+            }
+        }
+    }
+
+    private float calculateMaxWidth(float[] columnWidths, CellRangeAddress cellRange) {
+        float maxWidth = 0;
+        for (int k = cellRange.getFirstColumn(); k < cellRange.getLastColumn(); k++) {
+            maxWidth += columnWidths[k];
+        }
+        return maxWidth;
+    }
+
+    private void addEmptyCell(Table table) {
+        com.itextpdf.layout.element.Cell pdfCell = new com.itextpdf.layout.element.Cell();
+        pdfCell.setBorder(com.itextpdf.layout.borders.Border.NO_BORDER);
+        table.addCell(pdfCell);
+    }
+
+    private void addEmptyCells(Table table, int numberOfCells) {
+        for (int j = 0; j < numberOfCells; j++) {
+            addEmptyCell(table);
+        }
+    }
+
+    protected abstract com.itextpdf.layout.element.Cell convertCell(Cell cell, int rowspan, int colspan, float maxWidth, String fontPath) throws IOException;
+
+    public static com.itextpdf.layout.property.VerticalAlignment getVerticalAlignment(VerticalAlignment verticalAlignment) {
+        switch (verticalAlignment) {
+            case TOP:
+                return com.itextpdf.layout.property.VerticalAlignment.TOP;
+            case BOTTOM:
+                return com.itextpdf.layout.property.VerticalAlignment.BOTTOM;
+            case JUSTIFY:
+            case CENTER:
+                return com.itextpdf.layout.property.VerticalAlignment.MIDDLE;
+        }
+        return com.itextpdf.layout.property.VerticalAlignment.MIDDLE;
+    }
+
+    public static TextAlignment getTextAlignment(org.apache.poi.ss.usermodel.HorizontalAlignment alignment, CellType cellType) {
+        switch (alignment) {
+            case LEFT:
+                return TextAlignment.LEFT;
+            case RIGHT:
+                return TextAlignment.RIGHT;
+            case CENTER:
+                return TextAlignment.CENTER;
+            case JUSTIFY:
+                return TextAlignment.JUSTIFIED;
+            case GENERAL:
+                if (cellType == CellType.NUMERIC) {
+                    return TextAlignment.RIGHT;
+                } else if (cellType == CellType.BOOLEAN) {
+                    return TextAlignment.CENTER;
+                }
+        }
+        return TextAlignment.LEFT;
+    }
+
+    private float[] getColumnWidths(Sheet sheet) {
+        short lastCellNum = sheet.getRow(0).getLastCellNum();
+        float[] widths = new float[lastCellNum];
+        for (int i = 0; i < lastCellNum; i++) {
+            widths[i] = sheet.getColumnWidthInPixels(i);
+        }
+        return widths;
+    }
+
+    private boolean isCellProcessed(Cell cell) {
+        List<CellRangeAddress> mergedRegions = cell.getSheet().getMergedRegions();
+        int rowIndex = cell.getRowIndex();
+        int columnIndex = cell.getColumnIndex();
+
+        for (CellRangeAddress cellAddresses : mergedRegions) {
+            if (cellAddresses.getFirstRow() <= rowIndex && cellAddresses.getLastRow() >= rowIndex
+                    && cellAddresses.getFirstColumn() <= columnIndex && cellAddresses.getLastColumn() >= columnIndex) {
+                return !(cellAddresses.getFirstRow() == rowIndex && cellAddresses.getFirstColumn() == columnIndex);
+            }
+        }
+        return false;
+    }
+
+    private CellRangeAddress getCellRangeAddress(Cell cell) {
+        List<CellRangeAddress> mergedRegions = cell.getSheet().getMergedRegions();
+        int rowIndex = cell.getRowIndex();
+        int columnIndex = cell.getColumnIndex();
+
+        for (CellRangeAddress cellAddresses : mergedRegions) {
+            if (cellAddresses.getFirstRow() == rowIndex && cellAddresses.getFirstColumn() == columnIndex) {
+                return cellAddresses;
+            }
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/Excel2PdfUtils.java b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/Excel2PdfUtils.java
new file mode 100644
index 0000000..d490d64
--- /dev/null
+++ b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/Excel2PdfUtils.java
@@ -0,0 +1,45 @@
+package cn.idev.excel.fileconvertor;
+
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.ss.usermodel.DateUtil;
+import org.apache.poi.util.LocaleUtil;
+
+import java.text.SimpleDateFormat;
+
+public class Excel2PdfUtils {
+    private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; // 日期格式
+    private static final String TRUE_STRING = "TRUE";
+    private static final String FALSE_STRING = "FALSE";
+    private static final String EMPTY_STRING = "";
+
+    // 使用单例模式确保 SimpleDateFormat 只被创建一次
+    private static final ThreadLocal<SimpleDateFormat> DATE_FORMATTER = ThreadLocal.withInitial(() ->
+            new SimpleDateFormat(DATE_FORMAT, LocaleUtil.getUserLocale())
+    );
+
+    public static String getValue(Cell cell) {
+        if (cell == null) {
+            return EMPTY_STRING;
+        }
+
+        CellType cellType = cell.getCellType();
+        switch (cellType) {
+            case BOOLEAN:
+                return cell.getBooleanCellValue() ? TRUE_STRING : FALSE_STRING;
+            case NUMERIC:
+                return getNumericCellValue(cell);
+            case STRING:
+                return cell.getStringCellValue();
+            default:
+                return EMPTY_STRING;
+        }
+    }
+
+    private static String getNumericCellValue(Cell cell) {
+        if (DateUtil.isCellDateFormatted(cell)) {
+            return DATE_FORMATTER.get().format(cell.getDateCellValue());
+        }
+        return String.valueOf(cell.getNumericCellValue());
+    }
+}
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/ExcelConverter.java b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/ExcelConverter.java
new file mode 100644
index 0000000..f5bd14c
--- /dev/null
+++ b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/ExcelConverter.java
@@ -0,0 +1,17 @@
+package cn.idev.excel.fileconvertor;
+
+import java.io.File;
+
+/**
+ * Excel convert to other file
+ * @author jipengfei
+ */
+public interface ExcelConverter {
+
+    /**
+     * excel to pdf
+     *
+     */
+    void convertToPdf();
+
+}
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/FileConverterContext.java b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/FileConverterContext.java
new file mode 100644
index 0000000..e0948d4
--- /dev/null
+++ b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/FileConverterContext.java
@@ -0,0 +1,74 @@
+package cn.idev.excel.fileconvertor;
+
+import cn.idev.excel.read.metadata.ReadWorkbook;
+import cn.idev.excel.support.ExcelTypeEnum;
+import com.itextpdf.kernel.geom.PageSize;
+import com.itextpdf.kernel.pdf.PdfDocument;
+import com.itextpdf.kernel.pdf.PdfWriter;
+import com.itextpdf.layout.Document;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+@Getter
+@Setter
+public class FileConverterContext {
+
+    private File inputFile;
+    private File outputFile;
+    private String fountPath;
+    private Workbook workbook;
+    private Document document;
+    private int[] sheets;
+    private ExcelTypeEnum excelTypeEnum;
+
+    public FileConverterContext(File inputFile, File outputFile, String fountPath, int[] sheets) {
+        try {
+            this.inputFile = inputFile;
+            this.outputFile = outputFile;
+            this.fountPath = fountPath;
+            ReadWorkbook readWorkbook = new ReadWorkbook();
+            readWorkbook.setFile(inputFile);
+            excelTypeEnum = ExcelTypeEnum.valueOf(readWorkbook);
+            if (excelTypeEnum == ExcelTypeEnum.XLSX) {
+                this.workbook = new XSSFWorkbook(inputFile);
+            } else if (excelTypeEnum == ExcelTypeEnum.XLS) {
+                this.workbook = new HSSFWorkbook(new FileInputStream(inputFile));
+            } else {
+                throw new IllegalArgumentException("Not supported excel type");
+            }
+            PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outputFile));
+            this.document = new Document(pdfDocument, PageSize.A4.rotate());
+            if (sheets == null) {
+                this.sheets = new int[workbook.getNumberOfSheets()];
+                for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
+                    this.sheets[i] = i;
+                }
+            } else {
+                this.sheets = sheets;
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } catch (InvalidFormatException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public ExcelConverter getExcelConverter() {
+        if (excelTypeEnum == ExcelTypeEnum.XLSX) {
+            return new cn.idev.excel.fileconvertor.v07.XlsxConverter(this);
+        } else if (excelTypeEnum == ExcelTypeEnum.XLS) {
+            return new cn.idev.excel.fileconvertor.v03.XlsConverter(this);
+        }
+        throw new IllegalArgumentException("Not supported excel type");
+    }
+
+
+}
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/v03/XlsConverter.java b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/v03/XlsConverter.java
new file mode 100644
index 0000000..680c339
--- /dev/null
+++ b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/v03/XlsConverter.java
@@ -0,0 +1,150 @@
+package cn.idev.excel.fileconvertor.v03;
+
+import cn.idev.excel.fileconvertor.BaseExcelConverter;
+import cn.idev.excel.fileconvertor.Excel2PdfUtils;
+import cn.idev.excel.fileconvertor.FileConverterContext;
+import cn.idev.excel.util.StringUtils;
+import com.itextpdf.io.font.PdfEncodings;
+import com.itextpdf.kernel.colors.Color;
+import com.itextpdf.kernel.colors.ColorConstants;
+import com.itextpdf.kernel.colors.DeviceRgb;
+import com.itextpdf.kernel.font.PdfFontFactory;
+import com.itextpdf.layout.borders.*;
+import com.itextpdf.layout.element.*;
+import com.itextpdf.layout.element.Cell;
+import com.itextpdf.layout.element.Table;
+import org.apache.poi.hssf.usermodel.*;
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.usermodel.*;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class XlsConverter extends BaseExcelConverter {
+    public XlsConverter(FileConverterContext context) {
+        super(context);
+    }
+
+    @Override
+    public void addPicsToTable(Table table, Sheet sheet) {
+        HSSFPatriarch drawingPatriarch = ((HSSFSheet) sheet).getDrawingPatriarch();
+        if (drawingPatriarch != null) {
+            List<HSSFPicture> pictures = new ArrayList<>();
+            for (HSSFShape shape : drawingPatriarch.getChildren()) {
+                if (shape instanceof HSSFPicture) {
+                    pictures.add((HSSFPicture) shape);
+                }
+            }
+            table.setNextRenderer(new XlsImageTableRenderer(table, pictures, (HSSFSheet) sheet));
+        }
+    }
+
+    @Override
+    public Cell convertCell(org.apache.poi.ss.usermodel.Cell cell, int rowspan, int colspan, float maxWidth, String fontPath) throws IOException {
+        String value = Excel2PdfUtils.getValue(cell);
+        Cell pdfCell = createPdfCell(rowspan, colspan, cell, value, maxWidth, fontPath);
+
+        return pdfCell;
+    }
+
+    private Cell createPdfCell(int rowspan, int colspan, org.apache.poi.ss.usermodel.Cell cell, String value, float maxWidth, String fontPath) throws IOException {
+        float cellHeight = cell.getRow().getHeightInPoints() * 1.2f;
+        Cell pdfCell = new Cell(rowspan, colspan)
+                .setHeight(cellHeight)
+                .setPadding(0);
+        Text text = new Text(value);
+        setPdfCellFont((HSSFCell) cell, text, fontPath);
+
+        Paragraph paragraph = new Paragraph(text).setPadding(0f).setMargin(0f);
+        HSSFCellStyle cellStyle = ((HSSFCell) cell).getCellStyle();
+        if (cellStyle.getWrapText()) {
+            paragraph.setMaxWidth(maxWidth);
+        }
+
+        pdfCell.add(paragraph);
+
+        setCellStyles(cell, pdfCell);
+        return pdfCell;
+    }
+
+    private void setCellStyles(org.apache.poi.ss.usermodel.Cell cell, Cell pdfCell) throws IOException {
+        HSSFCellStyle cellStyle = ((HSSFCell) cell).getCellStyle();
+        // Layout
+        pdfCell.setVerticalAlignment(getVerticalAlignment(cellStyle.getVerticalAlignment()));
+        pdfCell.setTextAlignment(getTextAlignment(cellStyle.getAlignment(), cell.getCellType()));
+
+        // Set borders
+        transformBorders((HSSFCell) cell, pdfCell);
+
+        // Set background color
+        setBackgroundColor(cellStyle, pdfCell, cell);
+    }
+
+    private void setBackgroundColor(HSSFCellStyle cellStyle, Cell pdfCell, org.apache.poi.ss.usermodel.Cell cell) {
+        short colorIndex = cellStyle.getFillForegroundColor();
+        HSSFWorkbook workbook = (HSSFWorkbook) cell.getSheet().getWorkbook();
+        HSSFColor color = workbook.getCustomPalette().getColor(colorIndex);
+        if (color != null && color.getIndex() != 64) {
+            short[] triplet = color.getTriplet();
+            int r = Math.min(triplet[0] + 32, 255);
+            int g = Math.min(triplet[1] + 90, 255);
+            int b = Math.min(triplet[2] + 60, 255);
+            pdfCell.setBackgroundColor(new DeviceRgb(r, g, b));
+        }
+    }
+
+    public static void transformBorders(HSSFCell cell, Cell pdfCell) {
+        HSSFCellStyle cellStyle = cell.getCellStyle();
+        pdfCell.setBorderBottom(getBorder(cellStyle.getBorderBottom(), cellStyle.getBottomBorderColor(), cell));
+        pdfCell.setBorderLeft(getBorder(cellStyle.getBorderLeft(), cellStyle.getLeftBorderColor(), cell));
+        pdfCell.setBorderRight(getBorder(cellStyle.getBorderRight(), cellStyle.getRightBorderColor(), cell));
+        pdfCell.setBorderTop(getBorder(cellStyle.getBorderTop(), cellStyle.getTopBorderColor(), cell));
+    }
+
+    private void setPdfCellFont(HSSFCell cell, Text text, String fontPath) throws IOException {
+        HSSFCellStyle cellStyle = cell.getCellStyle();
+        HSSFFont font = cellStyle.getFont(cell.getSheet().getWorkbook());
+        text.setFont(StringUtils.isEmpty(fontPath) ? PdfFontFactory.createFont() : PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H));
+        text.setFontSize(font.getFontHeightInPoints());
+
+        // Set font color
+        HSSFColor hssfColor = font.getHSSFColor(cell.getSheet().getWorkbook());
+        if (hssfColor != null && hssfColor.getIndex() != 64) {
+            short[] triplet = hssfColor.getTriplet();
+            text.setFontColor(new DeviceRgb(triplet[0], triplet[1], triplet[2]));
+        }
+
+        // Set font styles
+        if (font.getBold()) text.setBold();
+        if (font.getItalic()) text.setItalic();
+        if (font.getUnderline() == 1) text.setUnderline(0.5f, -1f);
+    }
+
+    public static Border getBorder(BorderStyle borderStyle, short colorIndex, HSSFCell cell) {
+        HSSFPalette customPalette = cell.getSheet().getWorkbook().getCustomPalette();
+        HSSFColor color = customPalette.getColor(colorIndex);
+        Color defaultColor = (color != null && color.getIndex() != 64)
+                ? new DeviceRgb(color.getTriplet()[0], color.getTriplet()[1], color.getTriplet()[2])
+                : ColorConstants.BLACK;
+
+        switch (borderStyle) {
+            case THIN:
+                return new SolidBorder(defaultColor, 0.3f);
+            case MEDIUM:
+                return new SolidBorder(defaultColor, 0.5f);
+            case DASHED:
+                return new DashedBorder(defaultColor, 0.3f);
+            case DOTTED:
+                return new DottedBorder(defaultColor, 0.3f);
+            case THICK:
+                return new SolidBorder(defaultColor, 1f);
+            case DOUBLE:
+                return new DoubleBorder(defaultColor, 0.3f);
+            case MEDIUM_DASHED:
+                return new DashedBorder(defaultColor, 0.5f);
+            default:
+                return Border.NO_BORDER;
+        }
+    }
+}
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/v03/XlsImageTableRenderer.java b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/v03/XlsImageTableRenderer.java
new file mode 100644
index 0000000..a77094b
--- /dev/null
+++ b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/v03/XlsImageTableRenderer.java
@@ -0,0 +1,116 @@
+package cn.idev.excel.fileconvertor.v03;
+
+import com.itextpdf.io.image.ImageData;
+import com.itextpdf.io.image.ImageDataFactory;
+import com.itextpdf.kernel.geom.Rectangle;
+import com.itextpdf.layout.element.Table;
+import com.itextpdf.layout.renderer.CellRenderer;
+import com.itextpdf.layout.renderer.DrawContext;
+import com.itextpdf.layout.renderer.IRenderer;
+import com.itextpdf.layout.renderer.TableRenderer;
+import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
+import org.apache.poi.hssf.usermodel.HSSFPicture;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+
+import java.util.List;
+
+/**
+ * Renders images from an Excel sheet onto a PDF table.
+ */
+public class XlsImageTableRenderer extends TableRenderer {
+    private List<HSSFPicture> hSSFPictures;
+    private HSSFSheet sheet;
+
+    public XlsImageTableRenderer(Table modelElement, List<HSSFPicture> hSSFPictures, HSSFSheet sheet) {
+        super(modelElement);
+        this.hSSFPictures = hSSFPictures;
+        this.sheet = sheet;
+    }
+
+    @Override
+    public void drawChildren(DrawContext drawContext) {
+        super.drawChildren(drawContext);
+        drawExcelImages(drawContext);
+    }
+
+    private void drawExcelImages(DrawContext drawContext) {
+        for (HSSFPicture picture : hSSFPictures) {
+            HSSFClientAnchor clientAnchor = picture.getClientAnchor();
+            Rectangle imageRect = calculateImageRectangle(clientAnchor);
+            ImageData imageData = ImageDataFactory.create(picture.getPictureData().getData());
+            drawContext.getCanvas().addImage(imageData,
+                    imageRect.getWidth(),
+                    0,
+                    0,
+                    imageRect.getHeight(),
+                    imageRect.getLeft(),
+                    imageRect.getTop());
+        }
+    }
+
+    private Rectangle calculateImageRectangle(HSSFClientAnchor clientAnchor) {
+        CellRenderer cellRenderer1 = rows.get(clientAnchor.getRow1())[clientAnchor.getCol1()];
+        Rectangle rect1 = cellRenderer1.getOccupiedAreaBBox();
+
+        CellRenderer cellRenderer2 = rows.get(clientAnchor.getRow2())[clientAnchor.getCol2()];
+        Rectangle rect2 = cellRenderer2.getOccupiedAreaBBox();
+
+        float widthRate = calculateWidthRate(rect2);
+        float heightRate = calculateHeightRate(rect2);
+
+        float width = calculateImageWidth(clientAnchor, widthRate);
+        float height = calculateImageHeight(clientAnchor, heightRate);
+
+        float x = rect1.getLeft() + clientAnchor.getDx1() * widthRate;
+        float y = rect1.getTop() - height - clientAnchor.getDy1() * heightRate;
+
+        return new Rectangle(x, y, width, height);
+    }
+
+    private float calculateWidthRate(Rectangle rect2) {
+        return (super.getOccupiedAreaBBox().getWidth() + rect2.getWidth()) / getExcelWidth(sheet);
+    }
+
+    private float calculateHeightRate(Rectangle rect2) {
+        return (super.getOccupiedAreaBBox().getHeight() - rect2.getHeight()) / getExcelHeight(sheet);
+    }
+
+    private float calculateImageWidth(HSSFClientAnchor clientAnchor, float widthRate) {
+        float width = 0f;
+        for (int j = clientAnchor.getCol1(); j < clientAnchor.getCol2(); j++) {
+            width += sheet.getColumnWidth(j);
+        }
+        return Math.abs(width - clientAnchor.getDx1() + clientAnchor.getDx2()) * widthRate;
+    }
+
+    private float calculateImageHeight(HSSFClientAnchor clientAnchor, float heightRate) {
+        float height = 0f;
+        for (int j = clientAnchor.getRow1(); j < clientAnchor.getRow2(); j++) {
+            height += sheet.getRow(j).getHeight();
+        }
+        return Math.abs(height - clientAnchor.getDy1() + clientAnchor.getDy2()) * heightRate;
+    }
+
+    private float getExcelHeight(HSSFSheet sheet) {
+        int physicalNumberOfRows = sheet.getPhysicalNumberOfRows();
+        float result = 0;
+        for (int i = 0; i < physicalNumberOfRows; i++) {
+            result += sheet.getRow(i).getHeight();
+        }
+        return result;
+    }
+
+    private float getExcelWidth(HSSFSheet sheet) {
+        short lastCellNum = sheet.getRow(0).getLastCellNum();
+        float result = 0;
+        for (int i = 0; i < lastCellNum; i++) {
+            result += sheet.getColumnWidth(i);
+        }
+        return result;
+    }
+
+    @Override
+    public IRenderer getNextRenderer() {
+        return new XlsImageTableRenderer((Table) modelElement, hSSFPictures, sheet);
+    }
+}
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/v07/XlsxConverter.java b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/v07/XlsxConverter.java
new file mode 100644
index 0000000..8ab1bbc
--- /dev/null
+++ b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/v07/XlsxConverter.java
@@ -0,0 +1,161 @@
+package cn.idev.excel.fileconvertor.v07;
+
+import cn.idev.excel.fileconvertor.BaseExcelConverter;
+import cn.idev.excel.fileconvertor.Excel2PdfUtils;
+import cn.idev.excel.fileconvertor.FileConverterContext;
+import cn.idev.excel.util.StringUtils;
+import com.itextpdf.io.font.PdfEncodings;
+import com.itextpdf.kernel.colors.DeviceRgb;
+import com.itextpdf.kernel.font.PdfFontFactory;
+import com.itextpdf.layout.borders.*;
+import com.itextpdf.layout.element.Paragraph;
+import com.itextpdf.layout.element.Table;
+import com.itextpdf.layout.element.Text;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.*;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class XlsxConverter extends BaseExcelConverter {
+    private static final String DEFAULT_FONT_PATH = System.getProperty("user.dir") + "/doc/font/SimHei.TTF";
+
+    public XlsxConverter(FileConverterContext context) {
+        super(context);
+    }
+
+    @Override
+    public void addPicsToTable(Table table, Sheet sheet) {
+        XSSFDrawing drawing = (XSSFDrawing) sheet.createDrawingPatriarch();
+        if (drawing != null) {
+            List<XSSFPicture> pictures = new ArrayList<>();
+            for (XSSFShape shape : drawing.getShapes()) {
+                if (shape instanceof XSSFPicture) {
+                    pictures.add((XSSFPicture) shape);
+                }
+            }
+            table.setNextRenderer(new XlsxImageTableRenderer(table, pictures, (XSSFSheet) sheet));
+        }
+    }
+
+    @Override
+    public com.itextpdf.layout.element.Cell convertCell(Cell cell, int rowspan, int colspan, float maxWidth, String fontPath) throws IOException {
+        String value = Excel2PdfUtils.getValue(cell);
+        com.itextpdf.layout.element.Cell pdfCell = createPdfCell(rowspan, colspan, cell, value, maxWidth, fontPath);
+        return pdfCell;
+    }
+
+    public static void transformBorder(XSSFCell cell, com.itextpdf.layout.element.Cell pdfCell) {
+        XSSFCellStyle cellStyle = cell.getCellStyle();
+        BorderStyle borderBottom = cellStyle.getBorderBottom();
+        pdfCell.setBorderBottom(getBorder(borderBottom, cellStyle.getBottomBorderXSSFColor()));
+
+        BorderStyle borderLeft = cellStyle.getBorderLeft();
+        pdfCell.setBorderLeft(getBorder(borderLeft, cellStyle.getLeftBorderXSSFColor()));
+
+        BorderStyle borderRight = cellStyle.getBorderRight();
+        pdfCell.setBorderRight(getBorder(borderRight, cellStyle.getRightBorderXSSFColor()));
+
+        BorderStyle borderTop = cellStyle.getBorderTop();
+        pdfCell.setBorderTop(getBorder(borderTop, cellStyle.getTopBorderXSSFColor()));
+    }
+
+    private com.itextpdf.layout.element.Cell createPdfCell(int rowspan, int colspan, Cell cell, String value, float maxWidth, String fontPath) throws IOException {
+        com.itextpdf.layout.element.Cell pdfCell = new com.itextpdf.layout.element.Cell(rowspan, colspan)
+                .setHeight(cell.getRow().getHeightInPoints() * 1.2f)
+                .setPadding(0);
+        Text text = new Text(value);
+        setPdfCellFont((XSSFCell) cell, text, fontPath);
+        Paragraph paragraph = new Paragraph(text).setPadding(0f).setMargin(0f);
+        XSSFCellStyle cellStyle = ((XSSFCell) cell).getCellStyle();
+        if (cellStyle.getWrapText()) {
+            paragraph.setMaxWidth(maxWidth);
+        }
+        pdfCell.add(paragraph);
+        setCellStyles((XSSFCell)cell, pdfCell);
+        return pdfCell;
+    }
+
+    private void setCellStyles( XSSFCell cell,com.itextpdf.layout.element.Cell pdfCell) throws IOException {
+        XSSFCellStyle cellStyle = cell.getCellStyle();
+        pdfCell.setVerticalAlignment(getVerticalAlignment(cellStyle.getVerticalAlignment()))
+                .setTextAlignment(getTextAlignment(cellStyle.getAlignment(), cell.getCellType()));
+
+        // Set borders and background color
+        setBorders(pdfCell, cellStyle);
+        setBackgroundColor(pdfCell, cellStyle);
+    }
+
+    private void setBorders(com.itextpdf.layout.element.Cell pdfCell, XSSFCellStyle cellStyle) {
+        pdfCell.setBorderBottom(getBorder(cellStyle.getBorderBottom(), cellStyle.getBottomBorderXSSFColor()));
+        pdfCell.setBorderLeft(getBorder(cellStyle.getBorderLeft(), cellStyle.getLeftBorderXSSFColor()));
+        pdfCell.setBorderRight(getBorder(cellStyle.getBorderRight(), cellStyle.getRightBorderXSSFColor()));
+        pdfCell.setBorderTop(getBorder(cellStyle.getBorderTop(), cellStyle.getTopBorderXSSFColor()));
+    }
+
+    private void setBackgroundColor(com.itextpdf.layout.element.Cell pdfCell, XSSFCellStyle cellStyle) {
+        XSSFColor fillColor = cellStyle.getFillForegroundXSSFColor();
+        if (fillColor != null) {
+            byte[] rgb = fillColor.getRGB();
+            if (rgb != null) {
+                pdfCell.setBackgroundColor(new DeviceRgb(Byte.toUnsignedInt(rgb[0]), Byte.toUnsignedInt(rgb[1]), Byte.toUnsignedInt(rgb[2])));
+            }
+        }
+    }
+
+    private void setPdfCellFont(XSSFCell cell, Text text,String fontPath) throws IOException {
+        XSSFCellStyle cellStyle = cell.getCellStyle();
+        short fontHeight = cellStyle.getFont().getFontHeightInPoints();
+        cellStyle.getFont().getFontName();
+        text.setFont(StringUtils.isEmpty(fontPath) ? PdfFontFactory.createFont() : PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H));
+        text.setFontSize(fontHeight);
+        setFontColor(cellStyle.getFont(), text);
+        setFontStyles(cell.getCellStyle().getFont(), text);
+    }
+
+    private void setFontColor(XSSFFont font, Text text) {
+        XSSFColor xssfColor = font.getXSSFColor();
+        if (xssfColor != null && xssfColor.getIndex() != 64) {
+            byte[] rgb = xssfColor.getRGB();
+            if (rgb != null) {
+                text.setFontColor(new DeviceRgb(Byte.toUnsignedInt(rgb[0]), Byte.toUnsignedInt(rgb[1]), Byte.toUnsignedInt(rgb[2])));
+            }
+        }
+    }
+
+    private void setFontStyles(XSSFFont font, Text text) {
+        if (font.getBold()) text.setBold();
+        if (font.getItalic()) text.setItalic();
+        if (font.getUnderline() == 1) text.setUnderline(0.5f, -1f);
+    }
+
+    public static com.itextpdf.layout.borders.Border getBorder(BorderStyle borderStyle, XSSFColor xSSFColor) {
+        DeviceRgb defaultColor = new DeviceRgb(0, 0, 0); // Default to black
+        if (xSSFColor != null) {
+            byte[] rgb = xSSFColor.getRGB();
+            if (rgb != null) {
+                defaultColor = new DeviceRgb(Byte.toUnsignedInt(rgb[0]), Byte.toUnsignedInt(rgb[1]), Byte.toUnsignedInt(rgb[2]));
+            }
+        }
+
+        switch (borderStyle) {
+            case THIN:
+                return new SolidBorder(defaultColor, 0.3f);
+            case MEDIUM:
+                return new SolidBorder(defaultColor, 0.5f);
+            case DASHED:
+                return new DashedBorder(defaultColor, 0.3f);
+            case DOTTED:
+                return new DottedBorder(defaultColor, 0.3f);
+            case THICK:
+                return new SolidBorder(defaultColor, 1f);
+            case DOUBLE:
+                return new DoubleBorder(defaultColor, 0.3f);
+            case MEDIUM_DASHED:
+                return new DashedBorder(defaultColor, 0.5f);
+            default:
+                return Border.NO_BORDER;
+        }
+    }
+}
\ No newline at end of file
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/v07/XlsxImageTableRenderer.java b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/v07/XlsxImageTableRenderer.java
new file mode 100644
index 0000000..017704b
--- /dev/null
+++ b/fastexcel-core/src/main/java/cn/idev/excel/fileconvertor/v07/XlsxImageTableRenderer.java
@@ -0,0 +1,101 @@
+package cn.idev.excel.fileconvertor.v07;
+
+import com.itextpdf.io.image.ImageData;
+import com.itextpdf.io.image.ImageDataFactory;
+import com.itextpdf.kernel.geom.Rectangle;
+import com.itextpdf.layout.element.Table;
+import com.itextpdf.layout.renderer.CellRenderer;
+import com.itextpdf.layout.renderer.DrawContext;
+import com.itextpdf.layout.renderer.IRenderer;
+import com.itextpdf.layout.renderer.TableRenderer;
+import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
+import org.apache.poi.xssf.usermodel.XSSFPicture;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+
+import java.util.List;
+
+/**
+ * Renders images from an Excel sheet onto a PDF table.
+ */
+public class XlsxImageTableRenderer extends TableRenderer {
+    private List<XSSFPicture> xssfPictures;
+    private XSSFSheet sheet;
+
+    public XlsxImageTableRenderer(Table modelElement, List<XSSFPicture> xssfPictures, XSSFSheet sheet) {
+        super(modelElement);
+        this.xssfPictures = xssfPictures;
+        this.sheet = sheet;
+    }
+
+    @Override
+    public void drawChildren(DrawContext drawContext) {
+        super.drawChildren(drawContext);
+        renderExcelImages(drawContext);
+    }
+
+    private void renderExcelImages(DrawContext drawContext) {
+        for (XSSFPicture picture : xssfPictures) {
+            XSSFClientAnchor clientAnchor = picture.getClientAnchor();
+            Rectangle imageRect = calculateImageRectangle(clientAnchor);
+            ImageData imageData = ImageDataFactory.create(picture.getPictureData().getData());
+            drawContext.getCanvas().addImage(imageData,
+                    imageRect.getWidth(),
+                    0,
+                    0,
+                    imageRect.getHeight(),
+                    imageRect.getLeft(),
+                    imageRect.getTop());
+        }
+    }
+
+    private Rectangle calculateImageRectangle(XSSFClientAnchor clientAnchor) {
+        CellRenderer cellRenderer1 = rows.get(clientAnchor.getRow1())[clientAnchor.getCol1()];
+        CellRenderer cellRenderer2 = rows.get(clientAnchor.getRow2())[clientAnchor.getCol2()];
+        Rectangle rect1 = cellRenderer1.getOccupiedAreaBBox();
+        Rectangle rect2 = cellRenderer2.getOccupiedAreaBBox();
+
+        float widthRate = (super.getOccupiedAreaBBox().getWidth() + rect2.getWidth()) / getExcelWidth(sheet);
+        float heightRate = (super.getOccupiedAreaBBox().getHeight() - rect2.getHeight()) / getExcelHeight(sheet);
+
+        float width = calculateImageWidth(clientAnchor, widthRate);
+        float height = calculateImageHeight(clientAnchor, heightRate);
+
+        float x = rect1.getLeft() + clientAnchor.getDx1() * widthRate;
+        float y = rect1.getTop() - height - clientAnchor.getDy1() * heightRate;
+
+        return new Rectangle(x, y, width, height);
+    }
+
+    private float calculateImageWidth(XSSFClientAnchor clientAnchor, float widthRate) {
+        float width = 0f;
+        for (int j = clientAnchor.getCol1(); j < clientAnchor.getCol2(); j++) {
+            width += sheet.getColumnWidth(j);
+        }
+        return Math.abs(width - clientAnchor.getDx1() + clientAnchor.getDx2()) * widthRate;
+    }
+
+    private float calculateImageHeight(XSSFClientAnchor clientAnchor, float heightRate) {
+        float height = 0f;
+        for (int j = clientAnchor.getRow1(); j < clientAnchor.getRow2(); j++) {
+            height += sheet.getRow(j).getHeight();
+        }
+        return Math.abs(height - clientAnchor.getDy1() + clientAnchor.getDy2()) * heightRate;
+    }
+
+    private float getExcelHeight(XSSFSheet sheet) {
+        float totalHeight = 0;
+        for (int i = 0; i < sheet.getPhysicalNumberOfRows(); i++) {
+            totalHeight += sheet.getRow(i).getHeight();
+        }
+        return totalHeight;
+    }
+
+    private float getExcelWidth(XSSFSheet sheet) {
+        return (short)sheet.getRow(0).getLastCellNum() * sheet.getColumnWidth(0);
+    }
+
+    @Override
+    public IRenderer getNextRenderer() {
+        return new XlsxImageTableRenderer((Table) modelElement, xssfPictures, sheet);
+    }
+}
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/read/builder/ExcelReaderBuilder.java b/fastexcel-core/src/main/java/cn/idev/excel/read/builder/ExcelReaderBuilder.java
index bc24ac6..a0330fb 100644
--- a/fastexcel-core/src/main/java/cn/idev/excel/read/builder/ExcelReaderBuilder.java
+++ b/fastexcel-core/src/main/java/cn/idev/excel/read/builder/ExcelReaderBuilder.java
@@ -211,6 +211,12 @@
         return this;
     }
 
+
+    public ExcelReaderBuilder numRows(Integer numRows) {
+        readWorkbook.setNumRows(numRows);
+        return this;
+    }
+
     public ExcelReader build() {
         return new ExcelReader(readWorkbook);
     }
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/read/builder/ExcelReaderSheetBuilder.java b/fastexcel-core/src/main/java/cn/idev/excel/read/builder/ExcelReaderSheetBuilder.java
index 069761d..36d2b02 100644
--- a/fastexcel-core/src/main/java/cn/idev/excel/read/builder/ExcelReaderSheetBuilder.java
+++ b/fastexcel-core/src/main/java/cn/idev/excel/read/builder/ExcelReaderSheetBuilder.java
@@ -51,6 +51,17 @@
         return this;
     }
 
+    /**
+     * numRows
+     *
+     * @param numRows
+     * @return
+     */
+    public ExcelReaderSheetBuilder numRows(Integer numRows) {
+        readSheet.setNumRows(numRows);
+        return this;
+    }
+
     public ReadSheet build() {
         return readSheet;
     }
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/read/listener/PageReadListener.java b/fastexcel-core/src/main/java/cn/idev/excel/read/listener/PageReadListener.java
index 708c9d3..2aa18ab 100644
--- a/fastexcel-core/src/main/java/cn/idev/excel/read/listener/PageReadListener.java
+++ b/fastexcel-core/src/main/java/cn/idev/excel/read/listener/PageReadListener.java
@@ -17,7 +17,7 @@
     /**
      * Default single handle the amount of data
      */
-    public static int BATCH_COUNT = 100;
+    public static int BATCH_COUNT = 1;
     /**
      * Temporary storage of data
      */
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/read/listener/ReadListener.java b/fastexcel-core/src/main/java/cn/idev/excel/read/listener/ReadListener.java
index 9558ece..3d98558 100644
--- a/fastexcel-core/src/main/java/cn/idev/excel/read/listener/ReadListener.java
+++ b/fastexcel-core/src/main/java/cn/idev/excel/read/listener/ReadListener.java
@@ -6,6 +6,9 @@
 import cn.idev.excel.context.AnalysisContext;
 import cn.idev.excel.metadata.CellExtra;
 import cn.idev.excel.metadata.data.ReadCellData;
+import cn.idev.excel.read.metadata.holder.ReadRowHolder;
+import cn.idev.excel.read.metadata.holder.ReadSheetHolder;
+import cn.idev.excel.read.metadata.holder.ReadWorkbookHolder;
 
 /**
  * Interface to listen for read results
@@ -31,7 +34,8 @@
      * @param headMap
      * @param context
      */
-    default void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {}
+    default void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
+    }
 
     /**
      * When analysis one row trigger invoke function.
@@ -47,7 +51,8 @@
      * @param extra   extra information
      * @param context analysis context
      */
-    default void extra(CellExtra extra, AnalysisContext context) {}
+    default void extra(CellExtra extra, AnalysisContext context) {
+    }
 
     /**
      * if have something to do after all analysis
@@ -63,6 +68,24 @@
      * @return
      */
     default boolean hasNext(AnalysisContext context) {
+        if (context == null
+                || context.readRowHolder() == null
+                || context.readSheetHolder() == null
+                || context.readSheetHolder().getReadSheet() == null
+                || context.readWorkbookHolder().getReadWorkbook() == null
+        ) {
+            return true;
+        }
+        ReadRowHolder readRowHolder = context.readRowHolder();
+        int index = readRowHolder.getRowIndex();
+
+        Integer limit = context.readSheetHolder().getReadSheet().getNumRows();
+        if (limit == null) {
+            limit = context.readWorkbookHolder().getReadWorkbook().getNumRows();
+        }
+        if (limit != null && index >= limit) {
+            return false;
+        }
         return true;
     }
 }
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/read/metadata/ReadSheet.java b/fastexcel-core/src/main/java/cn/idev/excel/read/metadata/ReadSheet.java
index 36c5246..f570b05 100644
--- a/fastexcel-core/src/main/java/cn/idev/excel/read/metadata/ReadSheet.java
+++ b/fastexcel-core/src/main/java/cn/idev/excel/read/metadata/ReadSheet.java
@@ -15,6 +15,11 @@
      */
     private String sheetName;
 
+    /**
+     * The number of rows to read, the default is all, start with 0.
+     */
+    public Integer numRows;
+
     public ReadSheet() {}
 
     public ReadSheet(Integer sheetNo) {
@@ -26,6 +31,12 @@
         this.sheetName = sheetName;
     }
 
+    public ReadSheet(Integer sheetNo, String sheetName,Integer numRows) {
+        this.sheetNo = sheetNo;
+        this.sheetName = sheetName;
+        this.numRows = numRows;
+    }
+
     public Integer getSheetNo() {
         return sheetNo;
     }
@@ -42,6 +53,15 @@
         this.sheetName = sheetName;
     }
 
+
+    public Integer getNumRows() {
+        return numRows;
+    }
+
+    public void setNumRows(Integer numRows) {
+        this.numRows = numRows;
+    }
+
     public void copyBasicParameter(ReadSheet other) {
         if (other == null) {
             return;
@@ -53,6 +73,7 @@
         this.setCustomConverterList(other.getCustomConverterList());
         this.setAutoTrim(other.getAutoTrim());
         this.setUse1904windowing(other.getUse1904windowing());
+        this.setNumRows(other.getNumRows());
     }
 
     @Override
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/read/metadata/ReadWorkbook.java b/fastexcel-core/src/main/java/cn/idev/excel/read/metadata/ReadWorkbook.java
index 79b8640..a103fb1 100644
--- a/fastexcel-core/src/main/java/cn/idev/excel/read/metadata/ReadWorkbook.java
+++ b/fastexcel-core/src/main/java/cn/idev/excel/read/metadata/ReadWorkbook.java
@@ -115,4 +115,9 @@
      * @see CellExtraTypeEnum
      */
     private Set<CellExtraTypeEnum> extraReadSet;
+
+    /**
+     * The number of rows to read, the default is all, start with 0.
+     */
+    private Integer numRows;
 }
diff --git a/fastexcel-core/src/main/java/cn/idev/excel/read/processor/DefaultAnalysisEventProcessor.java b/fastexcel-core/src/main/java/cn/idev/excel/read/processor/DefaultAnalysisEventProcessor.java
index 7a90811..8351a51 100644
--- a/fastexcel-core/src/main/java/cn/idev/excel/read/processor/DefaultAnalysisEventProcessor.java
+++ b/fastexcel-core/src/main/java/cn/idev/excel/read/processor/DefaultAnalysisEventProcessor.java
@@ -118,6 +118,7 @@
                 throw new ExcelAnalysisStopException();
             }
         }
+
     }
 
     private void buildHead(AnalysisContext analysisContext, Map<Integer, ReadCellData<?>> cellDataMap) {
diff --git a/fastexcel-test/src/test/java/cn/idev/excel/test/demo/read/ReadTest.java b/fastexcel-test/src/test/java/cn/idev/excel/test/demo/read/ReadTest.java
index 4abde03..769c0c9 100644
--- a/fastexcel-test/src/test/java/cn/idev/excel/test/demo/read/ReadTest.java
+++ b/fastexcel-test/src/test/java/cn/idev/excel/test/demo/read/ReadTest.java
@@ -53,7 +53,7 @@
             for (DemoData demoData : dataList) {
                 log.info("读取到一条数据{}", JSON.toJSONString(demoData));
             }
-        })).sheet().doRead();
+        })).numRows(2).sheet().doRead();
 
         // 写法2:
         // 匿名内部类 不用额外写一个DemoDataListener
@@ -105,6 +105,7 @@
         try (ExcelReader excelReader = EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).build()) {
             // 构建一个sheet 这里可以指定名字或者no
             ReadSheet readSheet = EasyExcel.readSheet(0).build();
+            readSheet.setNumRows(2);
             // 读取一个sheet
             excelReader.read(readSheet);
         }
@@ -124,7 +125,7 @@
     public void indexOrNameRead() {
         String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
         // 这里默认读取第一个sheet
-        EasyExcel.read(fileName, IndexOrNameData.class, new IndexOrNameDataListener()).sheet().doRead();
+        EasyExcel.read(fileName, IndexOrNameData.class, new IndexOrNameDataListener()).numRows(1).sheet().doRead();
     }
 
     /**
diff --git a/fastexcel-test/src/test/resources/compatibility/t01.xls b/fastexcel-test/src/test/resources/compatibility/t01.xls
index e69de29..eb0782f 100644
--- a/fastexcel-test/src/test/resources/compatibility/t01.xls
+++ b/fastexcel-test/src/test/resources/compatibility/t01.xls
Binary files differ
diff --git a/fastexcel-test/src/test/resources/compatibility/t02.xlsx b/fastexcel-test/src/test/resources/compatibility/t02.xlsx
index e69de29..b8d755d 100644
--- a/fastexcel-test/src/test/resources/compatibility/t02.xlsx
+++ b/fastexcel-test/src/test/resources/compatibility/t02.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/compatibility/t03.xlsx b/fastexcel-test/src/test/resources/compatibility/t03.xlsx
index e69de29..3a31ef7 100644
--- a/fastexcel-test/src/test/resources/compatibility/t03.xlsx
+++ b/fastexcel-test/src/test/resources/compatibility/t03.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/compatibility/t04.xlsx b/fastexcel-test/src/test/resources/compatibility/t04.xlsx
index e69de29..7c95d42 100644
--- a/fastexcel-test/src/test/resources/compatibility/t04.xlsx
+++ b/fastexcel-test/src/test/resources/compatibility/t04.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/compatibility/t05.xlsx b/fastexcel-test/src/test/resources/compatibility/t05.xlsx
index e69de29..248ec7d 100644
--- a/fastexcel-test/src/test/resources/compatibility/t05.xlsx
+++ b/fastexcel-test/src/test/resources/compatibility/t05.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/compatibility/t06.xlsx b/fastexcel-test/src/test/resources/compatibility/t06.xlsx
index e69de29..b27be02 100644
--- a/fastexcel-test/src/test/resources/compatibility/t06.xlsx
+++ b/fastexcel-test/src/test/resources/compatibility/t06.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/compatibility/t07.xlsx b/fastexcel-test/src/test/resources/compatibility/t07.xlsx
index e69de29..a7b0eac 100644
--- a/fastexcel-test/src/test/resources/compatibility/t07.xlsx
+++ b/fastexcel-test/src/test/resources/compatibility/t07.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/compatibility/t09.xlsx b/fastexcel-test/src/test/resources/compatibility/t09.xlsx
index e69de29..0b29141 100644
--- a/fastexcel-test/src/test/resources/compatibility/t09.xlsx
+++ b/fastexcel-test/src/test/resources/compatibility/t09.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/converter/converter03.xls b/fastexcel-test/src/test/resources/converter/converter03.xls
index e69de29..89c2ab6 100644
--- a/fastexcel-test/src/test/resources/converter/converter03.xls
+++ b/fastexcel-test/src/test/resources/converter/converter03.xls
Binary files differ
diff --git a/fastexcel-test/src/test/resources/converter/converter07.xlsx b/fastexcel-test/src/test/resources/converter/converter07.xlsx
index e69de29..99ace69 100644
--- a/fastexcel-test/src/test/resources/converter/converter07.xlsx
+++ b/fastexcel-test/src/test/resources/converter/converter07.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/converter/img.jpg b/fastexcel-test/src/test/resources/converter/img.jpg
index e69de29..953f39f 100644
--- a/fastexcel-test/src/test/resources/converter/img.jpg
+++ b/fastexcel-test/src/test/resources/converter/img.jpg
Binary files differ
diff --git a/fastexcel-test/src/test/resources/dataformat/dataformat.xls b/fastexcel-test/src/test/resources/dataformat/dataformat.xls
index e69de29..95c306c 100644
--- a/fastexcel-test/src/test/resources/dataformat/dataformat.xls
+++ b/fastexcel-test/src/test/resources/dataformat/dataformat.xls
Binary files differ
diff --git a/fastexcel-test/src/test/resources/dataformat/dataformat.xlsx b/fastexcel-test/src/test/resources/dataformat/dataformat.xlsx
index e69de29..34a05cc 100644
--- a/fastexcel-test/src/test/resources/dataformat/dataformat.xlsx
+++ b/fastexcel-test/src/test/resources/dataformat/dataformat.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/dataformat/dataformatv2.xlsx b/fastexcel-test/src/test/resources/dataformat/dataformatv2.xlsx
index e69de29..c49aa04 100644
--- a/fastexcel-test/src/test/resources/dataformat/dataformatv2.xlsx
+++ b/fastexcel-test/src/test/resources/dataformat/dataformatv2.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/demo/cellDataDemo.xlsx b/fastexcel-test/src/test/resources/demo/cellDataDemo.xlsx
index e69de29..947229c 100644
--- a/fastexcel-test/src/test/resources/demo/cellDataDemo.xlsx
+++ b/fastexcel-test/src/test/resources/demo/cellDataDemo.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/demo/demo.xlsx b/fastexcel-test/src/test/resources/demo/demo.xlsx
index e69de29..662bb97 100644
--- a/fastexcel-test/src/test/resources/demo/demo.xlsx
+++ b/fastexcel-test/src/test/resources/demo/demo.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/demo/extra.xlsx b/fastexcel-test/src/test/resources/demo/extra.xlsx
index e69de29..4936b05 100644
--- a/fastexcel-test/src/test/resources/demo/extra.xlsx
+++ b/fastexcel-test/src/test/resources/demo/extra.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/demo/fill/complex.xlsx b/fastexcel-test/src/test/resources/demo/fill/complex.xlsx
index e69de29..5376713 100644
--- a/fastexcel-test/src/test/resources/demo/fill/complex.xlsx
+++ b/fastexcel-test/src/test/resources/demo/fill/complex.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/demo/fill/complexFillWithTable.xlsx b/fastexcel-test/src/test/resources/demo/fill/complexFillWithTable.xlsx
index e69de29..4de1a1e 100644
--- a/fastexcel-test/src/test/resources/demo/fill/complexFillWithTable.xlsx
+++ b/fastexcel-test/src/test/resources/demo/fill/complexFillWithTable.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/demo/fill/composite.xlsx b/fastexcel-test/src/test/resources/demo/fill/composite.xlsx
index e69de29..c76a2b1 100644
--- a/fastexcel-test/src/test/resources/demo/fill/composite.xlsx
+++ b/fastexcel-test/src/test/resources/demo/fill/composite.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/demo/fill/horizontal.xlsx b/fastexcel-test/src/test/resources/demo/fill/horizontal.xlsx
index e69de29..c8b4564 100644
--- a/fastexcel-test/src/test/resources/demo/fill/horizontal.xlsx
+++ b/fastexcel-test/src/test/resources/demo/fill/horizontal.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/demo/fill/list.xlsx b/fastexcel-test/src/test/resources/demo/fill/list.xlsx
index e69de29..d29e05e 100644
--- a/fastexcel-test/src/test/resources/demo/fill/list.xlsx
+++ b/fastexcel-test/src/test/resources/demo/fill/list.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/demo/fill/simple.xlsx b/fastexcel-test/src/test/resources/demo/fill/simple.xlsx
index e69de29..7514d1d 100644
--- a/fastexcel-test/src/test/resources/demo/fill/simple.xlsx
+++ b/fastexcel-test/src/test/resources/demo/fill/simple.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/extra/extra.xls b/fastexcel-test/src/test/resources/extra/extra.xls
index e69de29..89f389b 100644
--- a/fastexcel-test/src/test/resources/extra/extra.xls
+++ b/fastexcel-test/src/test/resources/extra/extra.xls
Binary files differ
diff --git a/fastexcel-test/src/test/resources/extra/extra.xlsx b/fastexcel-test/src/test/resources/extra/extra.xlsx
index e69de29..4936b05 100644
--- a/fastexcel-test/src/test/resources/extra/extra.xlsx
+++ b/fastexcel-test/src/test/resources/extra/extra.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/extra/extraRelationships.xlsx b/fastexcel-test/src/test/resources/extra/extraRelationships.xlsx
index e69de29..5784cd8 100644
--- a/fastexcel-test/src/test/resources/extra/extraRelationships.xlsx
+++ b/fastexcel-test/src/test/resources/extra/extraRelationships.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/fill/annotation.xls b/fastexcel-test/src/test/resources/fill/annotation.xls
index e69de29..de09678 100644
--- a/fastexcel-test/src/test/resources/fill/annotation.xls
+++ b/fastexcel-test/src/test/resources/fill/annotation.xls
Binary files differ
diff --git a/fastexcel-test/src/test/resources/fill/annotation.xlsx b/fastexcel-test/src/test/resources/fill/annotation.xlsx
index e69de29..2a4a92b 100644
--- a/fastexcel-test/src/test/resources/fill/annotation.xlsx
+++ b/fastexcel-test/src/test/resources/fill/annotation.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/fill/byName.xls b/fastexcel-test/src/test/resources/fill/byName.xls
index e69de29..e07fd50 100644
--- a/fastexcel-test/src/test/resources/fill/byName.xls
+++ b/fastexcel-test/src/test/resources/fill/byName.xls
Binary files differ
diff --git a/fastexcel-test/src/test/resources/fill/byName.xlsx b/fastexcel-test/src/test/resources/fill/byName.xlsx
index e69de29..327e055 100644
--- a/fastexcel-test/src/test/resources/fill/byName.xlsx
+++ b/fastexcel-test/src/test/resources/fill/byName.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/fill/complex.xls b/fastexcel-test/src/test/resources/fill/complex.xls
index e69de29..d575895 100644
--- a/fastexcel-test/src/test/resources/fill/complex.xls
+++ b/fastexcel-test/src/test/resources/fill/complex.xls
Binary files differ
diff --git a/fastexcel-test/src/test/resources/fill/complex.xlsx b/fastexcel-test/src/test/resources/fill/complex.xlsx
index e69de29..5376713 100644
--- a/fastexcel-test/src/test/resources/fill/complex.xlsx
+++ b/fastexcel-test/src/test/resources/fill/complex.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/fill/composite.xls b/fastexcel-test/src/test/resources/fill/composite.xls
index e69de29..e48aa0c 100644
--- a/fastexcel-test/src/test/resources/fill/composite.xls
+++ b/fastexcel-test/src/test/resources/fill/composite.xls
Binary files differ
diff --git a/fastexcel-test/src/test/resources/fill/composite.xlsx b/fastexcel-test/src/test/resources/fill/composite.xlsx
index e69de29..c76a2b1 100644
--- a/fastexcel-test/src/test/resources/fill/composite.xlsx
+++ b/fastexcel-test/src/test/resources/fill/composite.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/fill/horizontal.xls b/fastexcel-test/src/test/resources/fill/horizontal.xls
index e69de29..570f901 100644
--- a/fastexcel-test/src/test/resources/fill/horizontal.xls
+++ b/fastexcel-test/src/test/resources/fill/horizontal.xls
Binary files differ
diff --git a/fastexcel-test/src/test/resources/fill/horizontal.xlsx b/fastexcel-test/src/test/resources/fill/horizontal.xlsx
index e69de29..c8b4564 100644
--- a/fastexcel-test/src/test/resources/fill/horizontal.xlsx
+++ b/fastexcel-test/src/test/resources/fill/horizontal.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/fill/simple.xls b/fastexcel-test/src/test/resources/fill/simple.xls
index e69de29..317ef6d 100644
--- a/fastexcel-test/src/test/resources/fill/simple.xls
+++ b/fastexcel-test/src/test/resources/fill/simple.xls
Binary files differ
diff --git a/fastexcel-test/src/test/resources/fill/simple.xlsx b/fastexcel-test/src/test/resources/fill/simple.xlsx
index e69de29..a441eba 100644
--- a/fastexcel-test/src/test/resources/fill/simple.xlsx
+++ b/fastexcel-test/src/test/resources/fill/simple.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/fill/style.xls b/fastexcel-test/src/test/resources/fill/style.xls
index e69de29..3127743 100644
--- a/fastexcel-test/src/test/resources/fill/style.xls
+++ b/fastexcel-test/src/test/resources/fill/style.xls
Binary files differ
diff --git a/fastexcel-test/src/test/resources/fill/style.xlsx b/fastexcel-test/src/test/resources/fill/style.xlsx
index e69de29..062540d 100644
--- a/fastexcel-test/src/test/resources/fill/style.xlsx
+++ b/fastexcel-test/src/test/resources/fill/style.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/large/fill.xlsx b/fastexcel-test/src/test/resources/large/fill.xlsx
index e69de29..c3c376d 100644
--- a/fastexcel-test/src/test/resources/large/fill.xlsx
+++ b/fastexcel-test/src/test/resources/large/fill.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/large/large07.xlsx b/fastexcel-test/src/test/resources/large/large07.xlsx
index e69de29..a317e71 100644
--- a/fastexcel-test/src/test/resources/large/large07.xlsx
+++ b/fastexcel-test/src/test/resources/large/large07.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/multiplesheets/multiplesheets.xls b/fastexcel-test/src/test/resources/multiplesheets/multiplesheets.xls
index e69de29..a560128 100644
--- a/fastexcel-test/src/test/resources/multiplesheets/multiplesheets.xls
+++ b/fastexcel-test/src/test/resources/multiplesheets/multiplesheets.xls
Binary files differ
diff --git a/fastexcel-test/src/test/resources/multiplesheets/multiplesheets.xlsx b/fastexcel-test/src/test/resources/multiplesheets/multiplesheets.xlsx
index e69de29..f90680a 100644
--- a/fastexcel-test/src/test/resources/multiplesheets/multiplesheets.xlsx
+++ b/fastexcel-test/src/test/resources/multiplesheets/multiplesheets.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/simple/simple07.xlsx b/fastexcel-test/src/test/resources/simple/simple07.xlsx
index e69de29..3d25fcd 100644
--- a/fastexcel-test/src/test/resources/simple/simple07.xlsx
+++ b/fastexcel-test/src/test/resources/simple/simple07.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/temp/issue1663/template.xlsx b/fastexcel-test/src/test/resources/temp/issue1663/template.xlsx
index e69de29..a968ff4 100644
--- a/fastexcel-test/src/test/resources/temp/issue1663/template.xlsx
+++ b/fastexcel-test/src/test/resources/temp/issue1663/template.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/temp/issue2443/date1.xlsx b/fastexcel-test/src/test/resources/temp/issue2443/date1.xlsx
index e69de29..92ef811 100644
--- a/fastexcel-test/src/test/resources/temp/issue2443/date1.xlsx
+++ b/fastexcel-test/src/test/resources/temp/issue2443/date1.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/temp/issue2443/date2.xlsx b/fastexcel-test/src/test/resources/temp/issue2443/date2.xlsx
index e69de29..c6feb32 100644
--- a/fastexcel-test/src/test/resources/temp/issue2443/date2.xlsx
+++ b/fastexcel-test/src/test/resources/temp/issue2443/date2.xlsx
Binary files differ
diff --git a/fastexcel-test/src/test/resources/template/template03.xls b/fastexcel-test/src/test/resources/template/template03.xls
index e69de29..7c17eee 100644
--- a/fastexcel-test/src/test/resources/template/template03.xls
+++ b/fastexcel-test/src/test/resources/template/template03.xls
Binary files differ
diff --git a/fastexcel-test/src/test/resources/template/template07.xlsx b/fastexcel-test/src/test/resources/template/template07.xlsx
index e69de29..a046fbc 100644
--- a/fastexcel-test/src/test/resources/template/template07.xlsx
+++ b/fastexcel-test/src/test/resources/template/template07.xlsx
Binary files differ