Skip to content

Commit

Permalink
Continue implementing xlsx freeze feature
Browse files Browse the repository at this point in the history
  • Loading branch information
westonganger committed Feb 2, 2020
1 parent 456b165 commit b31a787
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 42 deletions.
2 changes: 1 addition & 1 deletion Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ appraise "caxlsx" do
end

appraise "caxlsx 3.0.0" do
gem "caxlsx", "3.0.0" # Ruby 1.9.3+
gem "caxlsx", "3.0.0" # Legacy Axlsx Support
end

appraise "caxlsx 2.0.2" do
Expand Down
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,24 +196,27 @@ File.open('path/to/file.csv', 'w+b') do |f|
end
```

# Multi Sheet XLSX Spreadsheets
# Multi Sheet Spreadsheets

### XLSX

```ruby
axlsx_package = SpreadsheetArchitect.to_axlsx_package({headers: headers, data: data})
axlsx_package = SpreadsheetArchitect.to_axlsx_package({headers: headers, data: data}, package)

File.open('path/to/file.xlsx', 'w+b') do |f|
File.open('path/to/multi_sheet_file.xlsx', 'w+b') do |f|
f.write axlsx_package.to_stream.read
end
```

See this file for more details: https://github.com/westonganger/spreadsheet_architect/blob/master/test/spreadsheet_architect/multi_sheet_test.rb

### Multi Sheet ODS Spreadsheets
### ODS
```ruby
ods_spreadsheet = SpreadsheetArchitect.to_rodf_spreadsheet({headers: headers, data: data})
ods_spreadsheet = SpreadsheetArchitect.to_rodf_spreadsheet({headers: headers, data: data}, spreadsheet)

