diff --git a/README.md b/README.md index 56f19204..0c223761 100644 --- a/README.md +++ b/README.md @@ -642,6 +642,7 @@ docx.table [['Header 1','Header 2'],['Cell 1', 'Cell 2']] do border_line :single # sets the border style. defaults to :single. see OOXML docs for details. border_size 4 # sets the border width. defaults to 0. units in twips. border_spacing 4 # sets the spacing around the border. defaults to 0. units in twips. + repeat_header 1 # sets the number of header rows that is repeated on each page. defaults to 0. end ``` diff --git a/lib/caracal/core/models/table_model.rb b/lib/caracal/core/models/table_model.rb index 2f41a22e..e4478369 100644 --- a/lib/caracal/core/models/table_model.rb +++ b/lib/caracal/core/models/table_model.rb @@ -21,7 +21,8 @@ class TableModel < BaseModel const_set(:DEFAULT_TABLE_BORDER_COLOR, 'auto') const_set(:DEFAULT_TABLE_BORDER_LINE, :single) const_set(:DEFAULT_TABLE_BORDER_SIZE, 0) # units in 1/8 points - const_set(:DEFAULT_TABLE_BORDER_SPACING, 0) + const_set(:DEFAULT_TABLE_BORDER_SPACING, 0) + const_set(:DEFAULT_TABLE_REPEAT_HEADER, 0) # accessors attr_reader :table_align @@ -36,6 +37,7 @@ class TableModel < BaseModel attr_reader :table_border_right # returns border model attr_reader :table_border_horizontal # returns border model attr_reader :table_border_vertical # returns border model + attr_reader :table_repeat_header # initialization def initialize(options={}, &block) @@ -44,6 +46,7 @@ def initialize(options={}, &block) @table_border_line = DEFAULT_TABLE_BORDER_LINE @table_border_size = DEFAULT_TABLE_BORDER_SIZE @table_border_spacing = DEFAULT_TABLE_BORDER_SPACING + @table_repeat_header = DEFAULT_TABLE_REPEAT_HEADER super options, &block end @@ -121,7 +124,7 @@ def cell_style(models, options={}) #=============== SETTERS ============================== # integers - [:border_size, :border_spacing, :width].each do |m| + [:border_size, :border_spacing, :width, :repeat_header].each do |m| define_method "#{ m }" do |value| instance_variable_set("@table_#{ m }", value.to_i) end @@ -196,6 +199,7 @@ def option_keys k << [:data, :align, :width] k << [:border_color, :border_line, :border_size, :border_spacing] k << [:border_bottom, :border_left, :border_right, :border_top, :border_horizontal, :border_vertical] + k << [:repeat_header] k.flatten end diff --git a/lib/caracal/renderers/document_renderer.rb b/lib/caracal/renderers/document_renderer.rb index b571f40b..8c89728d 100644 --- a/lib/caracal/renderers/document_renderer.rb +++ b/lib/caracal/renderers/document_renderer.rb @@ -349,8 +349,15 @@ def render_table(xml, model) end rowspan_hash = {} - model.rows.each do |row| + model.rows.each_with_index do |row, index| xml['w'].tr do + if model.table_repeat_header > 0 + if index < model.table_repeat_header + xml['w'].trPr do + xml['w'].tblHeader + end + end + end row.each_with_index do |tc, tc_index| xml['w'].tc do xml['w'].tcPr do diff --git a/spec/lib/caracal/core/models/table_model_spec.rb b/spec/lib/caracal/core/models/table_model_spec.rb index b3f30083..63648bfe 100644 --- a/spec/lib/caracal/core/models/table_model_spec.rb +++ b/spec/lib/caracal/core/models/table_model_spec.rb @@ -26,6 +26,7 @@ it { expect(described_class::DEFAULT_TABLE_BORDER_LINE).to eq :single } it { expect(described_class::DEFAULT_TABLE_BORDER_SIZE).to eq 0 } it { expect(described_class::DEFAULT_TABLE_BORDER_SPACING).to eq 0 } + it { expect(described_class::DEFAULT_TABLE_REPEAT_HEADER).to eq 0 } end # accessors @@ -36,6 +37,7 @@ it { expect(subject.table_border_line).to eq :double } it { expect(subject.table_border_size).to eq 8 } it { expect(subject.table_border_spacing).to eq 4 } + it { expect(subject.table_repeat_header).to eq 0 } end end @@ -179,6 +181,13 @@ it { expect(subject.table_width).to eq 7500 } end + # .repeat_header + describe '.repeat_header' do + before { subject.repeat_header(2) } + + it { expect(subject.table_repeat_header).to eq 2 } + end + @@ -212,7 +221,8 @@ let(:expected1) { [:data, :align, :width] } let(:expected2) { [:border_color, :border_line, :border_size, :border_spacing] } let(:expected3) { [:border_top, :border_bottom, :border_left, :border_right, :border_horizontal, :border_vertical] } - let(:expected) { (expected1 + expected2 + expected3).sort } + let(:expected4) { [:repeat_header] } + let(:expected) { (expected1 + expected2 + expected3 + expected4).sort } it { expect(actual).to eq expected } end