2010-11-18 18 views
9

Questa è la mia prima domanda qui, spero di farlo bene. Scusa per il mio cattivo inglese in anticipo :)FOP: come specificare il percorso relativo dell'immagine src?

Sto usando JSF 2.0 (Eclipse IDE) e sto provando a generare alcuni file PDF usando Apache FOP 1.0.

Sono stato in grado di creare semplici file PDF utilizzando le istruzioni su Apache Fop site, ma non riesco a inserire alcuna immagine dalla cartella dell'applicazione. La mia struttura di cartelle è come questo: Nella mia applicazione WebContent ho (tra gli altri) pdf_transform/XSLT/transformFile.xsl, e pdf_transform/XSLT/logo.jpg

In transformFile.xsl devo

<fo:block><fo:external-graphic src="url('logo.jpg')"/></fo:block> 

ma quando il pulsante 'showPDF' nel mio servlet i clik, ottengo file PDF senza immagine (tutto il resto è lì), e questi messaggi in console:

GRAVI: The Source che è stato restituito fr La risoluzione URI om non conteneva un InputStream per URI: logo.jpg 18 Nov, 2010 5:16:49 PM org.apache.fop.events.LoggingEventListener processEvent SEVERE: Immagine non trovata. URI: logo.jpg. (Nessuna informazione contesto disponibili)

ho cercato di usare 'logo.jpg' invece di url ('logo.jpg'), mettendo immagine su vari posti all'interno della cartella WebContent e utilizzare la navigazione diverso (" ./ logo .jpg ") ma non ha funzionato.

Funziona bene se si imposta il percorso assoluto (ad esempio "d: /fop/images/logo.jpg") ma ho bisogno di resoconti nella mia applicazione.

Durante la ricerca, ho trovato che questo è correlato a fopFactory.setURIResolver() e/o userAgent.setBaseURL(). Ho provato qualcosa con quello, ma non ci sono riuscito.

Sono nuovo sia per JSF che per FOP e questa situazione di immagine mi ha infastidito un bel po '. Qualcuno può aiutarmi con questo, o almeno indirizzarmi ad un tutorial su "come configurare la FOP per l'uso relativo del percorso"?

EDIT: Non voglio eventuali percorsi assoluti e applicazione dovrebbe funzionare indipendentemente dalla sua posizione sul computer (per essere pubblicabile). La mia ricerca mi dice che ha qualcosa a che fare con la configurazione di FOP, ma non so come farlo :)

Grazie in anticipo.

P.S. Questo è il metodo che si chiama per visualizzare PDF:

public void printExchangeRateList(ActionEvent event) { 

    BufferedOutputStream output = null; 

    FacesContext facesContext = FacesContext.getCurrentInstance(); 
    ExternalContext externalContext = facesContext.getExternalContext(); 
    HttpServletResponse response = (HttpServletResponse) externalContext.getResponse(); 

    String path = externalContext.getRealPath("/"); 


    try { 

     response.reset(); 
     response.setHeader("Content-Type", "application/pdf"); 
     output = new BufferedOutputStream(response.getOutputStream(), 10240); 

     File xsltfile = new File(path+"/pdf_transform/xslt/transformFile.xsl"); 

     FopFactory fopFactory = FopFactory.newInstance(); 
     FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); 

     try { 
      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()); // my method 
      Result res = new SAXResult(fop.getDefaultHandler()); 

      transformer.transform(src, res); 


     } finally { 
      if (output != null) output.close(); 
      /*try { 
       out.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      }*/ 
     } 

    } catch (Exception e) { 
     // TODO Auto-generated catch block 
    } 

    facesContext.responseComplete(); 
} 

risposta

2

Se si ha accesso all'URL web per le immagini è possibile utilizzare tale anche quando la generazione di report, vale a dire http://localhost/images/logo.jpg.

Ma mentre avevo ancora le immagini in locale sul server web, ho incluso il percorso dell'applicazione nel file XML e utilizzato in questo modo:

<xsl:variable name="base_path" select="base-path"/> 
<xsl:variable name="logo" select="companies/company/logo"/> 
<fo:external-graphic src="url({$base_path}{logo})"/> 

Qualora la struttura XML potrebbe essere qualcosa di simile:

<?xml version="1.0" encoding="UTF-8"?> 
<base-path>/path/to/app/</base-path> 
<companies> 
    <company> 
    <logo>images/company1.jpg</logo> 
    </company> 
    <company> 
    <logo>images/company2.jpg</logo> 
    </company> 
</companies> 
+0

Grazie per la tua risposta. Ma non è quello che sto cercando. Quando crei xml, la stringa "/ path/to/app /" deve essere simile a "C: \ Eclipse \ workspace \ myProject \ .. etc" (se sto ottenendo il risultato giusto). Sto rendendo questa applicazione per essere pubblicabile e tutti i dati xml e le immagini di accesso devono essere referenziati nell'ambito di applicazione (scusa, non l'ho scritto esplicitamente nella mia domanda, lo modificherò ora). – Nikola

10

ho trovato la soluzione al mio problema. Pensavo di averlo provato, ma sembra che abbia fatto qualche piccolo errore all'epoca. In ogni caso, con il seguente codice

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

FopFactory fopFactory = FopFactory.newInstance(); 
fopFactory.setBaseURL(basePath); 
FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); 
foUserAgent.setBaseURL(fopFactory.getBaseURL()); 

Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, output); // for some output 

è possibile accedere alle immagini (e altre risorse) dal file XSLT utilizzando percorso relativo a partire dalla cartella WebContent dell'applicazione. Nel mio caso, posso accedere logo.jpg come questo

<fo:external-graphic src="url('pdf_transform/xslt/logo.jpg')"/> 

mi ha preso tempo per capire questo, io non capisco il motivo per cui nessun esempio con una tale cosa di base sulla rete (o non riesco a trovare li :)

0

ho avuto lo stesso problema e provato questa soluzione:

FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); 
    Request request = RequestCycle.get().getRequest(); 
    //sort of a hack to find the path to the files that are in /img folder. 
    String baseUrl = request.getUrl().getProtocol()+"://"+request.getUrl().getHost()+":"+request.getUrl().getPort(); 
    foUserAgent.setBaseURL(baseUrl); 

Poi, XSL ho usato:

<fo:external-graphic src="/img/image.png" /> 

diT est se funziona, dovresti essere in grado di vedere l'immagine sul protocollo: // link: port/img/image.png