Este foro ya no está activo, así que no puedes publicar nuevas preguntas ni responder a las preguntas existentes.

Visor de documentos

13 de noviembre de 2013

Hola Javier,

Primero darte nuevamente las gracias por resolverme en este foro las dudas que tenía acerca de guardar de forma temporal datos, que pude solucionar con éxito gracias a las sesiones.

Siguiendo con el proyecto que estoy desarrollando, se me ha ocurrido la idea de mostrar documentos PDF en una parte de una plantilla al usuario. Luego he pensado que sería interesante mostrar también otros formatos como DOC, ODF, etc. ¿Tienes alguna idea de cómo visualizar en la mayor parte de navegadores este tipo de documentos?

Igualmente, he pensado en la posibilidad de que el usuario de la extranet pueda subir ficheros de este tipo, para que el usuario del frontend los pueda ver. No estoy interesado en generarlos desde mi web, sólo que puedan ser leídos.

¿Algún bundle/plugin fiable del que sepas?

Un saludo


Respuestas

#1

Por lo que he visto, hacer un visor de documentos sencillo es fácil, pero hacer un visor de documentos completo es extremadamente difícil.

El visor de documentos sencillo puedes crearlo por ejemplo con la librería pdf.js, que visualiza documentos PDF en el navegador sin usar plugins y con jPlayer que es una librería multimedia para jQuery con el que podrás ver todos los formatos de audio y vídeo más comunes.

Si no quieres programar a mano el código necesario para crear tu visor con todas estas librerías, puedes comprar en CodeCanyon un plugin para jQuery que ya lo hace.

Como te decía al principio, el problema es que tú necesitas un visor de documentos muy completo y eso es extremadamente difícil. No conozco ningún visor completo de DOC y ODF que esté programado con JavaScript. No se si es posible, pero como solución se me ocurre que podrías subir los documentos al Google Drive corporativo de la empresa (usando quizás Google Apps) y utilizar después el visor que proporciona el propio Google Drive y que soporta absolutamente todos los formatos.

@javiereguiluz

14 noviembre 2013, 9:03
#2

Tras mucho buscar he hallado un plugin de jQuery llamado Viewer.js que me viene al pelo y con el que se puede visualizar PDF y ODF, pero ahora... ¿Cómo instalo el plugin? Este viene con una estructura de carpetas propia, con archivos CSS, JS, imágenes, etc.

Encuentro mucha documentación para instalar plugins en Symfony 1.x, pero muy poquito para Symfony 2.2.

Aquí exponen una posible solución que no acabo de comprender.

@Jorge_Gante

14 noviembre 2013, 18:01
#3

El plugin Viewer.js tiene muy buena pinta, pero parece que no soporta ni archivos multimedia ni documentos de Microsoft Office :(

Respecto a cómo instalarlo bien con Symfony2, no es algo que esa inmediato. El problema de integrar plugins de JavaScript en Symfony2 es que en el código JavaScript y CSS se utilizan rutas para cargar imágenes y otros archivos. Estas rutas suelen estar hardcodeadas y por eso es muy fácil que los plugins se rompan o algunas partes no funcionen.

De todas formas, he estado echando un vistazo al código del plugin y es posible que no tengas que hacer casi ningún cambio. Pero para ello, te aconsejo que no utilices Assetic para comprimir y combinar los archivos JavaScript.

En primer lugar, copia los archivos CSS y JS del plugin en los directorios Resources/public/* típicos del bundle donde vayas a instalar este plugin. Después, enlaza en tus plantillas Twig el archivo CSS y los dos archivos JavaScript tal y como se indica en la documentación del plugin:

<link rel="stylesheet" type="text/css"
      href="{{ asset('bundles/acme/css/viewer.css') }}"/>
 
<script src="{{ asset('bundles/acme/js/viewer.js') }}"
        type="text/javascript"></script>
<script src="{{ asset('bundles/acme/js/PluginLoader.js') }}" 
        type="text/javascript"></script>

Si te fijas en el código del archivo PluginLoader.js, verás que carga el resto de archivos JavaScript de forma relativa respecto a su ruta, por lo que no deberías tener ningún problema:

// ...
function loadPlugin(pluginName, callback) {
    // ...
    script = document.createElement('script');
    script.async = false;
    script.onload = callback;
    script.src = pluginName + '.js';  // <-- RUTA RELATIVA
    script.type = 'text/javascript';
 
    document.getElementsByTagName('head')[0].appendChild(script);
}
 
function loadDocument(documentUrl) {
    // ...
 
    loadPlugin('./ODFViewerPlugin', function () {
        ...
    });
}

Con todo esto, el único problema que te puedes encontrar es el de las imágenes enlazadas desde el archivo viewer.css, como por ejemplo:

#toolbarContainer {
    /* ... */
 
    background-image: url('images/texture.png'),  /* <-- RUTA RELATIVA */
        linear-gradient(rgba(82, 82, 82, .99), rgba(69, 69, 69, .95));
}

