2012-05-09 24 views
10

Im utilizando gambas para crear archivos PDF que contienen muchos datos en formato de tabla y algunas listas. El problema con las listas es que estoy usando el texto como listas porque no hay un equivalente semántico para las listas de ul> li como las uso en el webfrointend. Entonces las listas no están justificadas. Un punto de lista que utiliza más de una línea se ve poco creativo porque no encaja en el ícono de la lista. ¿Cómo puedo implementar listas en gambas que no parecen basura?Uso de listas en gambas

+0

lo probaste? – tmaximini

+0

Acabo de probar las listas de elementos como textos, pero se ve tan pronto como el comentario tiene más de una fila. – davidb

Respuesta

23

La gamba era una buena biblioteca de PDF pero el problema es su propio sistema de visualización. Hay Prawn-format pero ya no se mantiene.

Sugiero usar WickedPDF, le permite incluir código ERB simple en su PDF.

El uso de gambas: otra solución sucia y fea es una tabla de dos columnas sin borde, primera columna contiene la lista de bala, el segundo texto de la columna:

table([ ["•", "First Element"], 
     ["•", "Second Element"], 
     ["•", "Third Element"] ]) 
+0

gracias, creo que esto funcionará para mí, ... – davidb

+1

¡Genial! También puede usar 'cell_style: {borders: []}' como una opción para deshacerse de los bordes y hacer que parezca una lista real. – Diego

9

que acaba de tener un problema similar y resuelto dentro de la gamba de una manera ligeramente diferente que el uso de una tabla:

["Item 1","Item 2","Item 3"].each() do |list-item| 

    #create a bounding box for the list-item label 
    #float it so that the cursor doesn't move down 
    float do 
    bounding_box [15,cursor], :width => 10 do 
     text "•" 
    end 
    end 

    #create a bounding box for the list-item content 
    bounding_box [25,cursor], :width => 600 do 
    text list-item 
    end 

    #provide a space between list-items 
    move_down(5) 

end 

Esto podría ser, obviamente, exte nded (por ejemplo, podría hacer listas numeradas con each_with_index() en lugar de cada()). También permite contenido arbitrario en el cuadro delimitador (que no está permitido en las tablas).

+1

Esta solución tiene un problema cuando el documento PDF tiene varias páginas: cuando el texto pasa a la página siguiente, aparece en la parte inferior. –

0

Una vuelta es crear un método similar a la respuesta de crm. La diferencia es que no se romperá cuando el texto vaya a otra página y también puede tener múltiples niveles.

def bullet_item(level = 1, string) 
    indent (15 * level), 0 do 
     text "• " + string 
    end 
end 

simplemente llame a este método así:

bullet_item(1, "Text for bullet point 1") 
bullet_item(2, "Sub point") 

dude refactorizar.

4

Para crear una viñeta con la fuente incorporada de Adobe, use \ u2022.

\u2022 This will be the first bullet item 
\u2022 blah blah blah 

gamba soporta símbolos (aka glifos) con códigos de WinAnsi y estos deben ser codificados como UTF-8. Consulte esta publicación para obtener más información: https://groups.google.com/forum/#!topic/prawn-ruby/axynpwaqK1g

El manual de la gamba contiene una lista completa de los glifos que son compatibles.

+1

¿Por qué esta respuesta no recibió más reconocimiento? @Powers: solo usé esto, funcionó perfectamente. Debería decirse que su sintaxis supone la encapsulación entre comillas dobles. – Tass

4

Acabo de hacer esto por un cliente. Para todos los que quieran representar HTML con formato previo que contiene las listas de UL/ol:

def render_html_text(text, pdf) 
    #render text (indented if inside ul) 
    indent = 0 #current indentation (absolute, e.g. n*indent_delta for level n) 
    indent_delta = 10 #indentation step per list level 
    states = [] #whether we have an ol or ul at level n 
    indices = [] #remembers at which index the ol list at level n, currently is 

    #while there is another list tag do 
    # => starting position of list tag is at i 
    # render everything that comes before the tag 
    # cut everything we have rendered from the whole text 
    #end 
    while (i = text.index /<\/?[ou]l>/) != nil do 
    part = text[0..i-1] 
    if indent == 0 #we're not in a list, but at the top level 
     pdf.text part, :inline_format => true 
    else 
     pdf.indent indent do 
     #render all the lis 
     part.gsub(/<\/li>/, '').split('<li>').each do |item| 
      next if item.blank? #split may return some ugly start and end blanks 

      item_text = if states.last == :ul 
         "• #{item}" 
         else # :ol 
         indices[indices.length-1] = indices.last + 1 
         "#{indices.last}. #{item}" 
         end 

      pdf.text item_text, :inline_format => true 
     end 
     end 
    end 

    is_closing = text[i+1] == '/' #closing tag? 
    if is_closing 
     indent -= indent_delta 
     i += '</ul>'.length 

     states.pop 
     indices.pop 
    else 
     pdf.move_down 10 if indent == 0 

     type_identifier = text[i+1] #<_u_l> or <_o_l> 
     states << if type_identifier == 'u' 
        :ul 
       elsif type_identifier == 'o' 
        :ol 
       else 
        raise "what means type identifier '#{type_identifier}'?" 
       end 
     indices << 0 

     indent += indent_delta 
     i += '<ul>'.length 
    end 

    text = text[i..text.length-1] #cut the text we just rendered 
    end 

    #render the last part 
    pdf.text text, :inline_format => true unless text.blank? 
end 
+1

¡Gracias, hombre, ha sido realmente útil para mí! Posibles mejoras: '¿String # blank?' No es Ruby puro. Utiliza '.strip == ''' como una solución rápida. Utilicé '# {item.strip}' al representar un elemento de viñeta; de lo contrario, terminé con un salto de línea después de mis viñetas (debido a las alimentaciones de línea en mi marcado HTML probablemente) –

3

Una excelente solución que respete la posición del cursor, así como hacen como una verdadera lista con un pequeño número de líneas de código es:

items = ["first","second","third"] 
def bullet_list(items) 
    start_new_page if cursor < 50 
    items.each do |item| 
    text_box "•", at: [13, cursor] 
    indent(30) do 
     text item 
    end 
    end 
end 

La cláusula start_new_page cubre los escenarios en los que es posible que la línea de pedido tenga que pasar a la página siguiente. Esto mantiene la bala con el contenido de la bala.

Ejemplo de representación en PDF Captura de pantalla:

Example Rendered List

Cuestiones relacionadas