使用 Apache POI 将 Excel 转换成 Html 工具类

本文介绍了一种将Excel文件转换为HTML格式的工具类实现,包括处理Excel中的样式、公式和合并单元格,以实现网页上的Excel展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有时需要将Excel展示在页面上,所以需要将Excel转化为html,这里封装一个工具类。

1.访问效果

Excel页面:

img

页面效果:

img

2.工具类代码

ExcelToHtmlUtil.java

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Test;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p> @Title ExcelToHtmlUtil
 * <p> @Description excel转化为html工具类
 *
 * @author ACGkaka
 * @date 2020/4/11 2:41
 */
public class ExcelToHtmlUtil {

    @Test
    public void run() throws IOException {
        String filePath = "F:\\Test1.xlsx";
        boolean isWithStyle = true;
        List<Map<String, String>> excelMapList = ExcelToHtmlUtil.readExcelToHtml(filePath, isWithStyle);
        System.out.println("excelMapList: " + excelMapList);
        getHtml(excelMapList, "F:\\test.html");
        System.out.println("文件写入完成");
    }

    /**
     * 包装成html
     */
    private static void getHtml(List<Map<String, String>> excelMapList, String path) throws IOException {
        Files.newBufferedWriter(Paths.get(path));
        String html = new StringBuffer()
                .append("<html>")
                .append("   <head>")
                .append("       <title>This is a Test</title>")
                .append("   </head>")
                .append("   <body>")
                .append(        excelMapList.get(0).get("content"))
                .append("   </body>")
                .append("</html>").toString();
        Files.write(Paths.get("F:/test.html"), html.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * excel转html入口
     */
    private static List<Map<String, String>> readExcelToHtml(String filePath, boolean isWithStyle) {
        List<Map<String, String>> excelInfoMapList = null;
        // 文件对象
        File file = new File(filePath);
        try (
                // 文件流
                InputStream inputStream = new FileInputStream(file)
        ) {
            // 创建工作簿
            Workbook workbook = WorkbookFactory.create(inputStream);
            // Excel类型
            if (workbook instanceof HSSFWorkbook) {
                // 2003
                HSSFWorkbook hssfWorkbook = (HSSFWorkbook) workbook;
                // 获取Excel信息
                excelInfoMapList = getExcelInfo(hssfWorkbook, isWithStyle);
            } else if (workbook instanceof XSSFWorkbook) {
                // 2007
                XSSFWorkbook xssfWorkbook = (XSSFWorkbook) workbook;
                // 获取Excel信息
                excelInfoMapList = getExcelInfo(xssfWorkbook, isWithStyle);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return excelInfoMapList;
    }

    /**
     * 获取Excel信息
     */
    private static List<Map<String, String>> getExcelInfo(Workbook workbook, boolean isWithStyle) {
        List<Map<String, String>> htmlMapList = new ArrayList<>();
        // 获取所有sheet
        int sheets = workbook.getNumberOfSheets();
        // 用于计算公式
        FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
        // 遍历sheets
        for (int sheetIndex = 0; sheetIndex < sheets; sheetIndex++) {
            // 用于保存sheet信息
            Map<String, String> sheetMap = new HashMap<>();
            // 获取sheet名
            String sheetName = workbook.getSheetName(sheetIndex);
            // 存储sheet名
            sheetMap.put("sheetName", sheetName);
            StringBuffer stringBuffer = new StringBuffer();
            // 获取第一个sheet信息
            Sheet sheet = workbook.getSheetAt(sheetIndex);
            // 行数
            int lastRowNum = sheet.getLastRowNum();
            // 获取合并后的单元格行列坐标
            Map<String, String>[] map = getRowSpanColSpan(sheet);
            stringBuffer.append("<table style='border-collapse:collapse;' width='100%'>");
            Row row;
            Cell cell;
            for (int rowNum = sheet.getFirstRowNum(); rowNum <= lastRowNum; rowNum++) {
                row = sheet.getRow(rowNum);
                if (row == null) {
                    stringBuffer.append("<tr><td>&nbsp;</td></tr>");
                    continue;
                }
                stringBuffer.append("<tr>");
                // 列数
                short lastCellNum = row.getLastCellNum();
                for (int colNum = 0; colNum <= lastCellNum; colNum++) {
                    // 获取列
                    cell = row.getCell(colNum);
                    // 空白单元格
                    if (cell == null) {
                        stringBuffer.append("<td>&nbsp;</td>");
                        continue;
                    }
                    // 获取列值
                    String cellValue = getCellValue(cell, evaluator);
                    if (map[0].containsKey(rowNum + "," + colNum)) {
                        String point = map[0].get(rowNum + "," + colNum);
                        map[0].remove(rowNum + "," + colNum);
                        int bottomRow = Integer.valueOf(point.split(",")[0]);
                        int bottomCol = Integer.valueOf(point.split(",")[1]);
                        int rowSpan = bottomRow - rowNum + 1;
                        int colSpan = bottomCol - colNum + 1;
                        stringBuffer.append("<td rowspan= '").append(rowSpan).append("' colSpan= '").append(colSpan).append("' ");
                    } else if (map[1].containsKey(rowNum + "," + colNum)) {
                        map[1].remove(rowNum + "," + colNum);
                        continue;
                    } else {
                        stringBuffer.append("<td ");
                    }

                    // 判断是否包含样式
                    if (isWithStyle) {
                        // 处理单元格样式
                        dealExcelStyle(workbook, sheet, cell, stringBuffer, rowNum == lastRowNum || rowNum > 500);
                    }

                    stringBuffer.append(">");
                    if (cellValue == null || "".equals(cellValue.trim())) {
                        stringBuffer.append(" &nbsp; ");
                    } else {
                        stringBuffer.append(cellValue.replace(String.valueOf((char) 160), "&nbsp;"));
                    }
                    stringBuffer.append("</td>");
                }
                stringBuffer.append("</tr>");
                if (rowNum > 500) {
                    stringBuffer.append("<tr><td colspan= '500'>数据量太大,请下载Excel查看更多数据……</td></tr>");
                    break;
                }
            }
            stringBuffer.append("</table>");
            sheetMap.put("content", stringBuffer.toString());
            htmlMapList.add(sheetMap);
        }
        return htmlMapList;
    }

    /**
     * 获取列值
     */
    private static String getCellValue(Cell cell, FormulaEvaluator evaluator) {
        String result;
        switch (cell.getCellType()) {
            case NUMERIC: // 数字类型
                if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    SimpleDateFormat simpleDateFormat;
                    // 时间
                    if (cell.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("h:mm")) {
                        simpleDateFormat = new SimpleDateFormat("HH:mm");
                    } else {
                        // 日期
                        simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    }
                    Date date = cell.getDateCellValue();
                    result = simpleDateFormat.format(date);
                } else if (cell.getCellStyle().getDataFormat() == 58) {
                    // 处理自定义日期格式:m月d日(通过判断单元格格式的id解决,id值为58)
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    double value = cell.getNumericCellValue();
                    Date date = DateUtil.getJavaDate(value);
                    result = simpleDateFormat.format(date);
                } else {
                    double value = cell.getNumericCellValue();
                    CellStyle cellStyle = cell.getCellStyle();
                    DecimalFormat decimalFormat = new DecimalFormat();
                    String temp = cellStyle.getDataFormatString();
                    // 单元格设置成常规
                    if (temp.equals("General")) {
                        decimalFormat.applyPattern("#");
                    }
                    result = decimalFormat.format(value);
                }
                break;
            case STRING: // 字符串
                result = cell.getStringCellValue();
                break;
            case FORMULA: // 公式
                CellValue cellVal = evaluator.evaluate(cell);
                result = (cellVal.getCellType() == CellType.NUMERIC) ? String.valueOf(cellVal.getNumberValue()) : cellVal.getStringValue();
                break;
            default:
                result = "";
                break;
        }
        return result;
    }

    /**
     * 合并单元格
     *
     * @return
     */
    private static Map<String, String>[] getRowSpanColSpan(Sheet sheet) {
        Map<String, String> map0 = new HashMap<>();
        Map<String, String> map1 = new HashMap<>();
        // 获取合并后的单元格数量
        int mergeNum = sheet.getNumMergedRegions();
        CellRangeAddress range;
        for (int i = 0; i < mergeNum; i++) {
            range = sheet.getMergedRegion(i);
            int topRow = range.getFirstRow();
            int topCol = range.getFirstColumn();
            int bottomRow = range.getLastRow();
            int bottomCol = range.getLastColumn();
            map0.put(topRow + "," + topCol, bottomRow + "," + bottomCol);
            int tempRow = topRow;
            while (tempRow <= bottomRow) {
                int tempCol = topCol;
                while (tempCol <= bottomCol) {
                    map1.put(tempRow + "," + tempCol, "");
                    tempCol++;
                }
                tempRow++;
            }
            map1.remove(topRow + "," + topCol);
        }
        return new Map[]{map0, map1};
    }

    private static String[] borders = {"border-top:", "border-right:", "border-bottom:", "border-left:"};
    private static String[] borderStyles = {"solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid", "solid", "solid", "solid", "solid"};

    /**
     * 处理单元格样式
     */
    private static void dealExcelStyle(Workbook wb, Sheet sheet, Cell cell, StringBuffer sb, boolean isLastRow) {
        CellStyle cellStyle = cell.getCellStyle();
        if (cellStyle != null) {
            HorizontalAlignment alignment = cellStyle.getAlignment();
            // 单元格内容的水平对齐方式
            sb.append("align='" + convertAlignToHtml(alignment) + "' ");
            VerticalAlignment verticalAlignment = cellStyle.getVerticalAlignment();
            // 单元格中内容的垂直排列方式
            sb.append("valign='" + convertVerticalAlignToHtml(verticalAlignment) + "' ");

            if (wb instanceof XSSFWorkbook) {

                XSSFFont xf = ((XSSFCellStyle) cellStyle).getFont();
                boolean isBold = xf.getBold();
                sb.append("style='");
                sb.append("white-space: nowrap; ");
                sb.append("font-weight:" + (isBold ? "bold" : "normal") + "; ");   // 字体加粗
                sb.append("font-size:" + xf.getFontHeight() / 2 + "%; ");   // 字体大小

                XSSFColor xc = xf.getXSSFColor();
                if (xc != null && !"".equals(xc)) {
                    sb.append("color:#" + xc.getARGBHex().substring(2) + "; ");  // 字体颜色
                }

                XSSFColor bgColor = (XSSFColor) cellStyle.getFillForegroundColorColor();
                if (bgColor != null && !"".equals(bgColor)) {
                    sb.append("background-color:#" + bgColor.getARGBHex().substring(2) + "; ");  // 背景颜色
                }
                sb.append(getBorderStyle(0, cellStyle.getBorderTop(), ((XSSFCellStyle) cellStyle).getTopBorderXSSFColor()));
                sb.append(getBorderStyle(1, cellStyle.getBorderRight(), ((XSSFCellStyle) cellStyle).getRightBorderXSSFColor()));
                sb.append(getBorderStyle(3, cellStyle.getBorderLeft(), ((XSSFCellStyle) cellStyle).getLeftBorderXSSFColor()));
                sb.append(getBorderStyle(2, cellStyle.getBorderBottom(), ((XSSFCellStyle) cellStyle).getBottomBorderXSSFColor()));

            } else if (wb instanceof HSSFWorkbook) {

                HSSFFont hf = ((HSSFCellStyle) cellStyle).getFont(wb);
                boolean isBold = hf.getBold();
                short fontColor = hf.getColor();
                sb.append("style='");
                HSSFPalette palette = ((HSSFWorkbook) wb).getCustomPalette(); // 类HSSFPalette用于求的颜色的国际标准形式
                HSSFColor hc = palette.getColor(fontColor);
                sb.append("font-weight:" + (isBold ? "bold" : "normal") + ";"); // 字体加粗
                sb.append("font-size: " + hf.getFontHeight() / 2 + "%;"); // 字体大小
                String fontColorStr = convertToStardColor(hc);
                if (fontColorStr != null && !"".equals(fontColorStr.trim())) {
                    sb.append("color:" + fontColorStr + ";"); // 字体颜色
                }
                short bgColor = cellStyle.getFillForegroundColor();
                hc = palette.getColor(bgColor);
                String bgColorStr = convertToStardColor(hc);
                if (bgColorStr != null && !"".equals(bgColorStr.trim())) {
                    sb.append("background-color:" + bgColorStr + ";"); // 背景颜色
                }
                sb.append(getBorderStyle(palette, 0, cellStyle.getBorderTop(), cellStyle.getTopBorderColor()));
                sb.append(getBorderStyle(palette, 1, cellStyle.getBorderRight(), cellStyle.getRightBorderColor()));
                sb.append(getBorderStyle(palette, 3, cellStyle.getBorderLeft(), cellStyle.getLeftBorderColor()));
                sb.append(getBorderStyle(palette, 2, cellStyle.getBorderBottom(), cellStyle.getBottomBorderColor()));
            }

            sb.append("' ");
        }
    }

    /**
     * 垂直对齐方式
     *
     * @param verticalAlignment
     * @return
     */
    private static String convertVerticalAlignToHtml(VerticalAlignment verticalAlignment) {
        String align = "middle";
        switch (verticalAlignment) {
            case BOTTOM:
                align = "bottom";
                break;
            case CENTER:
                align = "center";
                break;
            case TOP:
                align = "top";
                break;
            default:
                break;
        }
        return align;
    }

    /**
     * 水平对齐方式
     */
    private static String convertAlignToHtml(HorizontalAlignment alignment) {
        String align = "left";
        switch (alignment) {
            case LEFT:
                align = "left";
                break;
            case CENTER:
                align = "center";
                break;
            case RIGHT:
                align = "right";
                break;
            default:
                break;
        }
        return align;
    }

    private static String getBorderStyle(int b, BorderStyle s, XSSFColor xc) {
        if (s == BorderStyle.NONE) {
            return borders[b] + borderStyles[s.getCode()] + "#d0d7e5 1px;";
        }
        if (xc != null) {
            String borderColorStr = xc.getARGBHex();
            borderColorStr = borderColorStr == null || borderColorStr.length() < 1 ? "#000000" : borderColorStr.substring(2);
            return borders[b] + borderStyles[s.getCode()] + borderColorStr + " 1px;";
        }

        return "";
    }

    private static String getBorderStyle(HSSFPalette palette, int b, BorderStyle s, short t) {
        if (s == BorderStyle.NONE) {
            return borders[b] + borderStyles[s.getCode()] + "#d0d7e5 1px;";
        }
        String borderColorStr = convertToStardColor(palette.getColor(t));
        borderColorStr = borderColorStr.length() < 1 ? "#000000" : borderColorStr;
        return borders[b] + borderStyles[s.getCode()] + borderColorStr + " 1px;";

    }

    private static String convertToStardColor(HSSFColor hc) {
        StringBuffer sb = new StringBuffer();
        if (hc != null) {
            if (HSSFColor.HSSFColorPredefined.AUTOMATIC.getIndex() == hc.getIndex()) {
                return null;
            }
            sb.append("#");
            for (int i = 0; i < hc.getTriplet().length; i++) {
                sb.append(fillWithZero(Integer.toHexString(hc.getTriplet()[i])));
            }
        }
        return sb.toString();
    }

    private static String fillWithZero(String str) {
        if (str != null && str.length() < 2) {
            return "0" + str;
        }
        return str;
    }
}





参考地址:https://www.cnblogs.com/alphajuns/p/12013575.html

进行了部分的优化:table宽度的自适应;单元格公式的计算;代码规范的完善。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不愿放下技术的小赵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值