Para solucionarlo, lo que debes hacer es mantener el directorio images/ original dentro del directorio css/. Cuando instales los assets de la aplicación con el comando assets:install, Symfony2 copia todos los directorios y subdirectorios, por lo que las imágenes también se copiarán.

@javiereguiluz

14 noviembre 2013, 23:17
#4

Tras haber hecho lo abajo escrito, el servidor me dice que no encuentra Viewer.js en mi sistema:

Not Found
 
The requested URL /Viewer.js/ was not found on this server.

Paso a paso, lo que me has dicho. Ten en cuenta que mi proyecto parte de una estructura similar a la del tuyo, CUPON:

  • [1º] He copiado los ficheros JS y CSS del plugin, en las carpetas del bundle en el que voy a darles uso, que son respectivamente en mi caso: PprsBundle/Resources/public/js y PprsBundle/Resources/public/css. En esta última carpeta, he copiado íntegra la carpeta images/ del plugin.

  • [2º] Luego he añadido en los blocks stylesheets y javascripts de la plantilla app/Resources/views/frontend.html.twig el siguiente código:

{% stylesheets '@PprsBundle/Resources/public/css/viewer.css'
               output='css/frontend.css' %}
    <link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
{% endstylesheets %}
 
{% javascripts '@PprsBundle/Resources/public/js/*' output='js/viewer.js' %}
    <script src="{{ asset_url }}" type="text/javascript"></script>
{% endjavascripts %}
 
