Search code examples
jsfpdf-generationjsf-2acrobatapache-fop

How to show java (jsf) generated pdf directly in AdobeReader


i am using JSF 2.0 (Eclipse IDE) and i have a method in one of my beans which generates some PDF files using Apache FOP 1.0. When I click "makePDF" button on my JSF page, generated PDF opens in the SAME window where my page is (and i have to use 'back' button after i view/save/print PDF).

I can change this in a way that when "makePDF" button is pressed, standard pop-out dialog appears and asks me if i wish to save file or to open it with AdobeReader.

Is there a way that, when i click my "makePDF" button, generated PDF is directly opened in AdobeReader (and i still have my JSF page and dont need to confirm anything) ??? Also (it's not really needed, but good to know), is there a way to open it in new window or send it directly to printer?

Here is the main part of my code (i deleted some irrelevant stuff) :

public void makePDF(long contractId, int documentType) {

    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    String basePath = externalContext.getRealPath("/");

    try {
        fopFactory.setUserConfig(new File(basePath + "/pdf_transform/config/userconfig.xml"));
        fopFactory.setBaseURL(basePath);
        fopFactory.getFontManager().setFontBaseURL(basePath);
    } catch (Exception e) {
        e.printStackTrace();
    } 
    FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
    foUserAgent.setBaseURL(fopFactory.getBaseURL());

    HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
    response.reset();
    response.setHeader("Content-Type", "application/pdf");
    response.setHeader("Content-disposition", "attachment");
    BufferedOutputStream output = null;

    try {
        output = new BufferedOutputStream(response.getOutputStream(), 10240);
        Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, output);

        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer(new StreamSource(xsltfile));

        Source src = new DOMSource(makeXML(contract)); // my method
        Result res = new SAXResult(fop.getDefaultHandler());

        transformer.transform(src, res);

    } catch (Exception e) {
        e.printStackTrace();
    } 

    facesContext.responseComplete();
}`

When i remove response.setHeader("Content-disposition", "attachment"); it opens in the same window, otherwise it asks me to save or open.

Thanks in advance.


Solution

  • Opening a request in a new window is not directly a JSF concern. It's more a HTML concern.

    Add target="_blank" to the form

    <h:form target="_blank">
    

    and it'll submit the request into a new tab/window.

    Sending to the client's printer directly is not possible without introducing some piece of code which runs at the client side as man in the middle, like an applet.