POI将带图片html转excel

 参考easypoi

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.afterturn</groupId>
        <artifactId>easypoi</artifactId>
        <version>4.4.0</version>
    </parent>
    <artifactId>easypoi-base</artifactId>
    <dependencies>
        <!-- poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
        </dependency>
        <!-- Excel -->
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

        <!-- slf4j -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

HTML可以先用freemarker生成!!!

test1.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8"/>
	<title>Title</title>
	<style type = "text/css">
		body{
			font-family:SimHei;
			margin: 25mm 25mm 25mm 25mm;
			width: 542mm;
		}

	</style>
</head>
<body>

<table sheetName="test1" name="testName" border="1">
	<tr>
		<td style="height:110px;width:20px;">ma</td>
		<td></td>
	</tr>
	<tr>
		<th>Month</th>
		<th>Savi11ngs</th>
	</tr>
	<tr>
		<td>January</td>
		<td>1111111$100</td>
	</tr>
	<tr>
		<td name="img">
			<img src="data:png;base64,${file64Str}" width="600px" />
		</td>
		<td>

		</td>
	</tr>
</table>

</body>
</html>

mytester

package com.study.easypoi.test;

import com.study.easypoi.excel.ExcelXorHtmlUtil;
import com.study.easypoi.excel.entity.enmus.ExcelType;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.junit.Test;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Scanner;

@RestController
public class mytester {

 //获取批注对象  
        //   XSSFClientAnchor的参数说明:  
         //   参数   说明  
         //  dx1  第1个单元格中x轴的偏移量   
         //  dy1  第1个单元格中y轴的偏移量   
         //  dx2     第2个单元格中x轴的偏移量   
         //  dy2  第2个单元格中y轴的偏移量   
         //  col1 第1个单元格的列号   
         //  row1  第1个单元格的行号   
         //  col2 第2个单元格的列号   
         //  row2 第2个单元格的行号  
// 获取图片需要放置的位置
            /*
             * XSSFClientAnchor 参数
             * @param dx1  左上侧所在单元格里面左上角X坐标
             * @param dy1  左上侧所在单元格里面左上角Y坐标.
             * @param dx2  右下侧所在单元格里面左上角X坐标.
             * @param dy2  右下侧所在单元格里面左上角Y坐标.
             * @param col1 图片左侧所在col
             * @param row1 图片上侧所在row
             * @param col2 图片由侧所在col
             * @param row2 图片下侧所在row
             * */ 
        //(int dx1, int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2)

