Верхний и нижний колонтитулы в Prawn PDF

Я прочитал все соответствующие посты на Prawn, но не нашел упоминания (даже в собственной документации Prawn) верхних и нижних колонтитулов.

Однако на собственном веб-сайте Prawnto я увидел демо-версию о верхних и нижних колонтитулах. Я скопировал весь исходный код этой демонстрации, просто чтобы посмотреть, работает ли он, но на ошибку неопределенного "заголовка" метода жаловались. Должен ли я понять, что Prawn недавно вытащил заголовок и нижний колонтитул в геме, или мне нужно сделать что-то еще, чтобы использовать верхний и нижний колонтитулы?

Демонстрационная страница: 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

И под заголовком, на всякий случай, я имею в виду фрагменты слов, которые обычно появляются в углу каждой страницы документа. Как ваш номер счета на ваших страницах счетов.

Спасибо!

7 ответов

Решение

@GrantSayer, спасибо за пример, но это позволит вам показать только номер текущей страницы, а не общее количество страниц.

Вы также можете использовать функцию 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

Пример, на который вы ссылаетесь, из плагина prawnto, использует более старую версию prawn.

Так как мне также нужны верхний и нижний колонтитулы, я посмотрел немного больше в этом. Похоже, что у этой версии 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

Вы можете проверить страницу документации повтора для других опций, которые позволяют вам точно указать, где вы хотите повторители.

Это немного отличается от последней версии Prawn, вы должны пройти хэш

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

Если вы хотите, чтобы нижний колонтитул не писал ничего по вашему тексту, вы должны создать bounding_box ниже поля документа, используя bounds.bottom,

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

Это должно выглядеть так, вы можете видеть, что нижний колонтитул находится за пределами поля:

пример результата

Надеюсь, это поможет кому-то

НАЧАТЬ РЕДАКТИРОВАТЬ

Это работает в креветках>= 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

Вот проблема при использовании 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, будет отображать текст нижнего колонтитула на каждой странице.

Единственный способ найти повторяющийся элемент на странице - это использовать Prawn::Document::LazyBoundingBox метод. По сути, это позволяет вам определить ограничивающий прямоугольник, который будет отображаться только после его вызова. Так обычный pseudo-code шаги

1. Define lazy bounding box element assign to somevar
2. One each new page call the element.

Пример из источника показывает, как

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

конец

Это дает вам вывод текста на каждой новой странице. Что было бы идеально, если бы это можно было применить при настройке шаблона страницы, который повторно используется без ручного вызова для визуализации элемента. В сочетании с текстовым потоком это дало бы традиционное решение колонтитулов.

Другие вопросы по тегам