File.open('path/to/file.ods', 'w+b') do |f|
File.open('path/to/multi_sheet_file.ods', 'w+b') do |f|
f.write ods_spreadsheet
end
```
Expand All @@ -240,8 +243,8 @@ See this file for more details: https://github.com/westonganger/spreadsheet_arch
|**borders**<br>*Array*||[See this example for usage](https://github.com/westonganger/spreadsheet_architect/blob/master/test/unit/kitchen_sink_test.rb)|
|**column_types**<br>*Array*||Valid types for XLSX are :string, :integer, :float, :date, :time, :boolean, nil = auto determine.|
|**column_widths**<br>*Array*||Sometimes you may want explicit column widths. Use nil if you want a column to autofit again.|
|**freeze_headers**<br>*Boolean*||Make all header rows frozen/fixed so they do not scroll. Requires the Axlsx v3.0.0 which is unrelease, use the master branch in the meantime.|
|**freeze**<br>*String or Hash*|`B2` or `{row: 2, column: 2}`|Make all cells before the specified one frozen/fixed so they do not scroll. Requires the Axlsx v3.0.0 which is unrelease, use the master branch in the meantime.|
|**freeze_headers**<br>*Boolean*||Make all header rows frozen/fixed so they do not scroll.|
|**freeze**<br>* Hash*|`{rows: (1..4), columns: :all}`|Make all specified rows and columns frozen/fixed so they do not scroll.|

## `to_axlsx_spreadsheet(options={}, axlsx_package_to_join=nil)`
Same options as `to_xlsx`
Expand Down
53 changes: 23 additions & 30 deletions lib/spreadsheet_architect/class_methods/xlsx.rb
Original file line number Diff line number Diff line change
Expand Up @@ -196,44 +196,37 @@ def to_axlsx_package(opts={}, package=nil)
end


if options[:freeze]
if options[:freeze].is_a?(String)
freeze_cell = options[:freeze]
else
if !options[:freeze][:row]
options[:freeze][:row] = num_rows-1
end

### TODO
if !options[:freeze][:column]
options[:freeze][:column] = SpreadsheetArchitect::Utils::XLSX::COL_NAMES[max_row_length-1]
elsif options[:freeze][:column].is_a?(String)
options[:freeze][:column] = SpreadsheetArchitect::Utils::XLSX::COL_NAMES.index([options[:freeze][:column])
end

freeze_cell = "#{options[:freeze][:column]}#{options[:freeze][:row]}"
if options[:freeze_headers]
sheet.sheet_view.pane do |pane|
pane.top_left_cell = "A1"
pane.state = :frozen_split
pane.active_pane = :bottom_right
pane.y_split = options[:headers].count
end

elsif options[:freeze]
sheet.sheet_view.pane do |pane|
pane.top_left_cell = freeze_cell
pane.state = :frozen_split
pane.active_pane = :bottom_right

if options[:freeze][:row]
pane.y_split = options[:freeze][:row]
if !options[:freeze][:columns] || options[:freeze][:columns] == :all
freeze_cell = "A"
elsif options[:freeze][:columns].is_a?(Range)
freeze_cell = "#{SpreadsheetArchitect::Utils::XLSX::COL_NAMES[options[:freeze][:columns].first]}"
pane.y_split = options[:freeze][:columns].count
else
freeze_cell = "#{SpreadsheetArchitect::Utils::XLSX::COL_NAMES[options[:freeze][:columns]]}"
pane.y_split = 1
end

if options[:freeze][:column]
### TODO
pane.x_split = options[:freeze][:column]
if options[:freeze][:rows].is_a?(Range)
freeze_cell += "#{options[:freeze][:rows].first}"
pane.x_split = options[:freeze][:rows].count
else
freeze_cell += "#{options[:freeze][:rows]}"
pane.x_split = 1
end
end
elsif options[:freeze_headers]
sheet.sheet_view.pane do |pane|
pane.top_left_cell = "A1"
pane.state = :frozen_split
pane.active_pane = :bottom_right
pane.y_split = options[:headers].count

pane.top_left_cell = freeze_cell
end
end
end
Expand Down
6 changes: 3 additions & 3 deletions lib/spreadsheet_architect/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ def self.get_options(options, klass)
end
end

if options[:freeze].is_a?(Hash) && (!options[:freeze][:row] && !options[:freeze][:column])
raise SpreadsheetArchitect::Exceptions::ArgumentError.new('Must provide a :row or :column key when passing a hash to the :freeze option')
if options[:freeze] && options[:freeze].is_a?(Hash) && !options[:freeze][:rows]
raise SpreadsheetArchitect::Exceptions::ArgumentError.new('Must provide a :rows key when passing a hash to the :freeze option')
end

return options
Expand Down Expand Up @@ -230,7 +230,7 @@ def self.verify_option_types(options)
check_option_type(options, :column_widths, Array)
check_option_type(options, :column_types, Array)
check_option_type(options, :freeze_headers, [TrueClass, FalseClass])
check_option_type(options, :freeze, [String, Hash])
check_option_type(options, :freeze, Hash)
end

def self.stringify_keys(hash={})
Expand Down
4 changes: 2 additions & 2 deletions test/unit/exceptions_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ class ExceptionsTest < ActiveSupport::TestCase
end

assert_raise error do
SpreadsheetArchitect::Utils.get_options({freeze: "A1", freeze_headers: true}, SpreadsheetArchitect)
SpreadsheetArchitect::Utils.get_options({freeze: {rows: 1}, freeze_headers: true}, SpreadsheetArchitect)
end

assert_nothing_raised do
SpreadsheetArchitect.default_options = {freeze_headers: true}
SpreadsheetArchitect::Utils.get_options({freeze: "A1"}, SpreadsheetArchitect)
SpreadsheetArchitect::Utils.get_options({freeze: {rows: 1}}, SpreadsheetArchitect)
end
end

Expand Down
70 changes: 70 additions & 0 deletions test/unit/xlsx_freeze_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
require "test_helper"

class XlsxFreezeTest < ActiveSupport::TestCase

def setup
@options = {
headers: [
['Latest Posts'],
['Title','Category','Author','Posted on','Posted At','Earnings']
],
data: 50.times.map{|i| [i, "foobar-#{i}", 5.4*i, true, Date.today, Time.now]},
}
end

def teardown
end

def test_1
@options.merge!({
freeze: {rows: 1, columns: 1},
})

# Using Array Data
file_data = SpreadsheetArchitect.to_xlsx(@options)

File.open(VERSIONED_BASE_PATH.join("freeze_test_1.xlsx"),'w+b') do |f|
f.write file_data
end
end

def test_2
@options.merge!({
freeze: {rows: (2..4), columns: (2..4)},
})

# Using Array Data
file_data = SpreadsheetArchitect.to_xlsx(@options)

File.open(VERSIONED_BASE_PATH.join("freeze_test_2.xlsx"),'w+b') do |f|
f.write file_data
end
end

def test_ods
@options.merge!({
headers: [
['Latest Posts'],
['Title','Category','Author','Boolean','Posted on','Posted At']
],
data: 50.times.map{|i| [i, "foobar-#{i}", (5.4*i), true, Date.today, Time.now]},
column_types: [
:string,
:float,
:float,
:boolean,
:date,
:time,
nil
],
})

# Using Array Data
file_data = SpreadsheetArchitect.to_ods(@options)

File.open(VERSIONED_BASE_PATH.join("kitchen_sink.ods"),'w+b') do |f|
f.write file_data
end
end

end

0 comments on commit b31a787

Please sign in to comment.