 public void insertPic(Workbook wb, XSSFSheet sheet) {
        BufferedImage bufferImg = null;
        try {
            ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
            bufferImg = ImageIO.read(new File("D:\\gitee\\easypoi-my-simple\\Freemarker-Excel.png"));
            ImageIO.write(bufferImg, "png", byteArrayOut);
            XSSFDrawing patriarch = sheet.createDrawingPatriarch();
            XSSFClientAnchor anchor = new XSSFClientAnchor(
                    0, 0,
                    250, 250,
                    (short) 0, 0,
                    (short) 1, 1);
            // 插入图片
            patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
            System.out.println("----Excle文件已生成------");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void insertPic(Workbook wb, HSSFSheet sheet) {
        BufferedImage bufferImg = null;
        try {
            ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
            bufferImg = ImageIO.read(new File("D:\\gitee\\easypoi-my-simple\\Freemarker-Excel.png"));
            ImageIO.write(bufferImg, "png", byteArrayOut);
            HSSFPatriarch  patriarch= sheet.createDrawingPatriarch();
            HSSFClientAnchor anchor = new HSSFClientAnchor(
                    0, 0,
                    250, 250,
                    (short) 0, 0,
                    (short) 1, 1);
            // 插入图片
            patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
            System.out.println("----Excle文件已生成------");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void htmlToExcelByStr() throws Exception {
        String path = mytester.class.getClassLoader().getResource("test1.html").getPath();
        StringBuilder html = new StringBuilder();
        Scanner s = new Scanner(getClass().getClassLoader().getResourceAsStream("test1.html"), "utf-8");
        while (s.hasNext()) {
            html.append(s.nextLine());
        }
        s.close();
        Workbook workbook = ExcelXorHtmlUtil.htmlToExcel(html.toString(), ExcelType.XSSF);
        File savefile = new File("D:\\gitee\\easypoi-my-simple");
        if (!savefile.exists()) {
            savefile.mkdirs();
        }
        FileOutputStream fos = new FileOutputStream("D:\\gitee\\easypoi-my-simple\\htmlToExcelByStr.xlsx");
        Sheet sheet = workbook.getSheetAt(0);
        insertPic(workbook, (XSSFSheet) sheet);
        workbook.write(fos);
        fos.close();

        workbook = ExcelXorHtmlUtil.htmlToExcel(html.toString(), ExcelType.HSSF);
        Sheet sheetH = workbook.getSheetAt(0);
        insertPic(workbook, (HSSFSheet) sheetH);

        fos = new FileOutputStream("D:\\gitee\\easypoi-my-simple\\htmlToExcelByStr.xls");
        workbook.write(fos);
        fos.close();
    }
}
PoiCssUtils
package com.study.easypoi.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.util.HSSFColor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PoiCssUtils {
    private static final Logger log = LoggerFactory.getLogger(PoiCssUtils.class);
    /**
     * matches #rgb
     */
    private static final String COLOR_PATTERN_VALUE_SHORT = "^(#(?:[a-f]|\\d){3})$";
    private static final Pattern COLOR_PATTERN_VALUE_SHORT_PATTERN = Pattern.compile("([a-f]|\\d)");
    /**
     * matches #rrggbb
     */
    private static final String COLOR_PATTERN_VALUE_LONG = "^(#(?:[a-f]|\\d{2}){3})$";
    /**
     * matches #rgb(r, g, b)
     **/
    private static final String COLOR_PATTERN_RGB = "^(rgb\\s*\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\))$";
    private static final Pattern INT_AND_PER_PATTERN = Pattern.compile("^(\\d*\\.?\\d+)\\s*(%)?$");
    private static final Pattern INT_PATTERN = Pattern.compile("^(\\d+)(?:\\w+|%)?$");

    public static String processColor(String color) {
        log.info("Process Color [{}].", color);
        String colorRtn = null;
        if (StringUtils.isNotBlank(color)) {
            HSSFColor poiColor = null;
            // #rgb -> #rrggbb
            if (color.matches(COLOR_PATTERN_VALUE_SHORT)) {
                log.debug("Short Hex Color [{}] Found.", color);
                StringBuffer sbColor = new StringBuffer();
                Matcher m = COLOR_PATTERN_VALUE_SHORT_PATTERN.matcher(color);
                while (m.find()) {
                    m.appendReplacement(sbColor, "$1$1");
                }
                colorRtn = sbColor.toString();
                log.debug("Translate Short Hex Color [{}] To [{}].", color, colorRtn);
            }
            // #rrggbb
            else if (color.matches(COLOR_PATTERN_VALUE_LONG)) {
                colorRtn = color;
                log.debug("Hex Color [{}] Found, Return.", color);
            }
            // rgb(r, g, b)
            else if (color.matches(COLOR_PATTERN_RGB)) {
                Matcher m = Pattern.compile(COLOR_PATTERN_RGB).matcher(color);
                if (m.matches()) {
                    log.debug("RGB Color [{}] Found.", color);
                    colorRtn = convertColor(calcColorValue(m.group(2)), calcColorValue(m.group(3)),
                            calcColorValue(m.group(4)));
                    log.debug("Translate RGB Color [{}] To Hex [{}].", color, colorRtn);
                }
            }
            // color name, red, green, ...
            else if ((poiColor = getHssfColor(color)) != null) {
                log.debug("Color Name [{}] Found.", color);
                short[] t = poiColor.getTriplet();
                colorRtn = convertColor(t[0], t[1], t[2]);
                log.debug("Translate Color Name [{}] To Hex [{}].", color, colorRtn);
            }
        }
        return colorRtn;
    }
    private static String convertColor(int r, int g, int b) {
        return String.format("#%02x%02x%02x", r, g, b);
    }
    private static HSSFColor getHssfColor(String color) {
        String tmpColor = color.replace("_", "").toUpperCase();
        switch (tmpColor) {
            case "BLACK":
                return HSSFColor.HSSFColorPredefined.BLACK.getColor();
            case "BROWN":
                return HSSFColor.HSSFColorPredefined.BROWN.getColor();
            case "OLIVEGREEN":
                return HSSFColor.HSSFColorPredefined.OLIVE_GREEN.getColor();
            case "DARKGREEN":
                return HSSFColor.HSSFColorPredefined.DARK_GREEN.getColor();
            case "DARKTEAL":
                return HSSFColor.HSSFColorPredefined.DARK_TEAL.getColor();
            case "DARKBLUE":
                return HSSFColor.HSSFColorPredefined.DARK_BLUE.getColor();
            case "INDIGO":
                return HSSFColor.HSSFColorPredefined.INDIGO.getColor();
            case "GREY80PERCENT":
                return HSSFColor.HSSFColorPredefined.GREY_80_PERCENT.getColor();
            case "ORANGE":
                return HSSFColor.HSSFColorPredefined.ORANGE.getColor();
            case "DARKYELLOW":
                return HSSFColor.HSSFColorPredefined.DARK_YELLOW.getColor();
            case "GREEN":
                return HSSFColor.HSSFColorPredefined.GREEN.getColor();
            case "TEAL":
                return HSSFColor.HSSFColorPredefined.TEAL.getColor();
            case "BLUE":
                return HSSFColor.HSSFColorPredefined.BLUE.getColor();
            case "BLUEGREY":
                return HSSFColor.HSSFColorPredefined.BLUE_GREY.getColor();
            case "GREY50PERCENT":
                return HSSFColor.HSSFColorPredefined.GREY_50_PERCENT.getColor();
            case "RED":
                return HSSFColor.HSSFColorPredefined.RED.getColor();
            case "LIGHTORANGE":
                return HSSFColor.HSSFColorPredefined.LIGHT_ORANGE.getColor();
            case "LIME":
                return HSSFColor.HSSFColorPredefined.LIME.getColor();
            case "SEAGREEN":
                return HSSFColor.HSSFColorPredefined.SEA_GREEN.getColor();
            case "AQUA":
                return HSSFColor.HSSFColorPredefined.AQUA.getColor();
            case "LIGHTBLUE":
                return HSSFColor.HSSFColorPredefined.LIGHT_BLUE.getColor();
            case "VIOLET":
                return HSSFColor.HSSFColorPredefined.VIOLET.getColor();
            case "GREY40PERCENT":
                return HSSFColor.HSSFColorPredefined.GREY_40_PERCENT.getColor();
            case "GOLD":
                return HSSFColor.HSSFColorPredefined.GOLD.getColor();
            case "YELLOW":
                return HSSFColor.HSSFColorPredefined.YELLOW.getColor();
            case "BRIGHTGREEN":
                return HSSFColor.HSSFColorPredefined.BRIGHT_GREEN.getColor();
            case "TURQUOISE":
                return HSSFColor.HSSFColorPredefined.TURQUOISE.getColor();
            case "DARKRED":
                return HSSFColor.HSSFColorPredefined.DARK_RED.getColor();
            case "SKYBLUE":
                return HSSFColor.HSSFColorPredefined.SKY_BLUE.getColor();
            case "PLUM":
                return HSSFColor.HSSFColorPredefined.PLUM.getColor();
            case "GREY25PERCENT":
                return HSSFColor.HSSFColorPredefined.GREY_25_PERCENT.getColor();
            case "ROSE":
                return HSSFColor.HSSFColorPredefined.ROSE.getColor();
            case "LIGHTYELLOW":
                return HSSFColor.HSSFColorPredefined.LIGHT_YELLOW.getColor();
            case "LIGHTGREEN":
                return HSSFColor.HSSFColorPredefined.LIGHT_GREEN.getColor();
            case "LIGHTTURQUOISE":
                return HSSFColor.HSSFColorPredefined.LIGHT_TURQUOISE.getColor();
            case "PALEBLUE":
                return HSSFColor.HSSFColorPredefined.PALE_BLUE.getColor();
            case "LAVENDER":
                return HSSFColor.HSSFColorPredefined.LAVENDER.getColor();
            case "WHITE":
                return HSSFColor.HSSFColorPredefined.WHITE.getColor();
            case "CORNFLOWERBLUE":
                return HSSFColor.HSSFColorPredefined.CORNFLOWER_BLUE.getColor();
            case "LEMONCHIFFON":
                return HSSFColor.HSSFColorPredefined.LEMON_CHIFFON.getColor();
            case "MAROON":
                return HSSFColor.HSSFColorPredefined.MAROON.getColor();
            case "ORCHID":
                return HSSFColor.HSSFColorPredefined.ORANGE.getColor();
            case "CORAL":
                return HSSFColor.HSSFColorPredefined.CORAL.getColor();
            case "ROYALBLUE":
                return HSSFColor.HSSFColorPredefined.ROYAL_BLUE.getColor();
            case "LIGHTCORNFLOWERBLUE":
                return HSSFColor.HSSFColorPredefined.LIGHT_CORNFLOWER_BLUE.getColor();
            case "TAN":
                return HSSFColor.HSSFColorPredefined.TAN.getColor();
        }
        return null;
    }
    public static int calcColorValue(String color) {
        int rtn = 0;
        // matches 64 or 64%
        Matcher m = INT_AND_PER_PATTERN.matcher(color);
        if (m.matches()) {
            // % not found
            if (m.group(2) == null) {
                rtn = Math.round(Float.parseFloat(m.group(1))) % 256;
            } else {
                rtn = Math.round(Float.parseFloat(m.group(1)) * 255 / 100) % 256;
            }
        }
        return rtn;
    }
    /**
     * check number string
     *
     * @param strValue string
     * @return true if string is number
     */
    public static boolean isNum(String strValue) {
        return StringUtils.isNotBlank(strValue) && strValue.matches("^\\d+(\\w+|%)?$");
    }
    /**
     * get int value of string
     *
     * @param strValue string value
     * @return int value
     */
    public static int getInt(String strValue) {
        int value = 0;
        if (StringUtils.isNotBlank(strValue)) {
            Matcher m = INT_PATTERN.matcher(strValue);
            if (m.find()) {
                value = Integer.parseInt(m.group(1));
            }
        }
        return value;
    }

}
PoiMergeCellUtil
package com.study.easypoi.util;

import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 纵向合并单元格工具类
 *
 */
public class PoiMergeCellUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(PoiMergeCellUtil.class);

    private PoiMergeCellUtil() {
    }

    public static void addMergedRegion(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) {
        try {
            sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
        } catch (Exception e) {
            LOGGER.debug("发生了一次合并单元格错误,{},{},{},{}", new Integer[]{
                    firstRow, lastRow, firstCol, lastCol
            });
            // 忽略掉合并的错误,不打印异常
            LOGGER.debug(e.getMessage(), e);
        }
    }

}
ExcelXorHtmlUtil
package com.study.easypoi.excel;

import com.study.easypoi.excel.entity.enmus.ExcelType;
import com.study.easypoi.excel.html.HtmlToExcelService;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelXorHtmlUtil {

    private ExcelXorHtmlUtil() {
    }

    /**
     * Html 读取Excel
     * @param html
     * @param type
     * @return
     */
    public static Workbook htmlToExcel(String html, ExcelType type) {
        Workbook workbook = null;
        if (ExcelType.HSSF.equals(type)) {
            workbook = new HSSFWorkbook();
        } else {
            workbook = new XSSFWorkbook();
        }
        new HtmlToExcelService().createSheet(html, workbook);
        return workbook;
    }
}
HtmlToExcelService
package com.study.easypoi.excel.html;

import com.study.easypoi.excel.export.styler.ExcelExportStylerDefaultImpl;
import com.study.easypoi.excel.html.css.CssParseService;
import com.study.easypoi.excel.html.css.ICssConvertToExcel;
import com.study.easypoi.excel.html.entity.ExcelCssConstant;
import com.study.easypoi.excel.html.entity.HtmlCssConstant;
import com.study.easypoi.excel.html.entity.style.CellStyleEntity;
import com.study.easypoi.util.PoiMergeCellUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.management.RuntimeErrorException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 读取Table数据生成Excel
 */
public class HtmlToExcelService {
    private final Logger LOGGER = LoggerFactory.getLogger(HtmlToExcelService.class);

    private Sheet sheet;
    private int maxRow = 0;
    private Map<String, CellStyle> cellStyles = new HashMap<String, CellStyle>();
    private Map<String, Object> cellsOccupied = new HashMap<String, Object>();
    private CellStyle defaultCellStyle;
    private CssParseService cssParse = new CssParseService();
    //样式
    private static final List<ICssConvertToExcel> STYLE_APPLIERS = new LinkedList<ICssConvertToExcel>();

    //Cell 高宽
    private static final List<ICssConvertToExcel> SHEET_APPLIERS = new LinkedList<ICssConvertToExcel>();


    public Workbook createSheet(String html, Workbook workbook) {
        Elements els = Jsoup.parseBodyFragment(html).select("table");
        Map<String, Sheet> sheets = new HashMap<String, Sheet>();
        Map<String, Integer> maxRowMap = new HashMap<String, Integer>();
        for (Element table : els) {
            String sheetName = table.attr(ExcelCssConstant.SHEET_NAME);

            if (StringUtils.isBlank(sheetName)) {
                LOGGER.error("table必须存在name属性!");
                throw new RuntimeErrorException(null, "table必须存在name属性");
            }

            if (sheets.containsKey(sheetName)) {
                maxRow = maxRowMap.get(sheetName);
                //cellStyles = csStyleMap.get(sheetName);
                //cellsOccupied = cellsOccupiedMap.get(sheetName);
                sheet = sheets.get(sheetName);
            } else {
                maxRow = 0;
                cellStyles.clear();
                cellsOccupied.clear();
                sheet = workbook.createSheet(sheetName);
            }
            //生成一个默认样式
            defaultCellStyle = new ExcelExportStylerDefaultImpl(workbook).stringNoneStyle(workbook, false);
            processTable(table);
            maxRowMap.put(sheetName, maxRow);
            sheets.put(sheetName, sheet);
        }
        return workbook;
    }

    private void processTable(Element table) {
        int rowIndex = 0;
        if (maxRow > 0) {
            // blank row
            maxRow += 2;
            rowIndex = maxRow;
        }
        LOGGER.debug("Interate Table Rows.");
        String freezeCol = null;
        int freezeColIndex = -1;
        for (Element row : table.select("tr")) {
            LOGGER.debug("Parse Table Row [{}]. Row Index [{}].", row, rowIndex);
            String freezeRow = row.attr(ExcelCssConstant.FREEZE_ROW);
            if ("true".equals(freezeRow)) {
                sheet.createFreezePane(0, rowIndex + 1, 0, rowIndex + 1);
            }
            int colIndex = 0;
            LOGGER.debug("Interate Cols.");
            for (Element td : row.select("td, th")) {
                freezeCol = td.attr(ExcelCssConstant.FREEZE_COL);
                if ("true".equals(freezeCol)) {
                    if (colIndex > freezeColIndex) {
                        freezeColIndex = colIndex;
                    }
                }

                // skip occupied cell
                while (cellsOccupied.get(rowIndex + "_" + colIndex) != null) {
                    LOGGER.debug("Cell [{}][{}] Has Been Occupied, Skip.", rowIndex, colIndex);
                    ++colIndex;
                }
                LOGGER.debug("Parse Col [{}], Col Index [{}].", td, colIndex);
                int rowSpan = 0;
                String strRowSpan = td.attr("rowspan");
                if (StringUtils.isNotBlank(strRowSpan) && StringUtils.isNumeric(strRowSpan)) {
                    LOGGER.debug("Found Row Span [{}].", strRowSpan);
                    rowSpan = Integer.parseInt(strRowSpan);
                }
                int colSpan = 0;
                String strColSpan = td.attr("colspan");
                if (StringUtils.isNotBlank(strColSpan) && StringUtils.isNumeric(strColSpan)) {
                    LOGGER.debug("Found Col Span [{}].", strColSpan);
                    colSpan = Integer.parseInt(strColSpan);
                }
                // col span & row span
                if (colSpan > 1 && rowSpan > 1) {
                    spanRowAndCol(td, rowIndex, colIndex, rowSpan, colSpan);
                    colIndex += colSpan;
                }
                // col span only
                else if (colSpan > 1) {
                    spanCol(td, rowIndex, colIndex, colSpan);
                    colIndex += colSpan;
                }
                // row span only
                else if (rowSpan > 1) {
                    spanRow(td, rowIndex, colIndex, rowSpan);
                    ++colIndex;
                }
                // no span
                else {
                    createCell(td, getOrCreateRow(rowIndex), colIndex).setCellValue(td.text());
                    ++colIndex;
                }
            }
            ++rowIndex;
        }
        if (freezeColIndex != -1) {
            sheet.createFreezePane(freezeColIndex + 1, 0, freezeColIndex + 1, 0);
        }
    }

    private void spanRowAndCol(Element td, int rowIndex, int colIndex, int rowSpan, int colSpan) {
        LOGGER.debug("Span Row And Col, From Row [{}], Span [{}].", rowIndex, rowSpan);
        LOGGER.debug("From Col [{}], Span [{}].", colIndex, colSpan);
        mergeRegion(rowIndex, rowIndex + rowSpan - 1, colIndex, colIndex + colSpan - 1);
        for (int i = 0; i < rowSpan; ++i) {
            Row row = getOrCreateRow(rowIndex + i);
            for (int j = 0; j < colSpan; ++j) {
                createCell(td, row, colIndex + j);
                cellsOccupied.put((rowIndex + i) + "_" + (colIndex + j), true);
            }
        }
        getOrCreateRow(rowIndex).getCell(colIndex).setCellValue(td.text());
    }

    private void spanCol(Element td, int rowIndex, int colIndex, int colSpan) {
        LOGGER.debug("Span Col, From Col [{}], Span [{}].", colIndex, colSpan);
        mergeRegion(rowIndex, rowIndex, colIndex, colIndex + colSpan - 1);
        Row row = getOrCreateRow(rowIndex);
        for (int i = 0; i < colSpan; ++i) {
            createCell(td, row, colIndex + i);
        }
        row.getCell(colIndex).setCellValue(td.text());
    }

    private void spanRow(Element td, int rowIndex, int colIndex, int rowSpan) {
        LOGGER.debug("Span Row , From Row [{}], Span [{}].", rowIndex, rowSpan);
        mergeRegion(rowIndex, rowIndex + rowSpan - 1, colIndex, colIndex);
        for (int i = 0; i < rowSpan; ++i) {
            Row row = getOrCreateRow(rowIndex + i);
            createCell(td, row, colIndex);
            cellsOccupied.put((rowIndex + i) + "_" + colIndex, true);
        }
        getOrCreateRow(rowIndex).getCell(colIndex).setCellValue(td.text());
    }

    private Cell createCell(Element td, Row row, int colIndex) {
        Cell cell = row.getCell(colIndex);
        if (cell == null) {
            LOGGER.debug("Create Cell [{}][{}].", row.getRowNum(), colIndex);
            cell = row.createCell(colIndex);
        }
        return applyStyle(td, cell);
    }

    private Row getOrCreateRow(int rowIndex) {
        Row row = sheet.getRow(rowIndex);
        if (row == null) {
            LOGGER.debug("Create New Row [{}].", rowIndex);
            row = sheet.createRow(rowIndex);
            if (rowIndex > maxRow) {
                maxRow = rowIndex;
            }
        }
        return row;
    }

    private Cell applyStyle(Element td, Cell cell) {
        String style = td.attr(HtmlCssConstant.STYLE);
        CellStyle cellStyle = null;
        if (StringUtils.isNotBlank(style)) {
            CellStyleEntity styleEntity = cssParse.parseStyle(style.trim());
            cellStyle = cellStyles.get(styleEntity.toString());
            if (cellStyle == null) {
                LOGGER.debug("No Cell Style Found In Cache, Parse New Style.");
                cellStyle = cell.getRow().getSheet().getWorkbook().createCellStyle();
                cellStyle.cloneStyleFrom(defaultCellStyle);
                for (ICssConvertToExcel cssConvert : STYLE_APPLIERS) {
                    cssConvert.convertToExcel(cell, cellStyle, styleEntity);
                }
                cellStyles.put(styleEntity.toString(), cellStyle);
            }
            for (ICssConvertToExcel cssConvert : SHEET_APPLIERS) {
                cssConvert.convertToExcel(cell, cellStyle, styleEntity);
            }
            if (cellStyles.size() >= 4000) {
                LOGGER.info(
                        "Custom Cell Style Exceeds 4000, Could Not Create New Style, Use Default Style.");
                cellStyle = defaultCellStyle;
            }
        } else {
            LOGGER.debug("Style is null ,Use Default Cell Style.");
            cellStyle = defaultCellStyle;
        }

        cell.setCellStyle(cellStyle);
        return cell;
    }

    private void mergeRegion(int firstRow, int lastRow, int firstCol, int lastCol) {
        LOGGER.debug("Merge Region, From Row [{}], To [{}].", firstRow, lastRow);
        LOGGER.debug("From Col [{}], To [{}].", firstCol, lastCol);
        PoiMergeCellUtil.addMergedRegion(sheet, firstRow, lastRow, firstCol, lastCol);
    }

}
HtmlCssConstant
package com.study.easypoi.excel.html.entity;

public interface HtmlCssConstant {
    // constants
    public final String PATTERN_LENGTH   = "\\d*\\.?\\d+\\s*(?:em|ex|cm|mm|q|in|pt|pc|px)?";
    public final String STYLE            = "style";
    public final String FONT             = "font";
    public final String FONT_STYLE       = "font-style";
    public final String FONT_FAMILY      = "font-family";
    public final String FONT_WEIGHT      = "font-weight";

    public final String FONT_SIZE        = "font-size";
    public final String COLOR            = "color";
    public final String BACKGROUND       = "background";
    public final String BACKGROUND_COLOR = "background-color";
    public final String ITALIC           = "italic";
    public final String BOLD             = "bold";

    // direction
    public final String TOP              = "top";
    public final String RIGHT            = "right";
    public final String BOTTOM           = "bottom";
    public final String LEFT             = "left";

    public final String BORDER           = "border";

    public final String WIDTH            = "width";
    public final String HEIGHT           = "height";

    public final String TEXT_ALIGN       = "text-align";
    public final String VETICAL_ALIGN    = "vertical-align";

    public final String TEXT_DECORATION  = "text-decoration";
    public final String NONE             = "none";
    public final String HIDDEN           = "hidden";
    public final String SOLID            = "solid";
    public final String DOUBLE           = "double";
    public final String DOTTED           = "dotted";
    public final String DASHED           = "dashed";

}
ExcelCssConstant
package com.study.easypoi.excel.html.entity;

/**
 * Excel 自定义处理的自定义Html标签
 */
public interface ExcelCssConstant {

    public final String SHEET_NAME = "sheetName";
    public final String FREEZE_ROW = "freezeRow";
    public final String FREEZE_COL = "freezeCol";

}
CssStyleFontEnity
package com.study.easypoi.excel.html.entity.style;

import lombok.Data;

/**
 * 字体样式
 */
@Data
public class CssStyleFontEnity {
    /**
     *  italic  浏览器会显示一个斜体的字体样式。
     */
    private String style;
    /**
     *  bold 定义粗体字符
     */
    private String weight;
    /**
     * 仅支持**px获取不带px的数字大小
     */
    private int    size;
    private String family;
    private String decoration;
    private String color;
}
package com.study.easypoi.excel.html.entity.style;


import lombok.Data;

/**
 * Cell 具有的样式
 */
@Data
public class CellStyleEntity {
    /**
     * 宽
     */
    private String                width;
    /**
     * 高
     */
    private String                height;
    /**
     * 边框
     */
    private CellStyleBorderEntity border;
    /**
     * 背景
     */
    private String                background;
    /**
     * 水平位置
     */
    private String                align;
    /**
     * 垂直位置
     */
    private String                vetical;
    /**
     * 字体设置
     */
    private CssStyleFontEnity     font;
}

package com.study.easypoi.excel.html.entity.style;

import lombok.Data;

/**
 * 边框样式
 */
@Data
public class CellStyleBorderEntity {

    private String borderLeftColor;

    private String borderRightColor;

    private String borderTopColor;

    private String borderBottomColor;

    private String borderLeftStyle;

    private String borderRightStyle;

    private String borderTopStyle;

    private String borderBottomStyle;

    private String borderLeftWidth;

    private String borderRightWidth;

    private String borderTopWidth;

    private String borderBottomWidth;
}

package com.study.easypoi.excel.html.css;

import com.study.easypoi.excel.html.entity.style.CellStyleEntity;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;

public interface ICssConvertToExcel {
    void convertToExcel(Cell cell, CellStyle cellStyle, CellStyleEntity styleEntity);
}

package com.study.easypoi.excel.html.css;

import com.study.easypoi.excel.html.entity.style.CellStyleBorderEntity;
import com.study.easypoi.excel.html.entity.style.CellStyleEntity;
import com.study.easypoi.excel.html.entity.style.CssStyleFontEnity;
import com.study.easypoi.util.PoiCssUtils;
import com.study.easypoi.excel.html.entity.HtmlCssConstant;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 把Css样式解析成对应的Model
 */
public class CssParseService {

    private static final Logger log = LoggerFactory.getLogger(CssParseService.class);
    private static final Pattern STYLE_PATTERN =  Pattern.compile("(?:^|\\s+)(italic|oblique)(?:\\s+|$)");
    private static final Pattern WEIGHT_PATTERN =  Pattern.compile("(?:^|\\s+)(bold(?:er)?|[7-9]00)(?:\\s+|$)");

    private final static Set<String> BORDER_STYLES = new HashSet<String>() {
        {
            // Specifies no border
            add(HtmlCssConstant.NONE);
            // The same as "none", except in border conflict resolution for table elements
            add(HtmlCssConstant.HIDDEN);
            // Specifies a dotted border
            add(HtmlCssConstant.DOTTED);
            // Specifies a dashed border
            add(HtmlCssConstant.DASHED);
            // Specifies a solid border
            add(HtmlCssConstant.SOLID);
            // Specifies a double border
            add(HtmlCssConstant.DOUBLE);
        }
    };

    public CellStyleEntity parseStyle(String style) {
        Map<String, String> mapStyle = new HashMap<String, String>();
        for (String s : style.split("\\s*;\\s*")) {
            if (StringUtils.isNotBlank(s)) {
                String[] ss = s.split("\\s*\\:\\s*");
                if (ss.length == 2 && StringUtils.isNotBlank(ss[0])
                        && StringUtils.isNotBlank(ss[1])) {
                    String attrName = ss[0].toLowerCase();
                    String attrValue = ss[1];
                    // do not change font name
                    if (!HtmlCssConstant.FONT.equals(attrName) && !HtmlCssConstant.FONT_FAMILY.equals(attrName)) {
                        attrValue = attrValue.toLowerCase();
                    }
                    mapStyle.put(attrName, attrValue);
                }
            }
        }

        parseFontAttr(mapStyle);

        parseBackground(mapStyle);

        parseBorder(mapStyle);

        return mapToCellStyleEntity(mapStyle);
    }
    private void parseFontAttr(Map<String, String> mapRtn) {

        log.debug("Parse Font Style.");
        // color
        String color = PoiCssUtils.processColor(mapRtn.get(HtmlCssConstant.COLOR));
        if (StringUtils.isNotBlank(color)) {
            log.debug("Text Color [{}] Found.", color);
            mapRtn.put(HtmlCssConstant.COLOR, color);
        }
        // font
        String font = mapRtn.get(HtmlCssConstant.FONT);
        if (StringUtils.isNotBlank(font)
                && !ArrayUtils.contains(new String[] { "small-caps", "caption", "icon", "menu",
                        "message-box", "small-caption", "status-bar" },
                font)) {
            log.debug("Parse Font Attr [{}].", font);
            String[] ignoreStyles = new String[] { "normal",
                    // font weight normal
                    "[1-3]00" };
            StringBuffer sbFont = new StringBuffer(
                    font.replaceAll("^|\\s*" + StringUtils.join(ignoreStyles, "|") + "\\s+|$", " "));
            log.debug("Font Attr [{}] After Process Ingore.", sbFont);
            // style
            Matcher m = STYLE_PATTERN.matcher(sbFont.toString());
            if (m.find()) {
                sbFont.setLength(0);
                if (log.isDebugEnabled()) {
                    log.debug("Font Style [{}] Found.", m.group(1));
                }
                mapRtn.put(HtmlCssConstant.FONT_STYLE, HtmlCssConstant.ITALIC);
                m.appendReplacement(sbFont, " ");
                m.appendTail(sbFont);
            }
            // weight
            m = WEIGHT_PATTERN.matcher(sbFont.toString());
            if (m.find()) {
                sbFont.setLength(0);
                if (log.isDebugEnabled()) {
                    log.debug("Font Weight [{}](bold) Found.", m.group(1));
                }
                mapRtn.put(HtmlCssConstant.FONT_WEIGHT, HtmlCssConstant.BOLD);
                m.appendReplacement(sbFont, " ");
                m.appendTail(sbFont);
            }
            // size xx-small | x-small | small | medium | large | x-large | xx-large | 18px [/2]
            m = Pattern.compile(
                    // before blank or start
                    new StringBuilder("(?:^|\\s+)")
                            // font size
                            .append("(xx-small|x-small|small|medium|large|x-large|xx-large|").append("(?:")
                            .append(HtmlCssConstant.PATTERN_LENGTH).append("))")
                            // line height
                            .append("(?:\\s*\\/\\s*(").append(HtmlCssConstant.PATTERN_LENGTH).append("))?")
                            // after blank or end
                            .append("(?:\\s+|$)").toString())
                    .matcher(sbFont.toString());
            if (m.find()) {
                sbFont.setLength(0);
                log.debug("Font Size[/line-height] [{}] Found.", m.group());
                String fontSize = m.group(1);
                if (StringUtils.isNotBlank(fontSize)) {
                    fontSize = StringUtils.deleteWhitespace(fontSize);
                    log.debug("Font Size [{}].", fontSize);
                    if (fontSize.matches(HtmlCssConstant.PATTERN_LENGTH)) {
                        mapRtn.put(HtmlCssConstant.FONT_SIZE, fontSize);
                    } else {
                        log.info("Font Size [{}] Not Supported, Ignore.", fontSize);
                    }
                }
                String lineHeight = m.group(2);
                if (StringUtils.isNotBlank(lineHeight)) {
                    log.info("Line Height [{}] Not Supported, Ignore.", lineHeight);
                }
                m.appendReplacement(sbFont, " ");
                m.appendTail(sbFont);
            }
            // font family
            if (sbFont.length() > 0) {
                log.debug("Font Families [{}].", sbFont);
                // trim & remove '"
                String fontFamily = sbFont.toString().split("\\s*,\\s*")[0].trim()
                        .replaceAll("'|\"", "");
                log.debug("Use First Font Family [{}].", fontFamily);
                mapRtn.put(HtmlCssConstant.FONT_FAMILY, fontFamily);
            }
        }
        font = mapRtn.get(HtmlCssConstant.FONT_STYLE);
        if (ArrayUtils.contains(new String[] { HtmlCssConstant.ITALIC, "oblique" }, font)) {
            log.debug("Font Italic [{}] Found.", font);
            mapRtn.put(HtmlCssConstant.FONT_STYLE, HtmlCssConstant.ITALIC);
        }
        font = mapRtn.get(HtmlCssConstant.FONT_WEIGHT);
        if (StringUtils.isNotBlank(font) && Pattern.matches("^bold(?:er)?|[7-9]00$", font)) {
            log.debug("Font Weight [{}](bold) Found.", font);
            mapRtn.put(HtmlCssConstant.FONT_WEIGHT, HtmlCssConstant.BOLD);
        }
        font = mapRtn.get(HtmlCssConstant.FONT_SIZE);
        if (!PoiCssUtils.isNum(font)) {
            log.debug("Font Size [{}] Error.", font);
            mapRtn.remove(HtmlCssConstant.FONT_SIZE);
        }
    }
    private String parseBackground(Map<String, String> style) {
        String bg = style.get(HtmlCssConstant.BACKGROUND);
        String bgColor = null;
        if (StringUtils.isNotBlank(bg)) {
            for (String bgAttr : bg.split("(?<=\\)|\\w|%)\\s+(?=\\w)")) {
                if ((bgColor = PoiCssUtils.processColor(bgAttr)) != null) {
                    style.put(HtmlCssConstant.BACKGROUND_COLOR, bgColor);
                    break;
                }
            }
        }
        bg = style.get(HtmlCssConstant.BACKGROUND_COLOR);
        if (StringUtils.isNotBlank(bg) && (bgColor = PoiCssUtils.processColor(bg)) != null) {
            style.put(HtmlCssConstant.BACKGROUND_COLOR, bgColor);

        }
        if (bgColor != null) {
            bgColor = style.get(HtmlCssConstant.BACKGROUND_COLOR);
            if ("#ffffff".equals(bgColor)) {
                style.remove(HtmlCssConstant.BACKGROUND_COLOR);
            }
        }
        return null;
    }
    public void parseBorder(Map<String, String> style) {
        for (String pos : new String[] { null, HtmlCssConstant.TOP, HtmlCssConstant.RIGHT, HtmlCssConstant.BOTTOM, HtmlCssConstant.LEFT }) {
            // border[-attr]
            if (pos == null) {
                setBorderAttr(style, pos, style.get(HtmlCssConstant.BORDER));
                setBorderAttr(style, pos, style.get(HtmlCssConstant.BORDER + "-" + HtmlCssConstant.COLOR));
                setBorderAttr(style, pos, style.get(HtmlCssConstant.BORDER + "-" + HtmlCssConstant.WIDTH));
                setBorderAttr(style, pos, style.get(HtmlCssConstant.BORDER + "-" + HtmlCssConstant.STYLE));
            }
            // border-pos[-attr]
            else {
                setBorderAttr(style, pos, style.get(HtmlCssConstant.BORDER + "-" + pos));
                for (String attr : new String[] { HtmlCssConstant.COLOR, HtmlCssConstant.WIDTH, HtmlCssConstant.STYLE }) {
                    String attrName = HtmlCssConstant.BORDER + "-" + pos + "-" + attr;
                    String attrValue = style.get(attrName);
                    if (StringUtils.isNotBlank(attrValue)) {
                        style.put(attrName, attrValue);
                    }
                }
            }
        }
    }
    private CellStyleEntity mapToCellStyleEntity(Map<String, String> mapStyle) {
        CellStyleEntity entity = new CellStyleEntity();
        entity.setAlign(mapStyle.get(HtmlCssConstant.TEXT_ALIGN));
        entity.setVetical(mapStyle.get(HtmlCssConstant.VETICAL_ALIGN));
        entity.setBackground(parseBackground(mapStyle));
        entity.setHeight(mapStyle.get(HtmlCssConstant.HEIGHT));
        entity.setWidth(mapStyle.get(HtmlCssConstant.WIDTH));
        entity.setFont(getCssStyleFontEnity(mapStyle));
        entity.setBackground(mapStyle.get(HtmlCssConstant.BACKGROUND_COLOR));
        entity.setBorder(getCssStyleBorderEntity(mapStyle));
        return entity;
    }

    private void setBorderAttr(Map<String, String> mapBorder, String pos, String value) {
        if (StringUtils.isNotBlank(value)) {
            String borderColor = null;
            for (String borderAttr : value.split("\\s+")) {
                if ((borderColor = PoiCssUtils.processColor(borderAttr)) != null) {
                    setBorderAttr(mapBorder, pos, HtmlCssConstant.COLOR, borderColor);
                } else if (PoiCssUtils.isNum(borderAttr)) {
                    setBorderAttr(mapBorder, pos, HtmlCssConstant.WIDTH, borderAttr);
                } else if (BORDER_STYLES.contains(borderAttr)) {
                    setBorderAttr(mapBorder, pos, HtmlCssConstant.STYLE, borderAttr);
                } else {
                    log.info("Border Attr [{}] Is Not Suppoted.", borderAttr);
                }
            }
        }
    }

    private void setBorderAttr(Map<String, String> mapBorder, String pos, String attr,
                               String value) {
        if (StringUtils.isNotBlank(pos)) {
            mapBorder.put(HtmlCssConstant.BORDER + "-" + pos + "-" + attr, value);
        } else {
            for (String name : new String[] { HtmlCssConstant.TOP, HtmlCssConstant.RIGHT, HtmlCssConstant.BOTTOM, HtmlCssConstant.LEFT }) {
                mapBorder.put(HtmlCssConstant.BORDER + "-" + name + "-" + attr, value);
            }
        }
    }

    private CssStyleFontEnity getCssStyleFontEnity(Map<String, String> style) {
        CssStyleFontEnity font = new CssStyleFontEnity();
        font.setStyle(style.get(HtmlCssConstant.FONT_STYLE));
        int fontSize = PoiCssUtils.getInt(style.get(HtmlCssConstant.FONT_SIZE));
        if (fontSize > 0) {
            font.setSize(fontSize);
        }
        font.setWeight(style.get(HtmlCssConstant.FONT_WEIGHT));
        font.setFamily(style.get(HtmlCssConstant.FONT_FAMILY));
        font.setDecoration(style.get(HtmlCssConstant.TEXT_DECORATION));
        font.setColor(style.get(HtmlCssConstant.COLOR));
        return font;
    }
    private CellStyleBorderEntity getCssStyleBorderEntity(Map<String, String> mapStyle) {
        CellStyleBorderEntity border = new CellStyleBorderEntity();
        border.setBorderTopColor(mapStyle.get(HtmlCssConstant.BORDER + "-" + HtmlCssConstant.TOP + "-" + HtmlCssConstant.COLOR));
        border.setBorderBottomColor(mapStyle.get(HtmlCssConstant.BORDER + "-" + HtmlCssConstant.BOTTOM + "-" + HtmlCssConstant.COLOR));
        border.setBorderLeftColor(mapStyle.get(HtmlCssConstant.BORDER + "-" + HtmlCssConstant.LEFT + "-" + HtmlCssConstant.COLOR));
        border.setBorderRightColor(mapStyle.get(HtmlCssConstant.BORDER + "-" + HtmlCssConstant.RIGHT + "-" + HtmlCssConstant.COLOR));

        border.setBorderTopWidth(mapStyle.get(HtmlCssConstant.BORDER + "-" + HtmlCssConstant.TOP + "-" + HtmlCssConstant.WIDTH));
        border.setBorderBottomWidth(mapStyle.get(HtmlCssConstant.BORDER + "-" + HtmlCssConstant.BOTTOM + "-" + HtmlCssConstant.WIDTH));
        border.setBorderLeftWidth(mapStyle.get(HtmlCssConstant.BORDER + "-" + HtmlCssConstant.LEFT + "-" + HtmlCssConstant.WIDTH));
        border.setBorderRightWidth(mapStyle.get(HtmlCssConstant.BORDER + "-" + HtmlCssConstant.RIGHT + "-" + HtmlCssConstant.WIDTH));

        border.setBorderTopStyle(mapStyle.get(HtmlCssConstant.BORDER + "-" + HtmlCssConstant.TOP + "-" + HtmlCssConstant.STYLE));
        border.setBorderBottomStyle(mapStyle.get(HtmlCssConstant.BORDER + "-" + HtmlCssConstant.BOTTOM + "-" + HtmlCssConstant.STYLE));
        border.setBorderLeftStyle(mapStyle.get(HtmlCssConstant.BORDER + "-" + HtmlCssConstant.LEFT + "-" + HtmlCssConstant.STYLE));
        border.setBorderRightStyle(mapStyle.get(HtmlCssConstant.BORDER + "-" + HtmlCssConstant.RIGHT + "-" + HtmlCssConstant.STYLE));
        return border;
    }



}

package com.study.easypoi.excel.export.styler;

public interface IExcelExportStyler {
}
package com.study.easypoi.excel.export.styler;

import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;

public class ExcelExportStylerDefaultImpl extends AbstractExcelExportStyler implements IExcelExportStyler {

    public ExcelExportStylerDefaultImpl(Workbook workbook) {
        super.createStyles(workbook);
    }

    @Override
    public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) {
        CellStyle style = workbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setDataFormat(STRING_FORMAT);
        if (isWarp) {
            style.setWrapText(true);
        }
        return style;
    }

}
package com.study.easypoi.excel.export.styler;

import org.apache.poi.ss.usermodel.BuiltinFormats;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Workbook;

/**
 * 抽象接口提供两个公共方法
 */
public class AbstractExcelExportStyler implements IExcelExportStyler {

    //单行
    protected CellStyle stringNoneStyle;
    protected CellStyle stringNoneWrapStyle;
    //间隔行
    protected CellStyle stringSeptailStyle;
    protected CellStyle stringSeptailWrapStyle;

    protected Workbook workbook;

    protected static final short STRING_FORMAT = (short) BuiltinFormats.getBuiltinFormat("TEXT");

    protected void createStyles(Workbook workbook) {
        this.stringNoneStyle = stringNoneStyle(workbook, false);
        this.stringNoneWrapStyle = stringNoneStyle(workbook, true);
        this.stringSeptailStyle = stringSeptailStyle(workbook, false);
        this.stringSeptailWrapStyle = stringSeptailStyle(workbook, true);
        this.workbook = workbook;
    }

    public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) {
        return null;
    }
    public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) {
        return null;
    }

}
package com.study.easypoi.excel.entity.enmus;

/**
 * Excel Type
 */
public enum ExcelType {
    HSSF , XSSF;
}

导入图片时,xy轴偏移量没生效?主要原因竟然是偏移量的数值设置得不。。。够。。。大。。。

XSSFClientAnchor anchor = new XSSFClientAnchor(
        200000, 200000,
        100, 100,
        (short) 1, 2,
        (short) 5, 7);

参考 https://blog.csdn.net/u011279583/article/details/105092785/

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值