如何在使用 iText 生成 PDF 时消除异常

发布于 2024-12-28 21:34:33 字数 7556 浏览 1 评论 0原文

我试图在java spring框架mvc中使用itext渲染pdf。 这是我的过滤器类。

 public class PdfFilter implements Filter, ApplicationContextAware {

@SuppressWarnings({ "UnusedDeclaration" })
private static final Logger log = Logger.getLogger(PdfFilter.class);
protected ApplicationContext applicationContext;

public void init(FilterConfig config) {
    /* do nothing */
}

public void destroy() {
    /* do nothing */
}

public void doFilter(ServletRequest req, ServletResponse resp,
        FilterChain filterChain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) resp;

    // Check to see if this filter should apply.
    if (!"pdf".equals(request.getParameter("reportViewType"))) {
        filterChain.doFilter(request, response);
        return;
    }

    // Capture the content for this request
    ContentCaptureServletResponse capContent = new ContentCaptureServletResponse(
            response);
    filterChain.doFilter(request, capContent);

    response.setContentType("application/pdf; charset=UTF-8");
    response.setHeader("Content-disposition",
            "attachment; filename=\"report.pdf\"");
    response.addHeader("Cache-Control", "-1");

    try {
        // Get the html content
        String htmlContent = capContent.getHtlmContent();

        PdfGenerator pdfGenerator = new PdfGenerator(
                response.getOutputStream());

        pdfGenerator.renderPdf(htmlContent, request, response);

    } catch (Exception e) {
        throw new ServletException(e);
    }
}

public void setApplicationContext(ApplicationContext applicationContext) {
    this.applicationContext = applicationContext;
}
}

这是我的 pdfGenerator 类 公共类 PdfGenerator { 私有静态最终 Logger 日志 = Logger.getLogger(PdfGenerator.class); 私有输出流输出流;

public PdfGenerator(OutputStream os) {
    this.outputStream = os;
}

public void renderPdf(String htmlContent, HttpServletRequest request,
        HttpServletResponse response) throws Exception {
    log.debug("renderPdf");

    htmlContent = cleanUpHtml(htmlContent);
    htmlContent = addHeadBodyTag(htmlContent);

    htmlContent = addCss(htmlContent);

    log.debug("convertToXhtml-e:");
    OutputStream xhtmlOs = new ByteArrayOutputStream();

    Tidy tidy = new Tidy();
    tidy.setXHTML(true);
    tidy.setCharEncoding(Configuration.UTF8);
    tidy.parse(new ByteArrayInputStream(htmlContent.getBytes()), xhtmlOs);

    xhtmlOs.flush();
    xhtmlOs.close();
    log.debug(xhtmlOs.toString());
    StringReader contentReader = new StringReader(xhtmlOs.toString());

    InputSource source = new InputSource(contentReader);

    DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance()
            .newDocumentBuilder();
    // documentBuilder.setEntityResolver(new MyResolver(request));
    documentBuilder.setEntityResolver(new NoOpEntityResolver());

    Document xhtmlContent = documentBuilder.parse(source);

    ITextRenderer renderer = new ITextRenderer();
    renderer.setDocument(xhtmlContent, null);
    renderer.layout();

    renderer.createPDF(outputStream);

    outputStream.close();

}

private String cleanUpHtml(String data) {
    log.debug("cleanUpHtml-e:");

    data = HtmlUtils.removeAllTags(data, "<script", "</script>", null);
    data = HtmlUtils.replaceAll(data, "<a .*?>|</a>", "");
    // data = HtmlUtils.replaceAll(data, "<img .*?>|</img>", "");
    data = HtmlUtils.replaceAll(data, "<link .*?>", "");
    // remove hidden field
    data = HtmlUtils.replaceAll(data, "<input.*?type=['\"]hidden['\"].*?>",
            "");
    // remove pagination from lister
    data = HtmlUtils
            .replaceAll(
                    data,
                    "(<div style=\"top: .*?px; position: absolute;\" id=\"pager\" class=\"pager\".*?</div>)",
                    "");

    return data;
}

private String addHeadBodyTag(String data) {
    // data = "<html><head></head><body>" + data + "</body></html>";
    return data;
}

private String addCss(String data) {
    log.debug("addCss-e:");

    return data;
}

private String addHead(String data, HttpServletRequest request) {
    log.debug("addHeader-e:");
    StringBuilder sb = new StringBuilder(500);
    String header = sb.toString();
    data = HtmlUtils.replaceAll(data, "(<body.*?>)", "$1" + header);

    return data;

}

private String addFooter(String data) {
    log.debug("addFooter-e:");

    String footer = "iit lone gunmen 2.0";

    data = HtmlUtils.replaceAll(data, "(<body.*?>)", "$1" + footer);
    return data;
}

但不知怎的

,我得到了一些例外:

 Jan 26, 2012 5:43:08 AM org.apache.catalina.core.StandardWrapperValve invoke
 SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/govForms]       threw exception [Filter execution threw an exception] with root cause
    java.lang.NoSuchMethodError: com.lowagie.text.Rectangle.getHeight()F
