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