{% javascripts '@PprsBundle/Resources/public/js/*' output='js/PluginLoader.js' %}
    <script src="{{ asset_url }}" type="text/javascript"></script>
{% endjavascripts %}`
  • [3º] Finalmente he ejecutado en la consola lo siguiente (lo que ha provocado que las fuentes se vean más grandes en todo mi proyecto y no se porqué):
$ php app/console assets:install web --symlink

@Jorge_Gante

15 noviembre 2013, 13:15
#5

@Jorge_Gante, el problema que veo en lo que has hecho es que estás mezclando Assetic en las plantillas y assets normales con el comando assets:install.

En mi respuesta anterior te comentaba que mi consejo es que no utilices Assetic en este caso, ya que no se trata de un archivo JavaScript simple, sino que son varios archivos JavaScript que se cargan dinámicamente y llevan asociados CSS e imágenes. Si combinas y comprimes estos archivos JS y CSS con Assetic, puedes encontrarte con problemas.

Prueba a utilizar este código en tu plantilla:

<link rel="stylesheet" type="text/css"
      href="{{ asset('bundles/acme/css/viewer.css') }}"/>
 
<script src="{{ asset('bundles/acme/js/viewer.js') }}"
        type="text/javascript"></script>
<script src="{{ asset('bundles/acme/js/PluginLoader.js') }}" 
        type="text/javascript"></script>

Después, carga los assets con el comando asset:install, y si hace falta, borra la caché del proyecto. Si te sigue sin funcionar, mira con las herramientas de depuración del navegador cuál es la URL de los archivos JavaScript en la plantilla, cuál es la petición HTTP que realiza el navegador para esos archivos y cuál es la respuesta HTTP que recibe de la aplicación.

@javiereguiluz

15 noviembre 2013, 15:26
#6

Perdona por darte tanto la lata. He hecho lo que has escrito en el mensaje anterior (cambiando acme por pprs, siendo el nombre del bundle PprsBundle) en la plantilla en la que voy a hacer uso del plugin. Además he instalado los assets. El caso es que cuando veo el código fuente de la plantilla y pincho encima del enlace generado por los assets, se me redirige correctamente al código fuente de los ficheros viewer.css, viewer.js y PluginLoader.js, por lo que deduzco que están incluidos correctamente.

El problema viene cuando voy a utilizar viewer.js. En el manual se indica que para incluir cualquier fichero con los formatos especificados en una página, debo escribir lo siguiente en la plantilla (considerando que tengo una carpeta demo, no se en dónde):

<iframe id="viewer" src="/Viewer.js/#../demo/ohm2013.odp" width='400' height='300' allowfullscreen webkitallowfullscreen>

Al hacer esto, la plantilla se visualiza incorrectamente y en la caja del <iframe> me dice que no se encuentra la URL pedida /Viewer.js/ con lo cual no se si es problema de que el PDF no está en la carpeta correcta o es que no se invoca al plugin adecuadamente.

@Jorge_Gante

17 noviembre 2013, 4:32
#7

Según la documentación de viewer.js, el atributo src está formado por una primera parte donde se indica la ruta de viewer.js y una segunda parte donde se indica la ruta del archivo que quieres embeber. Además, para que funcione bien tienes que separar las dos partes con #..

Así que partiendo del ejemplo original que has puesto:

<iframe id="viewer" src="/Viewer.js/#../demo/ohm2013.odp" width='400' height='300'
        allowfullscreen webkitallowfullscreen>

Primero tendrías que generar la ruta del archivo viewer.js con la función asset():

<iframe id="viewer" src="{{ asset('bundles/acme/js/viewer.js') }}/#../demo/ohm2013.odp"
        width='400' height='300'
        allowfullscreen webkitallowfullscreen>

Después, tienes que cambiar la ruta del archivo para apuntar al archivo que quieres embeber. En Symfony2 normalmente estos archivos estarían en la carpeta web/uploads/, por lo que quedaría así:

<iframe id="viewer"
        src="{{ asset('bundles/acme/js/viewer.js') }}/#../uploads/mi_archivo.odp"
        width='400' height='300'
        allowfullscreen webkitallowfullscreen>

@javiereguiluz

17 noviembre 2013, 12:12
#8

Bueno, después de muchas pruebas conseguí finalmente instalar el plugin de marras... para llevarme un chasco: se solapan algunas letras y por tanto no se visualiza correctamente.

Al parecer está en pleno desarrollo y tiene aún muchos errores que resolver. De todas formas están puliéndolo y no lo voy a descartar del todo, seguiré haciendo mi página con la esperanza de que lo mejorarán en breve.

Ya para cerrar el asunto, te dejo aquí, paso a paso, como lo he hecho para que me funcione, por si a otras personas le interesa:

1) Se copian todos los ficheros JS del plugin en la carpeta AcmeBundle/Resources/public/js. Muy importante: a esta carpeta tiene que copiarse el archivo index.html del plugin. Este archivo debe editarse y hay que cambiar esta línea:

<link rel="stylesheet" type="text/css" href="css/viewer.css" media="screen"/>

Por esta otra:

<link rel="stylesheet" type="text/css" href="../css/viewer.css" media="screen"/>

2) Se copian todos los ficheros CSS del plugin en la carpeta AcmeBundle/Resources/public/css. Se debe editar el archivo viewer.css y cambiar todas las url(images/resto_ruta) por url(../images/resto_ruta).

3) La carpeta /images del plugin se mueve, teniendo que quedar en AcmeBundle/Resources/public/images.

4) Se instalan los assets: php app/console assets:install web (que realmente es lo mismo que si copiáramos las carpetas mencionadas en /web/bundles/acme/)

5) Y finalmente, en la plantilla en la que quieras embeber el visor de documentos:

<iframe id="viewer" width="700" height="500"
    src="{{ asset('bundles/acme/js/index.html') }}#../../../uploads/nombre_archivo.pdf"
    allowfullscreen webkitallowfullscreen></iframe>

@Jorge_Gante

18 noviembre 2013, 1:15
#9

Gracias por compartir la solución completa y lamento que el plugin no tenga todavía la calidad suficiente como para mostrar bien los documentos.

El único punto débil que le veo a tu solución es el punto 2). Al cambiar a mano el código fuente del plugin original, el mantenimiento será más difícil porque en cada actualización habrá que volver a cambiar esas URL y buscar si hay nuevas URL que deban cambiarse.

@javiereguiluz

18 noviembre 2013, 8:38
#10

La alternativa a cambiar las rutas es mantener la integridad de las carpetas del plugin en /web/bundles/acme/, extrayendo los ficheros del plugin directamente en esa carpeta.

Un saludo

EDITO: De esta forma me funciona estupendamente la visualización de PDFs.

@Jorge_Gante

18 noviembre 2013, 14:19
#11

Hola soy novata en lenguajes y programando. Hasta ahorita he hecho mi página web y corre en mi servidor local, cuenta con datos dinámicos y claro tengo mi base de datos. Los usuarios suben archivos pero mi duda es si las respuestas que han dado arriba me servirían para que en mi página se puedan vizualizar los archivos, ya que suben los archivos y se almacenan en una carpeta pero no se cómo hacer para que sean visibles y tengan la opcion de descargar.

Saludos y gracias

@LindaProg

23 agosto 2014, 20:56