2012-05-09 11 views
10

Im przy użyciu krewetki do tworzenia plików pdf, które zawierają wiele danych w formacie tabeli i niektóre listy. Problem z listami polega na tym, że po prostu używam tekstu jako list, ponieważ nie ma semantycznego odpowiednika list ul> li, jak używam ich w webfrointend. Listy nie są więc uzasadnione. Punkt listy, który używa więcej niż jednej linii wygląda na krem, ponieważ nie pasuję do ikony listy. Jak mogę zaimplementować listy w krewetkach, które nie wyglądają jak bzdura?Używanie list w krewetce

+0

co pan spróbować? – tmaximini

+0

Po prostu próbowałem dodawać listy jako teksty, ale wygląda na to, że się kręci, gdy komentarz ma więcej niż jeden wiersz. – davidb

Odpowiedz

23

Krewetka była dobrą biblioteką PDF, ale problemem jest własny system wyświetlania. Jest Prawn-format, ale nie jest już utrzymywany.

Proponuję użyć WickedPDF, pozwala to na włączenie prostego kodu ERB do pliku PDF.

Korzystanie Prawn: kolejny brudny i brzydki rozwiązaniem jest stół dwie kolumny bez obramowania, pierwsza kolumna zawiera list-pocisk, drugi tekst kolumna:

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

dziękuję, myślę, że to zadziała dla mnie, ... – davidb

+1

Świetnie! Możesz również użyć opcji 'cell_style: {borders: []}', aby pozbyć się granic i sprawić, że będzie wyglądać jak lista rzeczywista. – Diego

9

prostu miałem podobny problem i rozwiązać go w Krewetka nieco inny sposób niż za pomocą tabeli:

["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 

Może to oczywiście być ExTe nded (na przykład możesz tworzyć listy numerowane o wartości each_with_index() zamiast każdej()). Pozwala także na dowolną zawartość w ramce granicznej (co nie jest dozwolone w tabelach).

+1

To rozwiązanie ma problem, gdy dokument PDF ma wiele stron: gdy tekst przechodzi do następnej strony, pojawia się na dole. –

0

Jedną z opcji jest stworzenie metody podobnej do odpowiedzi CRM. Różnica polega na tym, że nie zostanie ona przerwana, gdy tekst przejdzie na inną stronę, a Ty możesz mieć również wiele poziomów.

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

Wystarczy zadzwonić to metoda tak:

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

Zapraszam byłaby.

4

Aby utworzyć punktor z wbudowaną czcionką Adobe, użyj \ u2022.

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

krewetki obsługuje symboli (czyli Glyphs) kodami WinAnsi i to musi być kodowany jako UTF-8. Zobacz ten post dla więcej szczegółów: https://groups.google.com/forum/#!topic/prawn-ruby/axynpwaqK1g

Instrukcja Prawn posiada kompletną listę glifów, które są obsługiwane.

+1

Dlaczego ta odpowiedź nie otrzymała więcej uznania? @Powers - sam użyłem tego, zadziałało idealnie. Trzeba powiedzieć, że twoja składnia zakłada enkapsulację w podwójnych cudzysłowach. – Tass

4

Po prostu zrobiłem to dla klienta. Dla każdego, kto chce uczynić preformatowany html zawierający list 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

Dzięki człowiekowi, naprawdę mi się przydało! Możliwe ulepszenia: 'String # blank?' Nie jest czystym Rubinem. Użyto '.strip == ''' jako szybkiej poprawki. Używam '# {item.strip}' podczas renderowania elementu wypunktowania, w przeciwnym razie skończyłem z linią po moich punktorach (prawdopodobnie ze względu na linka w moim znaczniku HTML) –

3

Doskonałym rozwiązaniem, które nie narusza pozycji kursora, a także uczynić jak prawdziwy listy z niewielkiej liczby linii kodu:

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 

Klauzula start_new_page obejmuje scenariusze, w których punktor może wymagać przejścia do następnej strony. Utrzymuje to zachowanie bulletu z treścią punktora.

Przykład PDF Screen Rendering:

Example Rendered List