如何使用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
相关产品推荐
相关产品推荐