at org.xhtmlrenderer.pdf.ITextRenderer.writePDF(ITextRenderer.java:339)
at org.xhtmlrenderer.pdf.ITextRenderer.createPDF(ITextRenderer.java:315)
at org.xhtmlrenderer.pdf.ITextRenderer.createPDF(ITextRenderer.java:246)
at bd.gov.forms.web.pdf.PdfGenerator.renderPdf(PdfGenerator.java:64)
at bd.gov.forms.web.pdf.PdfFilter.doFilter(PdfFilter.java:54)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:119)
at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:55)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

任何形式的帮助都是值得赞赏的。 谢谢。

I wast trying to render pdf using itext in java spring framework mvc.
Here's my filter class.

 public class PdfFilter implements Filter, ApplicationContextAware {

@SuppressWarnings({ "UnusedDeclaration" })
private static final Logger log = Logger.getLogger(PdfFilter.class);
protected ApplicationContext applicationContext;

public void init(FilterConfig config) {
    /* do nothing */
}

public void destroy() {
    /* do nothing */
}

public void doFilter(ServletRequest req, ServletResponse resp,
        FilterChain filterChain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) resp;

    // Check to see if this filter should apply.
    if (!"pdf".equals(request.getParameter("reportViewType"))) {
        filterChain.doFilter(request, response);
        return;
    }

    // Capture the content for this request
    ContentCaptureServletResponse capContent = new ContentCaptureServletResponse(
            response);
    filterChain.doFilter(request, capContent);

    response.setContentType("application/pdf; charset=UTF-8");
    response.setHeader("Content-disposition",
            "attachment; filename=\"report.pdf\"");
    response.addHeader("Cache-Control", "-1");

    try {
        // Get the html content
        String htmlContent = capContent.getHtlmContent();

        PdfGenerator pdfGenerator = new PdfGenerator(
                response.getOutputStream());

        pdfGenerator.renderPdf(htmlContent, request, response);

    } catch (Exception e) {
        throw new ServletException(e);
    }
}

public void setApplicationContext(ApplicationContext applicationContext) {
    this.applicationContext = applicationContext;
}
}

and here's my pdfGenerator class
public class PdfGenerator {
private static final Logger log = Logger.getLogger(PdfGenerator.class);
private OutputStream outputStream;

public PdfGenerator(OutputStream os) {
    this.outputStream = os;
}

public void renderPdf(String htmlContent, HttpServletRequest request,
        HttpServletResponse response) throws Exception {
    log.debug("renderPdf");

    htmlContent = cleanUpHtml(htmlContent);
    htmlContent = addHeadBodyTag(htmlContent);

    htmlContent = addCss(htmlContent);

    log.debug("convertToXhtml-e:");
    OutputStream xhtmlOs = new ByteArrayOutputStream();

    Tidy tidy = new Tidy();
    tidy.setXHTML(true);
    tidy.setCharEncoding(Configuration.UTF8);
    tidy.parse(new ByteArrayInputStream(htmlContent.getBytes()), xhtmlOs);

    xhtmlOs.flush();
    xhtmlOs.close();
    log.debug(xhtmlOs.toString());
    StringReader contentReader = new StringReader(xhtmlOs.toString());

    InputSource source = new InputSource(contentReader);

    DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance()
            .newDocumentBuilder();
    // documentBuilder.setEntityResolver(new MyResolver(request));
    documentBuilder.setEntityResolver(new NoOpEntityResolver());

    Document xhtmlContent = documentBuilder.parse(source);

    ITextRenderer renderer = new ITextRenderer();
    renderer.setDocument(xhtmlContent, null);
    renderer.layout();

    renderer.createPDF(outputStream);

    outputStream.close();

}

private String cleanUpHtml(String data) {
    log.debug("cleanUpHtml-e:");

    data = HtmlUtils.removeAllTags(data, "<script", "</script>", null);
    data = HtmlUtils.replaceAll(data, "<a .*?>|</a>", "");
    // data = HtmlUtils.replaceAll(data, "<img .*?>|</img>", "");
    data = HtmlUtils.replaceAll(data, "<link .*?>", "");
    // remove hidden field
    data = HtmlUtils.replaceAll(data, "<input.*?type=['\"]hidden['\"].*?>",
            "");
    // remove pagination from lister
    data = HtmlUtils
            .replaceAll(
                    data,
                    "(<div style=\"top: .*?px; position: absolute;\" id=\"pager\" class=\"pager\".*?</div>)",
                    "");

    return data;
}

private String addHeadBodyTag(String data) {
    // data = "<html><head></head><body>" + data + "</body></html>";
    return data;
}

private String addCss(String data) {
    log.debug("addCss-e:");

    return data;
}

private String addHead(String data, HttpServletRequest request) {
    log.debug("addHeader-e:");
    StringBuilder sb = new StringBuilder(500);
    String header = sb.toString();
    data = HtmlUtils.replaceAll(data, "(<body.*?>)", "$1" + header);

    return data;

}

private String addFooter(String data) {
    log.debug("addFooter-e:");

    String footer = "iit lone gunmen 2.0";

    data = HtmlUtils.replaceAll(data, "(<body.*?>)", "$1" + footer);
    return data;
}

}

