Prawn es una herramienta increíblemente configurable y flexible para la generación de PDF. Le permite crear aburridos archivos PDF de estilo financiero que casi pueden imitar una hoja de cálculo Excel (estática), y también puede crear una carta de invitación de la fiesta convincente.
Una de las muchas herramientas de Prawn para permitir este tipo de flexibilidad es el Repetidor. Le permite definir una sección de su PDF, y reutilizarlo una y otra vez, esencialmente sello en cada página (o sólo en páginas extrañas, o en las primeras 10 páginas, etc, también puede configurarlo).
Vamos a crear un documento PDF simple como ejemplo:
app/pdfs/base_pdf.rb:
clase BasePdf c) Prawn::Documento def inicialización super() generate pdf final def generate pdf repetición Todos do texto 'Test' final 3.veces {} start new page } final finalapp/controllers/application_controller.rb:
def informe send data BasePdf.nuevo.render, Tipo: 'application/pdf', enajenación: 'inline' final
Ahora tenemos que ir a localhost:3000/report.pdf (después de configurar la ruta) y se mostrará el PDF, que contendrá 3 páginas con el mismo texto 'Test' impreso en cada una de ellas.
Vamos a entender cómo sucede esto: Cuando ese código llama repeat :all, y pasar un bloque a ella, es esencialmente decir a Prawn a:
- Crear un nuevo
Stamp(Piensa en ello como un sello real). - Repita este sello Todos páginas del PDF (3 en nuestro ejemplo). También no importa si llamaste
repeatdespués de llamarstart_new_pageantes, hará el repetidor encendido cada uno página. - Render todo lo que está dentro del bloque en este nuevo sello (en nuestro caso un texto simple), por lo que cuando Prawn "estamps" que sellará exactamente lo mismo una y otra vez.
Sin embargo, este "estamping" no sucede inmediatamente, ni ocurre cuando se inicia una nueva página. Prawn sólo "amplificará" al repetidor después de que se haya definido todo el documento, cuando el método render se llama. Normalmente quieres llamar render cuando quieras enviar el PDF al usuario, así que siempre estará al final.
El problema con repetidores dinámicos
¿Y si quieres cambiar lo que hay dentro de esto? StampVeamos una nueva situación, más similar al mundo real, donde tengo un PDF con muchas páginas, y necesito imprimir información diferente en el encabezado para diferentes páginas. Si usted ya sabe el número exacto de páginas que el PDF tendrá y qué página tiene qué información, usted puede hacer algo así:
app/pdfs/base_pdf.rb
def header repetición Todos, dinámica: verdadero do si (Asuntos)page number c) 5) texto 'Una cosa' más texto Otra cosa final final final
Todo está bien y alegre, hasta que te metas en una situación como esta:
app/pdfs/base_pdf.rb
# Quiero imprimir el nombre del país de la primera ciudad en la página actual def header country repetición Todos, dinámica: verdadero do texto @current country final final # Asumimos que las ciudades son un hash, donde cada clave es un país y contiene una variedad de ciudades para cada país def print cities of the world(Asuntos)all cities) all cities.cada uno do Silenciopaís, ciudadesSilencio @current country = país ciudades.cada uno do SilenciociudadSilencio texto ciudad final final final
Por eso existen repetidores dinámicos. Te permiten cambiar el contenido del sello para cada página.