知識庫 / Spring / Spring MVC RSS 訂閱

使用 Spring MVC 上傳和顯示 Excel 文件

Spring MVC
HongKong
4
02:40 PM · Dec 06 ,2025

1. 引言

本文將演示如何使用 Spring MVC 框架上傳 Excel 文件並在網頁上顯示其內容。

2. 上傳 Excel 文件

為了能夠上傳文件,我們首先將創建一個控制器映射,該映射接收一個 <em >MultipartFile</em> 並將其保存到當前位置:

private String fileLocation;

@PostMapping("/uploadExcelFile")
public String uploadFile(Model model, MultipartFile file) throws IOException {
    InputStream in = file.getInputStream();
    File currDir = new File(".");
    String path = currDir.getAbsolutePath();
    fileLocation = path.substring(0, path.length() - 1) + file.getOriginalFilename();
    FileOutputStream f = new FileOutputStream(fileLocation);
    int ch = 0;
    while ((ch = in.read()) != -1) {
        f.write(ch);
    }
    f.flush();
    f.close();
    model.addAttribute("message", "File: " + file.getOriginalFilename() 
      + " has been uploaded successfully!");
    return "excel";
}

接下來,讓我們創建一個包含一個具有type file類型的input的JSP文件,該文件將設置accept屬性,僅允許Excel文件:

<c:url value="/uploadExcelFile" var="uploadFileUrl" />
<form method="post" enctype="multipart/form-data"
  action="${uploadFileUrl}">
    <input type="file" name="file" accept=".xls,.xlsx" /> <input
      type="submit" value="Upload file" />
</form>

3. 讀取 Excel 文件

為了解析上傳的 Excel 文件,我們將使用 Apache POI 庫,該庫可以處理 .xls.xlsx 文件。

讓我們創建一個名為 MyCell 的輔助類,該類將包含與 Excel 單元格的內容和格式相關的屬性:

public class MyCell {
    private String content;
    private String textColor;
    private String bgColor;
    private String textSize;
    private String textWeight;

    public MyCell(String content) {
        this.content = content;
    }
    
    //standard constructor, getters, setters
}

我們將讀取 Excel 文件的內容,將其放入一個 Map 對象中,該 Map 對象包含 MyCell 對象的列表。

3.1. 解析 .xls 文件

一個 .xls 文件在 Apache POI 庫中由 HSSFWorkbook 類表示,該類由 HSSFSheet 對象組成。要打開和讀取 .xls 文件的內容,您可以查看我們在 Java 中使用 Microsoft Excel 的文章。

要解析單元格的格式,我們將獲取 HSSFCellStyle 對象,它可以幫助我們確定諸如背景顏色和字體之類的屬性。所有讀取的屬性都將設置在 MyCell 對象的屬性中:

HSSFCellStyle cellStyle = cell.getCellStyle();

MyCell myCell = new MyCell();

HSSFColor bgColor = cellStyle.getFillForegroundColorColor();
if (bgColor != null) {
    short[] rgbColor = bgColor.getTriplet();
    myCell.setBgColor("rgb(" + rgbColor[0] + ","
      + rgbColor[1] + "," + rgbColor[2] + ")");
    }
HSSFFont font = cell.getCellStyle().getFont(workbook);

顏色以 格式表示,以便在 中在 頁面上更輕鬆地顯示。

我們還需要獲取字體大小、粗細度和顏色:

myCell.setTextSize(font.getFontHeightInPoints() + "");
if (font.getBold()) {
    myCell.setTextWeight("bold");
}
HSSFColor textColor = font.getHSSFColor(workbook);
if (textColor != null) {
    short[] rgbColor = textColor.getTriplet();
    myCell.setTextColor("rgb(" + rgbColor[0] + ","
      + rgbColor[1] + "," + rgbColor[2] + ")");
}

3.2. 解析 .xlsx 文件

對於採用較新 .xlsx 格式的文件,我們可以使用 XSSFWorkbook 類及其類似類來處理工作簿的內容,相關內容請參考“Java 中使用 Microsoft Excel”文章。

下面我們更詳細地瞭解一下如何讀取 .xlsx 格式單元格的格式。首先,我們將檢索與單元格關聯的 XSSFCellStyle 對象,並利用它來確定背景顏色和字體:

XSSFCellStyle cellStyle = cell.getCellStyle();

