Ruby-on-rails Prawn PDF 中的页眉和页脚
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2695019/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
header and footer in Prawn PDF
提问by Nik So
I have read through all relevant posts on Prawn but found no mentioning (even in Prawn's own documentation) of headers and footers.
我已经阅读了关于 Prawn 的所有相关帖子,但没有发现(甚至在 Prawn 自己的文档中)提到页眉和页脚。
However, I did see a demo on Prawnto's own website about headers and footers. I copied the entire source of that demo just to see if it works but an error of undefined method "header" is complained about. Am I to understand that Prawn took out header and footer recently in the gem or is there something else I need to do first to use header and footer?
但是,我确实在 Prawnto 自己的网站上看到了有关页眉和页脚的演示。我复制了该演示的整个源代码只是为了看看它是否有效,但有人抱怨未定义方法“标题”的错误。我是否理解 Prawn 最近在 gem 中取出页眉和页脚,或者我需要先做些什么才能使用页眉和页脚?
The demo page: http://cracklabs.com/prawnto/code/prawn_demos/source/text/flowing_text_with_header_and_footer
演示页面:http: //cracklabs.com/prawnto/code/prawn_demos/source/text/flowing_text_with_header_and_footer
the part of code of concern:
关注代码部分:
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
And by header, just in case, I mean the snippets of words that appear usually at a corner of every page of a document. Like your account number in your bills pages.
对于标题,以防万一,我指的是通常出现在文档每一页角落的单词片段。就像您帐单页面中的帐号一样。
thanks!
谢谢!
采纳答案by Gawin
@GrantSayer thx for the example, but this will only let you show the current page number, not the total number of pages.
@GrantSayer thx 例如,但这只会让您显示当前页码,而不是总页数。
You can also use the number_pagesfunction for the footer:
您还可以对页脚使用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
However, in my case I also need to format/style and right align the page numbers to match company style guides. I used go_to_page(k)to create my own header and footer functions, which add the header and footer to each page afterall the pages are created. This gives me both styling options and the total number of pages:
但是,在我的情况下,我还需要格式化/样式并右对齐页码以匹配公司样式指南。我使用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
回答by memical
The sample you are refering to, from the prawnto plugin, is using an older version of prawn.
您从 prawnto 插件中引用的示例使用的是旧版本的 prawn。
Since i also needed header and footer i looked a bit more into this. It seems that that version of prawn had header and footer methods, which were implemented using lazy bounding box. (found by checking the code on github)
由于我还需要页眉和页脚,因此我对此进行了更多研究。那个版本的 prawn 似乎有页眉和页脚方法,它们是使用惰性边界框实现的。(通过查看github上的代码找到)
In the new prawn version you can do the same thing using repeaters.
在新的 prawn 版本中,您可以使用中继器做同样的事情。
Here is the full sample rewritten using the new version:
以下是使用新版本重写的完整示例:
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
you can check the documentation page of repeat for other options which allow you to exactly specify where you want the repeaters.
您可以检查重复的文档页面以获取其他选项,这些选项允许您准确指定您想要中继器的位置。
回答by Joel AZEMAR
It's little bit different with latest version of Prawn you must passe an hash
与最新版本的 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
回答by onionpsy
If you want a footer that do not write stuff over your text, you have to create the bounding_boxbelow the margin of the document using bounds.bottom.
如果您想要一个不在文本上书写内容的页脚,则必须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
It should look like that, you can see that the footer is outside the margin bottom :
它应该是这样的,你可以看到页脚在边距底部之外:


Hope it help someone
希望它可以帮助某人
回答by konung
START EDIT
开始编辑
This works in prawn >= 0.12
这适用于对虾 >= 0.12
END EDIT
结束编辑
Here is my solution using repeat, canvas and cell. Essentially I'm drawing my bounding boxes at the absolute top and bottom of every page. I'm using cell to have better styling control over it. Hope this is going to be helpful to someone. ( I used slightly annoying colors to better illustrate how you can control styling of header and footer)
这是我使用重复、画布和单元格的解决方案。本质上,我在每个页面的绝对顶部和底部绘制我的边界框。我正在使用单元格来更好地控制它的样式。希望这会对某人有所帮助。(我使用了有点烦人的颜色来更好地说明如何控制页眉和页脚的样式)
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
回答by Grant Sayer
The only way I've found to get a repeating item on a page is to use the Prawn::Document::LazyBoundingBoxmethod. Basically this allows you to define a bounding box that is only rendered once you call it. So the usual pseudo-codesteps are
我发现在页面上获得重复项的唯一方法是使用该Prawn::Document::LazyBoundingBox方法。基本上,这允许您定义一个边界框,该边界框仅在您调用它时才呈现。所以通常的pseudo-code步骤是
1. Define lazy bounding box element assign to somevar
2. One each new page call the element.
The example from the source shows how
源代码中的示例显示了如何
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
结尾
This gives you a Page-count text output on each new page. What would be ideal is if this could be applied in the setup of a page template that is reused without the manual call to render the element. The combined with text flow it would give the traditional solution of headers and footers.
这为您提供了每个新页面上的 Page-count 文本输出。如果这可以应用于无需手动调用来呈现元素的重用页面模板的设置,那将是理想的。结合文本流,它将提供页眉和页脚的传统解决方案。
回答by PaulD
here's the problem when using the bounding_boxfor creating the custom footer contents... it is still rendering within the bounds of a margin.
这是使用bounding_box创建自定义页脚内容时的问题......它仍然在边距范围内呈现。
I was looking for something that will write the contents in the margin areatogether with number_pages.(because a footer usually is set in the bottom margin area)... and it seems that there were none.
我正在寻找可以将边距区域中的内容与number_pages.(因为页脚通常设置在底部边距区域中)一起写入的东西......似乎没有。
so instead, I used text_boxand place the coordinates outside my main bounding box like so:
所以相反,我使用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
take note that the repeat :all, will render this footer text to every page.
请注意,repeat :all, 会将此页脚文本呈现到每个页面。

