4

我的要求是使用 iText 生成 PDF 文件,我使用以下代码创建示例 PDF

Document document = new Document();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter.getInstance(document, baos);
document.open();
document.add(new Paragraph("success PDF FROM STRUTS"));
document.close();
ServletOutputStream outputStream = response.getOutputStream() ;
baos.writeTo(outputStream);
response.setHeader("Content-Disposition", "attachment; filename=\"stuReport.pdf\"");
response.setContentType("application/pdf");
outputStream.flush();
outputStream.close();

如果您在上面的代码中看到,iText 没有使用任何 inputStream 参数,而是直接写入响应的输出流。而 struts-2 要求我们使用 InputStream 参数(见下面的配置)

<action name="exportReport" class="com.export.ExportReportAction">
    <result name="pdf" type="stream">
        <param name="inputName">inputStream</param>
        <param name="contentType">application/pdf</param>
        <param name="contentDisposition">attachment;filename="sample.pdf"</param>
        <param name="bufferSize">1024</param>
    </result>
</action>

我知道我的类应该有 inputStream 的 getter 和 setter,我在 struts-configuration 中提到的类中也有

private InputStream inputStream;
public InputStream getInputStream() {
    return inputStream;
}

public void setInputStream(InputStream inputStream) {
    this.inputStream = inputStream;
}

但是由于 iText 并不真正需要输入流,而是直接写入响应的输出流,因此我得到了异常,因为我没有为 inputStream 参数设置任何内容。

请让我知道如何在 struts-2 中使用 iText 代码,并将 resultType 作为流

谢谢

4

2 回答 2

4

找到了解决方案。

执行此 PDF 导出的操作中的方法可以是无效的。当我们直接写入响应的输出流时,不需要结果类型配置

例如,以这种方式让你的动作课

Class ExportReportAction extends ActionSupport {
  public void exportToPdf() { // no return type
    try {
        Document document = new Document();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfWriter.getInstance(document, baos);
        document.open();
        document.add(new Paragraph("success PDF FROM STRUTS"));
        document.close(); 
        ServletOutputStream outputStream = response.getOutputStream() ; 
        baos.writeTo(outputStream); 
        response.setHeader("Content-Disposition", "attachment; filename=\"stuReport.pdf\""); 
        response.setContentType("application/pdf"); 
        outputStream.flush(); 
        outputStream.close(); 
    }catch (Exception e) {
        //catch
    }

  } 
}

并以这种方式进行您的 struts 配置

<action name="exportReport" class="com.export.ExportReportAction"> 
 <!-- NO NEED TO HAVE RESULT TYPE STREAM CONFIGURATION-->
</action>

这很酷!

感谢所有试图回答这个问题的人

于 2012-09-04T15:19:29.250 回答
2

主要答案:

您也可以return NONEreturn null按照 Apache 文档中的说明:

从操作类方法返回ActionSupport.NONE(或 null)会导致结果处理被跳过。如果操作完全处理结果处理,例如直接写入 HttpServletResponse OutputStream,这将很有用。

来源: http ://struts.apache.org/release/2.2.x/docs/result-configuration.html


例子:

O'Reilly 提供了关于使用 Servlet在 Web 应用程序中动态创建 PDF的教程(SC Sullivan,2003)。它可以转换为 Struts2 动作类,如下所示。

最好有一个帮助类,比如PDFGenerator为您创建 PDF 并将其作为ByteArrayOutputStream.

PDFGenerator

import java.io.ByteArrayOutputStream;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;

public class PDFGenerator {

    public ByteArrayOutputStream generatePDF() throws DocumentException {

        Document doc = new Document();
        ByteArrayOutputStream baosPDF = new ByteArrayOutputStream();            
        PdfWriter pdfWriter = PdfWriter.getInstance(doc, baosPDF);

        try {           
            doc.open();         

            // create pdf here
            doc.add(new Paragraph("Hello World"));

        } catch(DocumentException de) {
            baosPDF.reset();
            throw de;

        } finally {
            if(doc != null) {
                doc.close();
            }

            if(pdfWriter != null) {
                pdfWriter.close();
            }
        }

        return baosPDF;
    }
}

您现在可以在您的操作类中调用它。

ViewPDFAction

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ServletResponseAware;
import com.yoursite.helper.PDFGenerator;
import com.opensymphony.xwork2.ActionSupport;

public class ViewPDFAction extends ActionSupport
    implements ServletResponseAware {

    private static final long serialVersionUID = 1L;    
    private HttpServletResponse response;

    @Override
    public String execute() throws Exception {

        ByteArrayOutputStream baosPDF = new PDFGenerator().generatePDF();    
        String filename = "Your_Filename.pdf"; 

        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition",
            "inline; filename=" + filename); // open in new tab or window           
        response.setContentLength(baosPDF.size());

        OutputStream os = response.getOutputStream();
        os.write(baosPDF.toByteArray());
        os.flush();
        os.close();
        baosPDF.reset();

        return NONE; // or return null
    }

    @Override
    public void setServletResponse(HttpServletResponse response) {
        this.response = response;       
    }
}

web.xml

<mime-mapping>
    <extension>pdf</extension>
    <mime-type>application/pdf</mime-type>
</mime-mapping>

struts.xml

<action name="viewpdf" class="com.yoursite.action.ViewPDFAction">
    <!-- NO CONFIGURATION FOR RESULT NONE -->
</action>
于 2014-12-01T06:10:12.287 回答