MyCell myCell = new MyCell();
XSSFColor bgColor = cellStyle.getFillForegroundColorColor();
if (bgColor != null) {
    byte[] rgbColor = bgColor.getRGB();
    myCell.setBgColor("rgb(" 
      + (rgbColor[0] < 0 ? (rgbColor[0] + 0xff) : rgbColor[0]) + ","
      + (rgbColor[1] < 0 ? (rgbColor[1] + 0xff) : rgbColor[1]) + ","
      + (rgbColor[2] < 0 ? (rgbColor[2] + 0xff) : rgbColor[2]) + ")");
}
XSSFFont font = cellStyle.getFont();

在這種情況下,顏色的 RGB 值將是 有符號字節 值,因此我們將通過將負值加上 0xff 獲得 無符號 值。

我們還將確定字體屬性:

myCell.setTextSize(font.getFontHeightInPoints() + "");
if (font.getBold()) {
    myCell.setTextWeight("bold");
}
XSSFColor textColor = font.getXSSFColor();
if (textColor != null) {
    byte[] rgbColor = textColor.getRGB();
    myCell.setTextColor("rgb("
      + (rgbColor[0] < 0 ? (rgbColor[0] + 0xff) : rgbColor[0]) + "," 
      + (rgbColor[1] < 0 ? (rgbColor[1] + 0xff) : rgbColor[1]) + "," 
      + (rgbColor[2] < 0 ? (rgbColor[2] + 0xff) : rgbColor[2]) + ")");
}

3.3. 處理空行

上述方法不考慮 Excel 文件中的空行。 如果我們希望生成的結果中正確地顯示這些空行,則需要我們在 HashMap 中使用 ArrayList 包含 MyCell 對象,這些對象的內容為空 String

最初,在讀取 Excel 文件後,這些空行將是大小為 0 的 ArrayList 對象。

為了確定我們應該添加多少個空 String 對象,我們首先將使用 maxNrCols 變量確定 Excel 文件中最長的一行。然後,我們將該數量的空 String 對象添加到 HashMap 中所有大小為 0 的列表:

int maxNrCols = data.values().stream()
  .mapToInt(List::size)
  .max()
  .orElse(0);

data.values().stream()
  .filter(ls -> ls.size() < maxNrCols)
  .forEach(ls -> {
      IntStream.range(ls.size(), maxNrCols)
        .forEach(i -> ls.add(new MyCell("")));
  });

4. 顯示 Excel 文件

要顯示使用 Spring MVC 讀取的 Excel 文件,我們需要定義一個控制器映射和 JSP 頁面。

4.1. Spring MVC 控制器

讓我們創建一個使用 @RequestMapping 標註的方法,該方法將調用上述代碼讀取上傳文件的內容,然後將返回的 Map 作為 Model 屬性添加:

@Resource(name = "excelPOIHelper")
private ExcelPOIHelper excelPOIHelper;

@RequestMapping(method = RequestMethod.GET, value = "/readPOI")
public String readPOI(Model model) throws IOException {

  if (fileLocation != null) {
      if (fileLocation.endsWith(".xlsx") || fileLocation.endsWith(".xls")) {
          Map<Integer, List<MyCell>> data
            = excelPOIHelper.readExcel(fileLocation);
          model.addAttribute("data", data);
      } else {
          model.addAttribute("message", "Not a valid excel file!");
      }
  } else {
      model.addAttribute("message", "File missing! Please upload an excel file.");
  }
  return "excel";
}

4.2. JSP

為了以可視方式顯示文件的內容,我們將創建一個 HTML 表格,並在每個表格單元的 樣式屬性中添加與 Excel 文件中每個單元格對應的格式化屬性:

<c:if test="${not empty data}">
    <table style="border: 1px solid black; border-collapse: collapse;">
        <c:forEach items="${data}" var="row">
            <tr>
                <c:forEach items="${row.value}" var="cell">
                    <td style="border:1px solid black;height:20px;width:100px;
                      background-color:${cell.bgColor};color:${cell.textColor};
                      font-weight:${cell.textWeight};font-size:${cell.textSize}pt;">
                      ${cell.content}
                    </td>
                </c:forEach>
            </tr>
        </c:forEach>
    </table>
</c:if>

5. 結論

在本文中,我們展示了一個使用 Spring MVC 框架上傳 Excel 文件並在網頁上顯示的示例項目。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.