13

私はエビを使用して、テーブル形式の多くのデータといくつかのリストを含むPDFを作成しています。リストの問題は、Webfrointendで使用するようなul> liリストに相当するセマンティックがないため、Imがテキストをリストとして使用していることです。したがって、リストは正当化されません。複数の行を使用するリストポイントは、リストアイコンに合わないため、不気味に見えます。がらくたのように見えないエビのリストを実装するにはどうすればよいですか?

4

7 に答える 7

25

Prawn は優れた PDF ライブラリでしたが、問題は独自のビュー システムです。エビ形式がありますが、もう維持されていません。

WickedPDFを使用することをお勧めします。これにより、PDF に単純な ERB コードを含めることができます。

Prawn の使用: もう 1 つの汚い醜い解決策は、 border のない2 列のテーブルです。最初の列にはリストの箇条書きが含まれ、2 番目の列にはテキストが含まれます。

table([ ["•", "First Element"],
        ["•", "Second Element"],
        ["•", "Third Element"] ])
于 2012-06-23T16:10:40.697 に答える
9

同様の問題があり、テーブルを使用するのとは少し異なる方法で Prawn 内で解決しました。

["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() ではなく each_with_index() を使用して番号付きリストを作成できます)。また、境界ボックスに任意のコンテンツを含めることもできます (テーブルでは許可されていません)。

于 2012-10-05T21:37:02.250 に答える
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 レンダリングのスクリーンショットの例:

レンダリングされたリストの例

于 2014-09-11T14:57:17.813 に答える
4

顧客のためにこれを行いました。ul / ol リストを含む整形済みの html をレンダリングしたいすべての人のために:

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
于 2013-09-30T09:41:28.133 に答える
1

1 つの回避策は、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")

自由にリファクタリングしてください。

于 2013-06-18T14:43:41.913 に答える