prawn-table icon indicating copy to clipboard operation
prawn-table copied to clipboard

column widths not working

Open raquelhortab opened this issue 1 year ago • 4 comments

Hi! I got a table with subtables inside. I can successfully control the subtables' column widths but not the main table ones. Here's the code and below the result. If TLDR, important code is towards the end.

tmp_dir = Rails.root.join("tmp")
path = tmp_dir + "work_hours_test.pdf"

pdf = Prawn::Document.new(:page_size => PDF::Core::PageGeometry::SIZES["A4"])

title = [[{content: I18n.t('ubiquo.work_hours_month_validation.pdf.title').upcase, colspan: 3}]]

signature_table = pdf.make_table(
  [
    ["#{I18n.t('ubiquo.work_hours_month_validation.pdf.signature')}:", {image: '/home/raquel/Documents/signature_example.png', :image_height => 70}],
    [{content: "#{I18n.t('ubiquo.work_hours_month_validation.pdf.date')}: #{"???data firma"}", colspan:2}]
  ]
) do |table|
  table.cell_style = {border_width: 0}
end

headers = [
  [{content: pdf.make_table([
                              [
                                pdf.make_table([ [{content: I18n.t('ubiquo.work_hours_month_validation.pdf.company'), colspan: 2}],
                                                 [I18n.t('ubiquo.work_hours_month_validation.pdf.name_or_company_name'), "??"],
                                                 [I18n.t('ubiquo.work_hours_month_validation.pdf.nif_cif'), "??"],
                                                 [I18n.t('ubiquo.work_hours_month_validation.pdf.ccc'), "??"],
                                               ], width: pdf.bounds.width/2){|table|
                                  table.row(0).font_style = :bold
                                },
                                pdf.make_table([ [{content: I18n.t('ubiquo.work_hours_month_validation.pdf.worker'), colspan: 2}],
                                                 [I18n.t('ubiquo.work_hours_month_validation.pdf.name'), ubiquo_user.full_name],
                                                 [I18n.t('ubiquo.work_hours_month_validation.pdf.nif'), "??"],
                                                 [I18n.t('ubiquo.work_hours_month_validation.pdf.social_security_number'), "??"],
                                               ], width: pdf.bounds.width/2){|table|
                                  table.row(0).font_style = :bold
                                },
                              ],
                              [{content: "#{I18n.t('ubiquo.work_hours_month_validation.pdf.month')}: #{"??"}", colspan: 2}],
                              [{content: signature_table, colspan: 2}],
                            ], width: pdf.bounds.width, cell_style: {:background_color => "F1F1F1"}), colspan: 3}],
  [{content: "", colspan: 3}],
  [I18n.t('ubiquo.work_hours_month_validation.pdf.date'), I18n.t('ubiquo.work_hours_month_validation.pdf.schedule'), I18n.t('ubiquo.work_hours_month_validation.pdf.total_day_hours')]
]


month_hours = 0
table_data = work_hours_ranges.group_by(&:date).map do |date, ranges|
  # (some unimportant code ...)
  [date, hour_ranges, total_hours]
end

footer_data = [[{content: "", colspan: 3}],
               [{content: pdf.make_table([
                [I18n.t('ubiquo.work_hours_month_validation.pdf.total_hours'), month_hours],
                [I18n.t('ubiquo.work_hours_month_validation.pdf.expected_hours'), "??"],
                [I18n.t('ubiquo.work_hours_month_validation.pdf.hour_bag'), "??"],
                [I18n.t('ubiquo.work_hours_month_validation.pdf.hour_bag_spent'), "??"],
                [I18n.t('ubiquo.work_hours_month_validation.pdf.total_balance'), "??"],
              ]){|table|
                 table.width = pdf.bounds.width
                 table.column_widths = {1 => 50}
                 table.cell_style = {:background_color => "F1F1F1"}
                 table.row(-1).font_style = :bold
               }, colspan: 3}]]

pdf.table(title + headers + table_data + footer_data) do |table|

  table.header = 4

  # blank separators:
  table.row(2).border_left_width = 0
  table.row(2).border_right_width = 0
  table.row(-2).border_left_width = 0
  table.row(-2).border_right_width = 0

  # title style
  table.row(0).font_style = :bold
  table.row(0).align = :center

  # column headers style:
  table.row(3).font_style = :bold
  table.row(3).font_style = :bold

  # ---> ---> IMPORTANT CODE HERE <--- < ---
  # table.column_widths = {0 => 50, 2 => 50} # I have also tried this way
  table.column(0).width = 50
  table.column(2).width = 50

end

page_numbering_options = {
  at: [pdf.bounds.right - 150, 0],
  width: 150,
  align: :right,
  start_count_at: 1,
}
pdf.number_pages I18n.t('ubiquo.work_hours_month_validation.pdf.page'), page_numbering_options

pdf.render_file path

You can see the footer table respects the widths I've set, but the main content's columns have equal widths.

image

Thanks in advance!

raquelhortab avatar Apr 18 '23 09:04 raquelhortab

I've seen that by setting exact widths for all columns, it works. I tried this: column_widths = 50and it complained about it being too small. Since the error message said the exact size it needed was 523.28, calculated the widths from that. I set table.column_widths = [50, 423.28, 50] and that worked. I don't get why it does not work by setting only the first and the last column widths.

raquelhortab avatar Apr 18 '23 09:04 raquelhortab

in case someone else finds this, this seems to be the best solution: [50, pdf.bounds.width - 100, 50]

raquelhortab avatar Apr 19 '23 13:04 raquelhortab

I've seen that by setting exact widths for all columns, it works.

Thank you, I can confirm this worked for me too!

For a more flexible pattern, I did this:

    def column_widths
      cols = {
        0 => 25,
        2 => 26,
        3 => 35
      }
      # Calculate width for remaining column due to https://github.com/prawnpdf/prawn-table/issues/152
      cols.merge({
        1 => pdf.bounds.width - cols.values.sum
      })
    end

You can use the hash form to specify the column index.

dacook avatar Jun 02 '23 06:06 dacook

In case it helps anyone I just find out this should be

cell_style = { width: pdf.bounds.width / NUM_OF_COLS }
pdf.table(table, position: :left, cell_style: cell_style)

Use width instead of column_width

cleicar avatar Nov 30 '23 17:11 cleicar