but somehow Im getting some exception:

 Jan 26, 2012 5:43:08 AM org.apache.catalina.core.StandardWrapperValve invoke
 SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/govForms]       threw exception [Filter execution threw an exception] with root cause
    java.lang.NoSuchMethodError: com.lowagie.text.Rectangle.getHeight()F
at org.xhtmlrenderer.pdf.ITextRenderer.writePDF(ITextRenderer.java:339)
at org.xhtmlrenderer.pdf.ITextRenderer.createPDF(ITextRenderer.java:315)
at org.xhtmlrenderer.pdf.ITextRenderer.createPDF(ITextRenderer.java:246)
at bd.gov.forms.web.pdf.PdfGenerator.renderPdf(PdfGenerator.java:64)
at bd.gov.forms.web.pdf.PdfFilter.doFilter(PdfFilter.java:54)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:119)
at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:55)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Any kind of help is appreciated.
Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我三岁 2025-01-04 21:34:33

NoSuchMethod 错误表明您正在使用的库版本不匹配。我将首先检查我的库依赖项,并查找某些库是否不需要不同版本的 iText。如果是这样,我会尝试排除一个依赖项或选择支持适当版本的 iText 的库版本。

如果您使用 Maven,请尝试: mvn dependency:tree 并检查是否出现多个 iText

NoSuchMethod error suggest that you have a mismatch of versions of the libraries that you are using. I would start with checking my library dependencies and find if some libraries are not expecting different versions of iText. If so, I would try to exclude one dependency or choose libraries version which support proper versions of iText.

If you are using Maven, try: mvn dependency:tree and check for multiple iText occurence

走过海棠暮 2025-01-04 21:34:33

PDF 生成过程可能会因多种原因而失败。
您必须将 pdf 生成包围在 try/catch 块中,并在 catch 块中进行某种错误处理。我看到处理该问题的两种基本方法:

  1. 使用默认 pdf 文档部署您的应用程序:在捕获的生成异常中提供默认 pdf 的内容,其中将包含生成失败的通用警告短语
  2. pdf 生成器以字节流(而不是直接在响应输出流中),并且仅当正确返回时,您才设置响应标头来提供生成的 pdf 并复制响应输出流中返回的字节;在捕获的生成异常中,您可以设置响应以提供描述错误的 html 页面,或者可以重定向到标准错误页面。

The process of PDF generation can fail for a wide variety of reasons.
You must surround the pdf generation in a try/catch block and, in the catch block, make some sort of error handling. I see 2 basic way to handle the problem:

  1. Deploy your app with a default pdf document: in the catched generation exception serve the content of the default pdf, which would contain a generic warning phrase of failed generation
  2. The pdf generator return the result in a stream of bytes (and not directly in the response output stream) and only if return correctly, you set up the response headers to serve the generated pdf and copy the byte returned in the response output stream; in the catched generation exception you set up the response to serve a html page describing the error or you can redirect to a standard error page.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文