使用Prawn Gem渲染动态页眉时report_date不更新的问题
Prawn Gem 页眉日期不更新问题修复
问题根源
你在render_page方法里使用了pdf.repeat(:all, dynamic: true),但这个方法的作用是为所有页面添加重复渲染的内容。当循环处理每个页面时,每次调用render_page都会重新定义这个repeat块,后面的定义会覆盖前面的,最终所有页面的页眉都会使用最后一次循环传入的report_date值。
快速修复方案
去掉repeat(:all)逻辑,直接在每个页面创建时渲染页眉页脚即可——毕竟你本来就是逐个循环生成页面的:
修改后的完整代码
def render_pages(pdf) grouped_items = rows.group_by { |item| item[0] } grouped_items.each_with_index do |(report_date, booking_items), index| render_page(pdf, report_date, booking_items) pdf.start_new_page unless index == grouped_items.size - 1 end end # 渲染单页PDF # # @param pdf [Prawn::Document] PDF对象 def render_page(pdf, report_date, booking_items) # 直接渲染当前页面页眉 pdf.bounding_box([pdf.bounds.left, pdf.bounds.top], width: pdf.bounds.width) do render_header(pdf, report_date, organisation_name) end # 直接渲染当前页面页脚 pdf.bounding_box([pdf.bounds.left, pdf.bounds.bottom + 150 ], width: pdf.bounds.width) do render_footer(pdf) end render_body(pdf, report_date , booking_items) end def render_header(pdf, report_date, organisation_name) pdf.image open("https://s3.amazonaws.com/www-inside-design/uploads/2019/05/woolmarkimagelogo-1024x576.png"), width: 80, height: 80, position: :center pdf.text "HEY #{report_date}" pdf.table( [ ["#{"Sumanth Samala PVT LTD"} - #{format_report_date(report_date)} \n Attendance Register", "Customer to complete all sections below \n Generated on #{Time.now.strftime("%d/%m/%Y %H:%M")}"] ], width: pdf.bounds.width, row_colors: ["808080"], cell_style: header_cell_style ) do |table| table.column(0).width = 464 end end
进阶方案(保留repeat逻辑)
如果需要后续新增页面也自动带页眉页脚,可以把所有日期提前存入数组,结合页码动态获取对应日期:
def render_pages(pdf) grouped_items = rows.group_by { |item| item[0] } @report_dates = grouped_items.keys # 提前存储所有页面的日期 # 只定义一次repeat块 pdf.repeat(:all, dynamic: true) do pdf.bounding_box([pdf.bounds.left, pdf.bounds.top], width: pdf.bounds.width) do current_date = @report_dates[pdf.page_number - 1] # 页码从1开始,数组索引从0开始 render_header(pdf, current_date, organisation_name) end pdf.bounding_box([pdf.bounds.left, pdf.bounds.bottom + 150 ], width: pdf.bounds.width) do render_footer(pdf) end end # 循环渲染页面主体内容 grouped_items.each_with_index do |(report_date, booking_items), index| render_body(pdf, report_date , booking_items) pdf.start_new_page unless index == grouped_items.size - 1 end end
内容的提问来源于stack exchange,提问作者Samala Sumanth
相关产品推荐
相关产品推荐

