首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> JSP 程式設計 >> 關於JSP

JSP 直接輸出 Word/Excel 文件:Content-Type 設置與瀏覽器處理機制

     編輯:關於JSP

核心原理

瀏覽器根據響應頭 Content-Type 決定如何處理內容:
▸ application/msword → 調用 Word / WPS 打開 .doc
▸ application/vnd.ms-excel → 調用 Excel / WPS 打開 .xls
▸ application/vnd.openxmlformats-officedocument.wordprocessingml.document → .docx
▸ application/vnd.openxmlformats-officedocument.spreadsheetml.sheet → .xlsx

JSP 頁首指令設置

<!-- 輸出 Word 97-2003 (.doc) -->
<%@ page contentType="application/msword;charset=UTF-8" %>

<!-- 輸出 Excel 97-2003 (.xls) -->
<%@ page contentType="application/vnd.ms-excel;charset=UTF-8" %>

<!-- 現代格式 .docx -->
<%@ page contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=UTF-8" %>

<!-- 現代格式 .xlsx -->
<%@ page contentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8" %>

完整示例:導出 Excel 表格

<%@ page contentType="application/vnd.ms-excel;charset=UTF-8" %>
<%@ page import="java.util.*,java.text.*" %>
<%
    response.setHeader("Content-Disposition", "attachment; filename=users_" + new SimpleDateFormat("yyyyMMdd").format(new Date()) + ".xls");
%>
<table border="1">
    <tr><th>ID</th><th>姓名</th><th>郵箱</th><th>註冊時間</th></tr>
    <%
        List<User> users = (List<User>) request.getAttribute("userList");
        if (users != null) {
            for (User u : users) {
    %>
    <tr>
        <td><%= u.getId() %></td>
        <td><%= u.getName() %></td>
        <td><%= u.getEmail() %></td>
        <td><%= new SimpleDateFormat("yyyy-MM-dd HH:mm").format(u.getRegTime()) %></td>
    </tr>
    <%
            }
        }
    %>
</table>

關鍵點與避坑指南

問題解決
中文亂碼頁面 charset=UTF-8、數據庫連接 characterEncoding=utf8、JSP pageEncoding="UTF-8"
文件名中文filename*=UTF-8''%E6%96%87%E4%BB%B6.xls (RFC 5987) 或雙重編碼兼容舊瀏覽器
大數據量導出JSP 輸出易 OOM,**改用 Servlet + SXSSF (POI 流式寫入) 直接寫 response.getOutputStream()**
樣式/公式/合併儲存格HTML 表格不支持,**必須用 Apache POI 生成真實 .xlsx/.xls 二進制**
瀏覽器直接打開而非下載加 Content-Disposition: attachment; filename=... 強制下載

現代最佳實踐:POI + Servlet 流式導出

@WebServlet("/export/users.xlsx")
public class UserExcelExportServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        resp.setHeader("Content-Disposition", "attachment; filename=users_" + LocalDate.now() + ".xlsx");

        try (SXSSFWorkbook wb = new SXSSFWorkbook(100); // 內存保留 100 行,其餘寫臨時文件
             ServletOutputStream out = resp.getOutputStream()) {

            Sheet sheet = wb.createSheet("用戶列表");
            Row header = sheet.createRow(0);
            String[] cols = {"ID", "姓名", "郵箱", "註冊時間"};
            for (int i = 0; i < cols.length; i++) header.createCell(i).setCellValue(cols[i]);

            List<User> users = userService.findAll(); // 或分頁查詢
            int rowNum = 1;
            for (User u : users) {
                Row row = sheet.createRow(rowNum++);
                row.createCell(0).setCellValue(u.getId());
                row.createCell(1).setCellValue(u.getName());
                row.createCell(2).setCellValue(u.getEmail());
                row.createCell(3).setCellValue(u.getRegTime().toString());
            }

            wb.write(out); // 直接寫響應流
            out.flush();
        }
    }
}

總結

JSP 設置 contentType 導出 Office 文件是**快速原型/小數據量**的權宜之計:本質是輸出 HTML 表格,瀏覽器勉強識別為 Word/Excel。**缺陷**:無樣式控制、無公式、大數據 OOM、非標準格式。生產環境**必須使用 Apache POI (SXSSF/XSSF) 生成真實二進制文件**,配合 Content-Disposition: attachment 強制下載,支持百萬行導出、樣式、公式、圖表、簽名等企業級需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved