【问题标题】:header and footer in Prawn PDFPrawn PDF中的页眉和页脚
【发布时间】:2010-04-22 22:41:12
【问题描述】:

我已经阅读了所有关于 Prawn 的相关帖子,但没有发现(即使在 Prawn 自己的文档中)提到页眉和页脚。

但是,我确实在 Prawnto 自己的网站上看到了有关页眉和页脚的演示。我复制了该演示的整个源代码,只是为了看看它是否有效,但抱怨未定义方法“标题”的错误。我是否知道 Prawn 最近在 gem 中取出了页眉和页脚,或者我需要先做些什么才能使用页眉和页脚?

演示页面: http://cracklabs.com/prawnto/code/prawn_demos/source/text/flowing_text_with_header_and_footer

关注的代码部分:

Prawn::Document.generate("flow_with_headers_and_footers.pdf")  do

  header margin_box.top_left do 
      text "Here's My Fancy Header", :size => 25, :align => :center   
  end   

  text "hello world!"
end

为了以防万一,我指的是通常出现在文档每一页角落的单词的sn-ps。就像您账单页面中的帐号一样。

谢谢!

【问题讨论】:

    标签: ruby-on-rails prawn prawnto


    【解决方案1】:

    您所指的示例,来自 prawnto 插件,使用的是旧版本的 prawn。

    由于我还需要页眉和页脚,所以我对此进行了更多研究。似乎那个版本的虾有页眉和页脚方法,它们是使用惰性边界框实现的。 (通过查看github上的代码找到)

    在新的大虾版本中,您可以使用中继器来做同样的事情。

    这是使用新版本重写的完整示例:

    require "#{File.dirname(__FILE__)}/../example_helper.rb"
    
    Prawn::Document.generate("test.pdf")  do
    
       repeat :all do
        # header
        bounding_box [bounds.left, bounds.top], :width  => bounds.width do
            font "Helvetica"
            text "Here's My Fancy Header", :align => :center, :size => 25
            stroke_horizontal_rule
        end
    
        # footer
        bounding_box [bounds.left, bounds.bottom + 25], :width  => bounds.width do
            font "Helvetica"
            stroke_horizontal_rule
            move_down(5)
            text "And here's a sexy footer", :size => 16
        end
      end
    
      bounding_box([bounds.left, bounds.top - 50], :width  => bounds.width, :height => bounds.height - 100) do                 
       text "this is some flowing text " * 200    
    
       move_down(20)
    
       font "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf"
       table [["ὕαλον ϕαγεῖν",    "baaar",             "1" ],
              ["This is","a sample",          "2" ],
              ["Table",  "dont\ncha\nknow?",  "3" ],
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules\nwith an iron fist", "x" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],   
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ],  
              [ "It",    "Rules",             "4" ],     
              [ "It",    "Rules",             "4" ]],     
    
         :font_size          => 24, 
         :horizontal_padding => 10,
         :vertical_padding   => 3,
         :border_width       => 2,
         :position           => :center,
         :headers            => ["Column A","Column B","#"]
    
      end
    end
    

    您可以查看 repeat 的文档页面以获取其他选项,这些选项允许您准确指定中继器的位置。

    【讨论】:

      【解决方案2】:

      @GrantSayer thx 示例,但这只会让您显示当前页码,而不是总页数。

      您还可以将 number_pages 函数用于页脚:

      Prawn::Document.generate("page_with_numbering.pdf") do
        text "Hai"
        start_new_page
        text "bai"
        start_new_page
        text "-- Hai again"
        number_pages "<page> in a total of <total>", [bounds.right - 50, 0]
      end
      

      但是,就我而言,我还需要格式化/样式并右对齐页码以匹配公司样式指南。我使用go_to_page(k) 创建了我自己的页眉和页脚函数,在创建所有页面之后 将页眉和页脚添加到每个页面。这给了我样式选项和总页数:

      Prawn::Document.generate("footer_example.pdf", :skip_page_creation => true) do
        10.times do
          start_new_page
          text "Some filler text for the page"
        end
      
        # footer
        page_count.times do |i|
          go_to_page(i+1)
          lazy_bounding_box([bounds.right-50, bounds.bottom + 25], :width => 50) {
            text "#{i+1} / #{page_count}"
          }.draw
        end
      end
      

      【讨论】:

      • 我仍然想知道您是如何管理的,在这种情况下,大虾不会在您的页脚框上写东西。我正在使用相同的方式,但它不起作用。当您增加文本量时,您的示例中也会发生同样的情况。只需删除 start_new_page 并将“* 100”添加到循环内的文本行。我通常将整个文档移动到一个边界框中并减去页眉/页脚框的大小以避免此类问题。
      • 那个页脚示例确实为我节省了数小时的痛苦。
      【解决方案3】:

      与最新版本的虾有点不同,你必须传递一个哈希

      Prawn::Document.generate("page_with_numbering.pdf") do
        text "Hai"
        start_new_page
        text "bai"
        start_new_page
        text "-- Hai again"
        number_pages "<page> in a total of <total>", { :start_count_at => 0, :page_filter => :all, :at => [bounds.right - 50, 0], :align => :right, :size => 14 }
      end
      

      【讨论】:

      【解决方案4】:

      如果您想要一个不会在您的文本上写东西的页脚,您必须使用bounds.bottom 在文档边距下方创建bounding_box

      require 'prawn'
      
      file_name = 'hello.pdf'
      random_table = (0..50).map{|i|[*('a'..'z')]} # generate a 2D array for example (~2 pages)
      
      Prawn::Document::generate(file_name) do |pdf|
          pdf.table random_table
          pdf.page_count.times do |i|
              pdf.bounding_box([pdf.bounds.left, pdf.bounds.bottom], :width => pdf.bounds.width, :height => 30) {
              # for each page, count the page number and write it
              pdf.go_to_page i+1
                   pdf.move_down 5 # move below the document margin
                   pdf.text "#{i+1}/#{pdf.page_count}", :align => :center # write the page number and the total page count
              }
          end
      end
      

      应该是这样的,你可以看到页脚在边距底部之外:

      希望对大家有所帮助

      【讨论】:

        【解决方案5】:

        开始编辑

        这适用于虾 >= 0.12

        结束编辑

        这是我使用重复、画布和单元格的解决方案。本质上,我在每一页的绝对顶部和底部绘制我的边界框。我正在使用单元格对其进行更好的样式控制。希望这会对某人有所帮助。 (我使用了一些令人讨厌的颜色来更好地说明如何控制页眉和页脚的样式)

         Prawn::Document.generate("headers_and_footers_with_background.pdf") do
          repeat :all do
            # header
            canvas do
              bounding_box([bounds.left, bounds.top], :width => bounds.width) do
                cell :content => 'Header',
                     :background_color => 'EEEEEE',
                     :width => bounds.width,
                     :height => 50,
                     :align => :center,
                     :text_color => "001B76",
                     :borders => [:bottom],
                     :border_width => 2,
                     :border_color => '00FF00',
                     :padding => 12
              end
            end
            # footer
            canvas do
              bounding_box [bounds.left, bounds.bottom + 50], :width  => bounds.width do
                cell :content => 'Footer',
                     :background_color => '333333',
                     :width => bounds.width,
                     :height => 50,
                     :align => :center,
                     :text_color => "FFFFFF",
                     :borders => [:top],
                     :border_width => 2,
                     :border_color => 'FF0000',
                     :padding => 12
              end
            end
          end
          # body
          bounding_box([bounds.left, bounds.top - 25], :width  => bounds.width, :height => bounds.height - 50) do
            100.times do
              text "Some filler text for the page"
            end
          end
        end
        

        【讨论】:

        • 非常感谢,这正是我想要的。
        【解决方案6】:

        这是使用bounding_box 创建自定义页脚内容时的问题...它仍在边距范围内呈现。

        我一直在寻找可以将内容在边距区域number_pages一起写入的东西。(因为页脚通常设置在底部边距区域中)......而且似乎没有。

        因此,我使用text_box 并将坐标放置在我的主边界框之外,如下所示:

        repeat :all do
              text_box "My custom footer", size: 7, align: :center, :at => [bounds.left, bounds.bottom], :height => 100, :width => bounds.width
        end
        

        请注意,repeat :all 会将此页脚文本呈现到每一页。

        【讨论】:

          【解决方案7】:

          我发现在页面上获得重复项的唯一方法是使用Prawn::Document::LazyBoundingBox 方法。基本上,这允许您定义一个边界框,该边界框仅在您调用它时才呈现。所以通常的pseudo-code 步骤是

          1. 定义惰性边界框元素分配给 somevar
          2. 在每个新页面上调用元素。

          来自源代码的示例显示了如何

          file = "lazy_bounding_boxes.pdf"
          Prawn::Document.generate(file, :skip_page_creation => true) do
            point = [bounds.right-50, bounds.bottom + 25]
            page_counter = lazy_bounding_box(point, :width => 50) do
              text "Page: #{page_count}"
            end 
          
            10.times do
              start_new_page
              text "Some filler text for the page"  
              page_counter.draw
            end
          end
          

          这会在每个新页面上为您提供页面计数文本输出。理想的情况是,如果可以将其应用于页面模板的设置,该页面模板无需手动调用即可重用以呈现元素。结合文本流,这将提供传统的页眉和页脚解决方案。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-05-16
            • 1970-01-01
            • 2014-02-13
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多