верхний и нижний колонтитулы в Prawn PDF - PullRequest
29 голосов
/ 23 апреля 2010

Я прочитал все соответствующие посты в 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 ]

33 голосов
/ 07 сентября 2010

Образец, на который вы ссылаетесь, из плагина 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

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

21 голосов
/ 27 мая 2010

@ 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
16 голосов
/ 15 июля 2011

С последней версией 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
9 голосов
/ 11 июня 2014

Если вы хотите, чтобы нижний колонтитул не записывал текст поверх текста, вы должны создать 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

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

example result

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

4 голосов
/ 22 мая 2013

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

Это работает в креветках> = 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
0 голосов
/ 12 марта 2018

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

0 голосов
/ 26 мая 2010

Единственный способ найти повторяющийся элемент на странице - это использовать метод 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

end

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

...