You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Java代码在JSP页面展示完整格式的Excel文件?

嘿,要在JSP页面完整展示带格式的Excel(不是光秃秃的纯数据),核心思路是把Excel的格式和内容转换成浏览器能渲染的HTML——毕竟浏览器本身没法直接解析Excel的私有格式信息。我给你整理了一套可行的实现方案,包括代码示例:

在JSP页面展示带完整格式的Excel文件

1. 准备依赖

首先得引入Apache POI相关工具包,它能帮我们解析Excel的内容和格式,还能辅助转换成HTML。如果用Maven,直接在pom.xml里加这些依赖:

<dependencies>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.5</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.5</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>4.1.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.11.0</version>
    </dependency>
</dependencies>

2. 编写Excel转HTML的工具类

这个类负责读取Excel文件,把单元格的内容、合并状态、字体样式、背景色等转换成对应的HTML代码:

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Iterator;

public class ExcelToHtmlConverter {

    public static String convertExcelToHtml(String excelFilePath) throws IOException {
        StringWriter htmlWriter = new StringWriter();
        Workbook workbook = null;

        // 判断Excel格式(.xls或.xlsx)
        if (excelFilePath.endsWith(".xls")) {
            workbook = new HSSFWorkbook(new FileInputStream(excelFilePath));
        } else if (excelFilePath.endsWith(".xlsx")) {
            workbook = new XSSFWorkbook(new FileInputStream(excelFilePath));
        } else {
            throw new IllegalArgumentException("仅支持.xls和.xlsx格式的Excel文件");
        }

        // 遍历每个工作表
        for (int sheetIdx = 0; sheetIdx < workbook.getNumberOfSheets(); sheetIdx++) {
            Sheet sheet = workbook.getSheetAt(sheetIdx);
            if (sheet == null) continue;

            htmlWriter.write("<table border='1' cellpadding='5' cellspacing='0' style='border-collapse: collapse; margin-bottom: 20px;'>");

            // 标记合并单元格位置,避免重复渲染
            boolean[][] isMergedCell = new boolean[sheet.getLastRowNum() + 1][];
            for (int i = 0; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                isMergedCell[i] = row != null ? new boolean[row.getLastCellNum()] : new boolean[0];
            }
            Iterator<CellRangeAddress> mergedCells = sheet.getMergedCells().iterator();
            while (mergedCells.hasNext()) {
                CellRangeAddress range = mergedCells.next();
                for (int r = range.getFirstRow(); r <= range.getLastRow(); r++) {
                    for (int c = range.getFirstColumn(); c <= range.getLastColumn(); c++) {
                        isMergedCell[r][c] = true;
                    }
                }
            }

            // 遍历每一行
            for (int rowIdx = sheet.getFirstRowNum(); rowIdx <= sheet.getLastRowNum(); rowIdx++) {
                Row row = sheet.getRow(rowIdx);
                if (row == null) continue;

                htmlWriter.write("<tr>");

                // 遍历每个单元格
                for (int cellIdx = row.getFirstCellNum(); cellIdx < row.getLastCellNum(); cellIdx++) {
                    Cell cell = row.getCell(cellIdx);
                    if (cell == null) {
                        htmlWriter.write("<td></td>");
                        continue;
                    }

                    // 处理合并单元格的首单元格
                    CellRangeAddress mergedRange = sheet.getMergedRegionAt(sheet.getMergedRegionIndex(cell));
                    if (mergedRange != null && cellIdx == mergedRange.getFirstColumn() && rowIdx == mergedRange.getFirstRow()) {
                        int rowSpan = mergedRange.getLastRow() - mergedRange.getFirstRow() + 1;
                        int colSpan = mergedRange.getLastColumn() - mergedRange.getFirstColumn() + 1;
                        htmlWriter.write(String.format("<td rowspan='%d' colspan='%d' style='%s'>", rowSpan, colSpan, getCellStyle(cell)));
                    } else if (isMergedCell[rowIdx][cellIdx]) {
                        // 跳过合并单元格的非首单元格
                        continue;
                    } else {
                        htmlWriter.write(String.format("<td style='%s'>", getCellStyle(cell)));
                    }

                    // 写入单元格内容
                    htmlWriter.write(getCellValue(cell));
                    htmlWriter.write("</td>");
                }

                htmlWriter.write("</tr>");
            }

            htmlWriter.write("</table>");
        }

        workbook.close();
        return htmlWriter.toString();
    }

