Im использует креветку для создания PDF файлов, содержащих много данных в формате таблицы и некоторых списках. Проблема со списками заключается в том, что Im просто использует текст в виде списков, потому что нет семантического эквивалента спискам ul > li, как я их использую в webfrointend. Таким образом, списки arent оправданы. Точка списка, которая использует более одной строки, выглядит сложной, потому что я не подхожу к значку списка. Как я могу реализовать списки в креветках, которые не выглядят как дерьмо?
Использование списков в креветок
Ответ 1
Креветка была хорошей библиотекой PDF, но проблема заключается в ее собственной системе просмотра. Существует Prawn-format, но больше не поддерживается.
Я предлагаю использовать WickedPDF, он позволяет включать простой простой код ERB в ваш PDF файл.
Использование креветки: другое грязное и уродливое решение - это таблица с двумя столбцами без рамки, первый столбец содержит список-пулю, второй текст столбца:
table([ ["•", "First Element"],
["•", "Second Element"],
["•", "Third Element"] ])
Ответ 2
У меня была аналогичная проблема, и она была решена в креветке несколько иначе, чем с помощью таблицы:
["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
Это, очевидно, может быть расширено (например, вы могли бы делать нумерованные списки с помощью each_with_index(), а не each()). Он также допускает произвольное содержимое в ограничивающей рамке (что недопустимо в таблицах).
Ответ 3
Чтобы создать пулю с встроенным шрифтом Adobe, используйте \u2022.
\u2022 This will be the first bullet item
\u2022 blah blah blah
Креветка поддерживает символы (aka glyphs) с кодами WinAnsi, и они должны быть закодированы как UTF-8. См. Это сообщение для более подробной информации: https://groups.google.com/forum/#!topic/prawn-ruby/axynpwaqK1g
Руководство по креветке имеет полный список поддерживаемых глифов.
Ответ 4
Просто сделал это для клиента. Для всех, кто хочет отобразить предварительно форматированный html, содержащий списки 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
Ответ 5
Отличное решение, которое учитывает позицию курсора, а также отображение как истинного списка с небольшим количеством строк кода:
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
В предложении start_new_page рассматриваются сценарии, в которых для позиции маркера может потребоваться перейти на следующую страницу. Это позволяет сохранить пулю с содержанием пули.
Пример рендеринга PDF-рендеринга:
Ответ 6
Один ход - создать метод, похожий на crm-ответ. Разница в том, что он не сломается, когда текст перейдет на другую страницу, и вы также можете иметь несколько уровней.
def bullet_item(level = 1, string)
indent (15 * level), 0 do
text "• " + string
end
end
Просто вызовите этот метод следующим образом:
bullet_item(1, "Text for bullet point 1")
bullet_item(2, "Sub point")
Не стесняйтесь рефакторинга.