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

家电Web应用中,如何从现有JSP生成可下载PDF订单报表?

当然可以!直接把JSP输出转成PDF的方案

你完全不需要手动用iText从零构建PDF内容——捕获JSP渲染后的HTML并转换为PDF是更高效且贴合你现有开发流程的方案,我来给你详细拆解实现步骤:

核心思路

  1. 捕获JSP渲染后的完整HTML内容(替代直接输出到浏览器)
  2. 将捕获到的HTML转换为PDF文件,作为下载响应返回给用户

步骤1:捕获JSP的HTML输出

我们可以通过自定义HttpServletResponseWrapper来拦截JSP的输出流,把渲染后的HTML保存为字符串。

自定义响应包装类

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletOutputStream;

public class HtmlCaptureResponseWrapper extends HttpServletResponseWrapper {
    private final CharArrayWriter charArrayWriter = new CharArrayWriter();

    public HtmlCaptureResponseWrapper(HttpServletResponse response) {
        super(response);
    }

    // 覆盖getWriter,将输出写入CharArrayWriter
    @Override
    public PrintWriter getWriter() throws IOException {
        return new PrintWriter(charArrayWriter);
    }

    // 覆盖getOutputStream,处理字节流输出
    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        return new ServletOutputStream() {
            @Override
            public void write(int b) throws IOException {
                charArrayWriter.write(b);
            }
        };
    }

    // 获取捕获到的HTML内容
    public String getCapturedHtml() {
        return charArrayWriter.toString();
    }
}

步骤2:在Servlet中处理PDF生成请求

当用户点击“生成PDF”按钮时,对应的Servlet会先转发到订单报表JSP捕获HTML,再用HTML转PDF工具生成可下载的PDF文件。

Servlet核心代码

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.io.IOException;

@WebServlet("/generateOrderPdf")
public class OrderPdfGeneratorServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 捕获JSP渲染的HTML内容
        HtmlCaptureResponseWrapper responseWrapper = new HtmlCaptureResponseWrapper(response);
        // 转发到你的订单报表JSP(替换为实际路径)
        request.getRequestDispatcher("/WEB-INF/views/order-report.jsp").forward(request, responseWrapper);
        String capturedHtml = responseWrapper.getCapturedHtml();

        // 2. 配置PDF下载响应头
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "attachment; filename=\"order-report-" + System.currentTimeMillis() + ".pdf\"");

        // 3. 使用Flying Saucer + iText7将HTML转PDF
        ITextRenderer renderer = new ITextRenderer();
        // 加载捕获到的HTML
        renderer.setDocumentFromString(capturedHtml);
        // 渲染布局
        renderer.layout();
        // 生成PDF并写入响应输出流
        renderer.createPDF(response.getOutputStream());
        
        renderer.finishPDF();
    }
}

步骤3:添加依赖(Maven示例)

推荐使用Flying Saucer(一款纯Java的HTML/CSS到PDF渲染工具)配合iText7,无需额外安装软件:

<!-- Flying Saucer核心库 -->
<dependency>
    <groupId>org.xhtmlrenderer</groupId>
    <artifactId>flying-saucer-core</artifactId>
    <version>9.1.22</version>
</dependency>
<!-- Flying Saucer对iText7的适配 -->
<dependency>
    <groupId>org.xhtmlrenderer</groupId>
    <artifactId>flying-saucer-pdf-itext7</artifactId>
    <version>9.1.22</version>
</dependency>
<!-- iText7核心依赖(通过pom导入所有子模块) -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext7-core</artifactId>
    <version>7.2.5</version>
    <type>pom</type>
</dependency>

关键注意事项

  • 确保JSP输出标准XHTML:Flying Saucer对HTML的兼容性不如浏览器,建议给JSP添加<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">声明,并且所有标签闭合、属性值加引号。
  • CSS兼容性:支持大部分CSS2.1属性,CSS3的部分属性(如flexbox)可能有限支持,建议用基础CSS样式控制报表布局。
  • 资源路径问题:如果JSP中引用了图片、CSS文件,需要将路径转为绝对路径,或者在渲染时通过renderer.getSharedContext().setBaseURL()设置基础路径,确保资源能被正确加载。

内容的提问来源于stack exchange,提问作者A.Martinez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:44:09