    // 提取单元格的样式(字体、颜色、对齐方式等)
    private static String getCellStyle(Cell cell) {
        CellStyle style = cell.getCellStyle();
        StringBuilder styleStr = new StringBuilder();

        // 字体样式
        Font font = cell.getSheet().getWorkbook().getFontAt(style.getFontIndex());
        if (font.getBold()) styleStr.append("font-weight: bold; ");
        if (font.getItalic()) styleStr.append("font-style: italic; ");
        styleStr.append(String.format("font-family: %s; font-size: %dpt; ", font.getFontName(), font.getFontHeightInPoints()));

        // 背景色
        Color bgColor = style.getFillForegroundColorColor();
        if (bgColor != null) {
            if (bgColor instanceof XSSFColor) {
                byte[] rgb = ((XSSFColor) bgColor).getRGB();
                styleStr.append(String.format("background-color: rgb(%d,%d,%d); ", rgb[0]&0xFF, rgb[1]&0xFF, rgb[2]&0xFF));
            } else {
                short colorIdx = style.getFillForegroundColor();
                styleStr.append(String.format("background-color: %s; ", getColorName(colorIdx)));
            }
        }

        // 文本对齐
        HorizontalAlignment align = style.getAlignment();
        switch (align) {
            case CENTER: styleStr.append("text-align: center; "); break;
            case RIGHT: styleStr.append("text-align: right; "); break;
            default: styleStr.append("text-align: left; ");
        }

        // 边框
        styleStr.append("border: 1px solid #333; ");
        return styleStr.toString();
    }

    // 提取单元格内容
    private static String getCellValue(Cell cell) {
        switch (cell.getCellType()) {
            case STRING: return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString();
                } else {
                    return String.valueOf(cell.getNumericCellValue());
                }
            case BOOLEAN: return String.valueOf(cell.getBooleanCellValue());
            case FORMULA: return cell.getCellFormula();
            default: return "";
        }
    }

    // 辅助方法:映射HSSF颜色索引到颜色值
    private static String getColorName(short colorIndex) {
        switch (colorIndex) {
            case 8: return "#000000";
            case 9: return "#FFFFFF";
            case 10: return "#FF0000";
            case 11: return "#00FF00";
            case 12: return "#0000FF";
            default: return "#FFFFFF";
        }
    }

    // 测试用的main方法
    public static void main(String args[]) {
        try {
            // 替换成你的本地Excel路径
            String htmlContent = convertExcelToHtml("C:/test/sample_excel.xlsx");
            System.out.println(htmlContent);
            // 输出的内容可以直接在JSP中渲染
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3. 在JSP页面中渲染转换后的HTML

写一个JSP页面,调用上面的工具类,把转换后的HTML直接输出到页面上:

<%@ page import="com.yourpackage.ExcelToHtmlConverter" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>带格式的Excel展示</title>
</head>
<body>
    <h2>Excel原格式展示</h2>
    <%
        try {
            // 替换成服务器上的Excel文件路径(可以是WEB-INF下的文件,或者用户上传的临时文件)
            String excelPath = application.getRealPath("/WEB-INF/files/sample.xlsx");
            String excelHtml = ExcelToHtmlConverter.convertExcelToHtml(excelPath);
            // 直接输出HTML,保留所有格式
            out.print(excelHtml);
        } catch (Exception e) {
            out.print("<p>加载Excel失败:" + e.getMessage() + "</p>");
            e.printStackTrace();
        }
    %>
</body>
</html>

一些注意点

  • 上面的工具类已经处理了合并单元格、字体样式、背景色、文本对齐这些常见格式,你可以根据需求扩展(比如单元格宽高、边框样式)
  • 如果是用户上传的Excel,要先保存到服务器临时目录,再传入转换方法
  • 要是Excel里有复杂图表,这个方法没法转换图表,需要的话得用截图或者专门的图表转换工具

内容的提问来源于stack exchange,提问作者Krishanu Debnath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:46:44