2010-11-18 31 views
9

Esta es mi primera pregunta aquí, espero hacerlo bien. Lo siento por mi mal inglés por adelantado :)FOP: cómo especificar la ruta relativa de src de la imagen?

Estoy usando JSF 2.0 (Eclipse IDE) y estoy tratando de generar algunos archivos PDF utilizando Apache FOP 1.0.

Pude crear archivos PDF sencillos usando las instrucciones en Apache Fop site, pero no puedo insertar ninguna imagen desde la carpeta de mi aplicación. Mi estructura de carpetas es la siguiente: En mi WebContent aplicación tengo (entre demás) pdf_transform/XSLT/transformFile.xsl y pdf_transform/XSLT/logo.jpg

En transformFile.xsl tengo

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

pero cuando clik botón 'showPDF' en mi servlet, consigo archivo PDF sin imagen (todo lo demás está allí), y estos mensajes en la consola:

GRAVES: La Fuente que fue devuelto fr La resolución de URI om no contiene un InputStream para URI: logo.jpg 18 de noviembre de 2010 5:16:49 PM org.apache.fop.events.LoggingEventListener processEvent SEVERE: Imagen no encontrada. URI: logo.jpg. (No hay información de contexto disponibles)

me trató de usar 'logo.jpg' en lugar de url ('logo.jpg'), imagen poniendo en varios lugares dentro de la carpeta WebContent y el uso de navegación diferente (" ./ logo .jpg ") pero no funcionó.

Funciona bien si establezco la ruta absoluta (por ejemplo "d: /fop/images/logo.jpg") pero necesito resurces en mi aplicación.

Mientras buscaba, encontré que esto está relacionado con fopFactory.setURIResolver() y/o userAgent.setBaseURL(). Intentó algo con eso, pero no tuvo éxito.

Soy nuevo en JSF y FOP, y esta situación de imagen me ha estado molestando bastante tiempo. ¿Alguien puede ayudarme con esto, o al menos dirigirme a algún tutorial sobre "cómo configurar FOP para el uso relativo de la ruta"?

EDITAR: No quiero ninguna ruta de acceso absoluta y la aplicación debería funcionar independientemente de su ubicación en la computadora (para ser publicable). Mi búsqueda me dice que tiene algo que ver con la configuración de FOP, pero no sé cómo hacerlo :)

Gracias de antemano.

P.S. Este es el método que se llama para visualizar 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(); 
} 

Respuesta

2

Si tiene acceso a la URL de acceso a las imágenes que se pueden utilizar, así que cuando la generación de informes, es decir http://localhost/images/logo.jpg.

Sin embargo, aunque todavía tenía las imágenes de forma local en el servidor web, que incluye la ruta de acceso a la aplicación en el archivo XML y se utiliza de esta manera:

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

Cuando la estructura XML podría ser algo como esto:

<?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

Gracias por su respuesta. Pero eso no es lo que estoy buscando. Cuando crea xml, la cadena "/ ruta/a/aplicación /" debe tener un aspecto similar a "C: \ Eclipse \ workspace \ myProject \ .. etc" (si lo estoy haciendo bien). Estoy haciendo que esta aplicación sea publicable y todos los datos xml e imágenes que estoy accediendo deben ser referenciados dentro del alcance de la aplicación (lo siento, no lo escribí explícitamente en mi pregunta, la editaré ahora). – Nikola

10

encontré la solución a mi problema. Pensé que había intentado eso, pero parece que cometí un pequeño error en ese entonces. De todos modos, con el siguiente código

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 

puede acceder a sus imágenes (y otros recursos) de su archivo XSLT usando ruta relativa desde la carpeta WebContent de su aplicación. En mi caso, puedo acceder logo.jpg como esto

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

Me llevó tiempo para averiguar esto, yo no entiendo por qué no hay ejemplos con tal cosa básica en la red (o no puedo encontrar ellos :)

0

que tenían el mismo problema y trató esta solución:

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); 

Luego, el XSL que se utiliza:

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

a t Si esto está funcionando, debería poder ver la imagen en el protocolo: // link: port/img/image.png

Cuestiones relacionadas