From fd8366970d9cb3f5fb431ba6c40a2a2ac2737615 Mon Sep 17 00:00:00 2001 From: Weston Ganger Date: Thu, 29 Sep 2022 20:45:39 -0700 Subject: Merge axlsx_styler gem into caxlsx --- CHANGELOG.md | 12 ++ axlsx.gemspec | 1 + examples/add_border_example.md | 28 +++ examples/append_styles_example.md | 31 +++ lib/axlsx/package.rb | 8 + lib/axlsx/stylesheet/styles.rb | 37 ++++ lib/axlsx/workbook/workbook.rb | 28 +++ lib/axlsx/workbook/worksheet/border_creator.rb | 82 +++++++ lib/axlsx/workbook/worksheet/cell.rb | 31 +++ lib/axlsx/workbook/worksheet/worksheet.rb | 38 ++++ lib/caxlsx.rb | 10 + test/tc_axlsx_styler.rb | 287 +++++++++++++++++++++++++ 12 files changed, 593 insertions(+) create mode 100644 examples/add_border_example.md create mode 100644 examples/append_styles_example.md create mode 100644 lib/axlsx/workbook/worksheet/border_creator.rb create mode 100644 test/tc_axlsx_styler.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 6791d637..fac4015a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,18 @@ CHANGELOG --------- +- **Unreleased - Axlsx Styler** + - [PR #xx](https://github.com/caxlsx/caxlsx/pull/xx)Merge in the gem [`axlsx_styler`](https://github.com/axlsx-styler-gem/axlsx_styler) + - Add ability to both apply or append to existing styles after rows have been created using `worksheet.add_style` + - `worksheet.add_style "A1", {b: true}` + - `worksheet.add_style "A1:B2", {b: true}` + - `worksheet.add_style ["A1", "B2:C7", "D8:E9"], {b: true}` + - Add ability to create borders upon specific areas of the page using `worksheet.add_border` + - `worksheet.add_border "A1", {style: :thin}` + - `worksheet.add_border "A1:B2", {style: :thin}` + - `worksheet.add_border ["A1", "B2:C7", "D8:E9"], {style: :thin}` + - Add `BorderCreator` - TODO: Do we mention this at all? + - **Unreleased** - [PR #155](https://github.com/caxlsx/caxlsx/pull/155) - Add `hideDropDown` alias for `showDropDown` setting, as the latter is confusing to use (because its logic seems inverted). - [PR #143](https://github.com/caxlsx/caxlsx/pull/143) - Add setting `sort_on_headers` for pivot tables diff --git a/axlsx.gemspec b/axlsx.gemspec index 5da4d73f..e9b1f0a9 100644 --- a/axlsx.gemspec +++ b/axlsx.gemspec @@ -18,6 +18,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'rubyzip', '>= 1.3.0', '< 3' s.add_runtime_dependency "htmlentities", "~> 4.3", '>= 4.3.4' s.add_runtime_dependency "marcel", '~> 1.0' + s.add_runtime_dependency "activesupport" ### TODO: replace with local? s.add_development_dependency 'yard', "~> 0.9.8" s.add_development_dependency 'kramdown', '~> 2.3' diff --git a/examples/add_border_example.md b/examples/add_border_example.md new file mode 100644 index 00000000..934cf183 --- /dev/null +++ b/examples/add_border_example.md @@ -0,0 +1,28 @@ +## Description + +Shows how to use `add_border` to add a border to four edges of the selected cell range. + +## Code + +```ruby +p = Axlsx::Package.new +wb = p.workbook + +wb.add_worksheet do |sheet| + sheet.add_row + sheet.add_row ["", "Product", "Category", "Price"] + sheet.add_row ["", "Butter", "Dairy", 4.99] + sheet.add_row ["", "Bread", "Baked Goods", 3.45] + sheet.add_row ["", "Broccoli", "Produce", 2.99] + + sheet.add_border "B2:D5" + sheet.add_border "B3:D3", { edges: [:top], style: :thick } + sheet.add_border ["C3:C4", "D3:D4"] +end + +p.serialize "add_border.xlsx" +``` + +## Output + +![Output](images/add_border.png "Output") diff --git a/examples/append_styles_example.md b/examples/append_styles_example.md new file mode 100644 index 00000000..0dc7792c --- /dev/null +++ b/examples/append_styles_example.md @@ -0,0 +1,31 @@ +## Description + +Shows how to append styles after rows have been created using `worksheet.add_style` + +## Code + +```ruby +p = Axlsx::Package.new +wb = p.workbook + +wb.add_worksheet do |sheet| + sheet.add_row + sheet.add_row ["", "Product", "Category", "Price"] + sheet.add_row ["", "Butter", "Dairy", 4.99] + sheet.add_row ["", "Bread", "Baked Goods", 3.45] + sheet.add_row ["", "Broccoli", "Produce", 2.99] + + sheet.add_style "B2:D2", b: true + sheet.add_style "B2:B5", b: true + sheet.add_style "B2:D2", bg_color: "95AFBA" + sheet.add_style "B3:D5", bg_color: "E2F89C" + sheet.add_style "D3:D5", alignment: { horizontal: :left } + sheet.add_style ["C3:C4", "D3:D4"], fg_color: "00FF00" +nd + +p.serialize "append_styles.xlsx" +``` + +## Output + +![Output](images/append_styles.png "Output") diff --git a/lib/axlsx/package.rb b/lib/axlsx/package.rb index ccabf799..6baaa173 100644 --- a/lib/axlsx/package.rb +++ b/lib/axlsx/package.rb @@ -101,6 +101,10 @@ module Axlsx # s = p.to_stream() # File.open('example_streamed.xlsx', 'wb') { |f| f.write(s.read) } def serialize(output, options = {}, secondary_options = nil) + if !workbook.styles_applied + workbook.apply_styles + end + confirm_valid, zip_command = parse_serialize_options(options, secondary_options) return false unless !confirm_valid || self.validate.empty? zip_provider = if zip_command @@ -122,6 +126,10 @@ module Axlsx # @param [Boolean] confirm_valid Validate the package prior to serialization. # @return [StringIO|Boolean] False if confirm_valid and validation errors exist. rewound string IO if not. def to_stream(confirm_valid=false) + if !workbook.styles_applied + workbook.apply_styles + end + return false unless !confirm_valid || self.validate.empty? Relationship.initialize_ids_cache zip = write_parts(Zip::OutputStream.new(StringIO.new.binmode, true)) diff --git a/lib/axlsx/stylesheet/styles.rb b/lib/axlsx/stylesheet/styles.rb index fd741ac5..3d557a1a 100644 --- a/lib/axlsx/stylesheet/styles.rb +++ b/lib/axlsx/stylesheet/styles.rb @@ -120,6 +120,10 @@ module Axlsx load_default_styles end + def style_index + @style_index ||= {} + end + # Drastically simplifies style creation and management. # @return [Integer] # @option options [String] fg_color The text color @@ -219,7 +223,40 @@ module Axlsx # f = File.open('example_differential_styling', 'wb') # p.serialize(f) # + # + # + # + # An index for cell styles where keys are styles codes as per Axlsx::Style and values are Cell#raw_style + # The reason for the backward key/value ordering is that style lookup must be most efficient, while `add_style` can be less efficient def add_style(options={}) + ### TODO: Refractor this + + if options[:type] == :dxf + style_id = original_add_style(options) + else + # Add styles to style_index cache for re-use + + font_defaults = {name: @fonts.first.name, sz: @fonts.first.sz, family: @fonts.first.family} + + raw_style = {type: :xf}.merge(font_defaults).merge(options) + + if raw_style[:format_code] + raw_style.delete(:num_fmt) + end + + style_id = style_index.key(raw_style) + + if !style_id + style_id = original_add_style(options) + + style_index[style_id] = raw_style + end + end + + return style_id + end + + def original_add_style(options={}) # Default to :xf options[:type] ||= :xf raise ArgumentError, "Type must be one of [:xf, :dxf]" unless [:xf, :dxf].include?(options[:type] ) diff --git a/lib/axlsx/workbook/workbook.rb b/lib/axlsx/workbook/workbook.rb index edf719d1..f9e857fc 100644 --- a/lib/axlsx/workbook/workbook.rb +++ b/lib/axlsx/workbook/workbook.rb @@ -187,6 +187,34 @@ require 'axlsx/workbook/worksheet/selection.rb' @styles end + # An array that holds all cells with styles + attr_accessor :styled_cells + + # Checks if styles are indexed to make it work for pre 0.1.5 version + # users that still explicitly call @workbook.apply_styles + attr_accessor :styles_applied + + # A helper to apply styles that were added using `worksheet.add_style` + # @return [Boolean] + require 'active_support/core_ext/hash/deep_merge' ### TODO: keep or replace with local solution + def apply_styles + return false if !styled_cells + + styled_cells.each do |cell| + current_style = styles.style_index[cell.style] + + if current_style + new_style = current_style.deep_merge(cell.raw_style) + else + new_style = cell.raw_style + end + + cell.style = styles.add_style(new_style) + end + + self.styles_applied = true + end + # Indicates if the epoc date for serialization should be 1904. If false, 1900 is used. @@date1904 = false diff --git a/lib/axlsx/workbook/worksheet/border_creator.rb b/lib/axlsx/workbook/worksheet/border_creator.rb new file mode 100644 index 00000000..a38e78b3 --- /dev/null +++ b/lib/axlsx/workbook/worksheet/border_creator.rb @@ -0,0 +1,82 @@ +# encoding: UTF-8 + +module Axlsx + class BorderCreator + attr_reader :worksheet, :cells, :edges, :width, :color + + def initialize(worksheet, cells, args) + @worksheet = worksheet + @cells = cells + if args.is_a?(Hash) + @edges = args[:edges] || :all + @width = args[:style] || :thin + @color = args[:color] || '000000' + else + @edges = args || :all + @width = :thin + @color = '000000' + end + end + + def draw + selected_edges(edges).each { |edge| add_border(edge, width, color) } + end + + private + + def selected_edges(edges) + all_edges = [:top, :right, :bottom, :left] + if edges == :all + all_edges + elsif edges.is_a?(Array) && edges - all_edges == [] + edges.uniq + else + [] + end + end + + def add_border(position, width, color) + style = { + border: { + style: width, color: color, edges: [position.to_sym] + } + } + worksheet.add_style border_cells[position.to_sym], style + end + + def border_cells + # example range "B2:D5" + { + top: "#{first_cell}:#{last_col}#{first_row}", # "B2:D2" + right: "#{last_col}#{first_row}:#{last_cell}", # "D2:D5" + bottom: "#{first_col}#{last_row}:#{last_cell}", # "B5:D5" + left: "#{first_cell}:#{first_col}#{last_row}" # "B2:B5" + } + end + + def first_cell + @first_cell ||= cells.first.r + end + + def last_cell + @last_cell ||= cells.last.r + end + + def first_row + @first_row ||= first_cell.scan(/\d+/).first + end + + def first_col + @first_col ||= first_cell.scan(/\D+/).first + end + + def last_row + @last_row ||= last_cell.scan(/\d+/).first + end + + def last_col + @last_col ||= last_cell.scan(/\D+/).first + end + + end +end diff --git a/lib/axlsx/workbook/worksheet/cell.rb b/lib/axlsx/workbook/worksheet/cell.rb index 3277b8c5..626cf60f 100644 --- a/lib/axlsx/workbook/worksheet/cell.rb +++ b/lib/axlsx/workbook/worksheet/cell.rb @@ -82,6 +82,37 @@ module Axlsx defined?(@style) ? @style : 0 end + attr_accessor :raw_style + + require 'active_support/core_ext/hash/deep_merge' ### TODO: can/should we remove this dependency + # The index of the cellXfs item to be applied to this cell. + # @param [Hash] styles + # @see Axlsx::Styles + require 'set' ### TODO: move to appropriate place + def add_style(style) + self.raw_style ||= {} + + # using deep_merge from active_support: + # with regular Hash#merge adding borders fails miserably + new_style = raw_style.deep_merge(style) + + all_edges = [:top, :right, :bottom, :left] + + if !raw_style[:border].nil? && !style[:border].nil? + border_at = (raw_style[:border][:edges] || all_edges) + (style[:border][:edges] || all_edges) + new_style[:border][:edges] = border_at.uniq.sort + elsif !style[:border].nil? + new_style[:border] = style[:border] + end + + self.raw_style = new_style + + wb = row.worksheet.workbook + + wb.styled_cells ||= Set.new + wb.styled_cells << self + end + # The row this cell belongs to. # @return [Row] attr_reader :row diff --git a/lib/axlsx/workbook/worksheet/worksheet.rb b/lib/axlsx/workbook/worksheet/worksheet.rb index 921687c8..527d2e71 100644 --- a/lib/axlsx/workbook/worksheet/worksheet.rb +++ b/lib/axlsx/workbook/worksheet/worksheet.rb @@ -1,4 +1,7 @@ # encoding: UTF-8 + +require_relative "border_creator" + module Axlsx # The Worksheet class represents a worksheet in the workbook. @@ -560,6 +563,41 @@ module Axlsx cells.each { |cell| cell.style = style } end + # Set the style for cells in a specific column + # @param [String|Array] cell references + # @param styles TODO: how to specify this + def add_style(cell_refs, *styles) + if !cell_refs.is_a?(Array) + cell_refs = [cell_refs] + end + + cell_refs.each do |cell_ref| + item = self[cell_ref] + + cells = item.is_a?(Array) ? item : [item] + + cells.each do |cell| + styles.each do |style| + cell.add_style(style) + end + end + end + end + + # Set the style for cells in a specific column + # @param [String|Array] cell references + # @param [Hash|Symbol] options TODO: describe this + def add_border(cell_refs, options = :all) ### TODO: will we support the :all argument + if !cell_refs.is_a?(Array) + cell_refs = [cell_refs] + end + + cell_refs.each do |cell_ref| + cells = self[cell_ref] + Axlsx::BorderCreator.new(self, cells, options).draw + end + end + # Returns a sheet node serialization for this sheet in the workbook. def to_sheet_node_xml_string(str='') add_autofilter_defined_name_to_workbook diff --git a/lib/caxlsx.rb b/lib/caxlsx.rb index a82d49fb..1dcc6005 100644 --- a/lib/caxlsx.rb +++ b/lib/caxlsx.rb @@ -1,2 +1,12 @@ # encoding: UTF-8 require 'axlsx.rb' + +begin + require "axlsx_styler" + + if defined?(AxlsxStyler) + raise StandardError.new("Please remove `axlsx_styler` from your Gemfile, the associated functionality is now built-in to `caxlsx` directly.") + end +rescue LoadError + # Do nothing, all good +end diff --git a/test/tc_axlsx_styler.rb b/test/tc_axlsx_styler.rb new file mode 100644 index 00000000..1ce25481 --- /dev/null +++ b/test/tc_axlsx_styler.rb @@ -0,0 +1,287 @@ +# encoding: UTF-8 +require 'tc_helper.rb' + +class TestAxlsxStyler < Test::Unit::TestCase + + def setup + FileUtils.mkdir_p("tmp/") ### TODO: remove + end + + def test_to_stream_automatically_performs_apply_styles + p = Axlsx::Package.new + wb = p.workbook + + filename = 'to_stream_automatically_performs_apply_styles' + assert_nil wb.styles_applied + wb.add_worksheet do |sheet| + sheet.add_row ['A1', 'B1'] + sheet.add_style 'A1:B1', b: true + end + File.open("tmp/#{filename}.xlsx", 'wb') do |f| + f.write p.to_stream.read + end + assert_equal 1, wb.styles.style_index.count + end + + def test_serialize_automatically_performs_apply_styles + p = Axlsx::Package.new + wb = p.workbook + + filename = 'without_apply_styles_serialize' + assert_nil wb.styles_applied + wb.add_worksheet do |sheet| + sheet.add_row ['A1', 'B1'] + sheet.add_style 'A1:B1', b: true + end + p.serialize("tmp/#{filename}.xlsx") + assert_equal true, wb.styles_applied + assert_equal 1, wb.styles.style_index.count + end + + def test_merge_styles_1 + p = Axlsx::Package.new + wb = p.workbook + + filename = 'merge_styles_1' + bold = wb.styles.add_style b: true + + wb.add_worksheet do |sheet| + sheet.add_row + sheet.add_row ['', '1', '2', '3'], style: [nil, bold] + sheet.add_row ['', '4', '5', '6'], style: bold + sheet.add_row ['', '7', '8', '9'] + sheet.add_style 'B2:D4', b: true + sheet.add_border 'B2:D4', { style: :thin, color: '000000' } + end + wb.apply_styles + assert_equal 9, wb.styles.style_index.count + p.serialize("tmp/#{filename}.xlsx") + assert_equal true, wb.styles_applied + end + + def test_merge_styles_2 + p = Axlsx::Package.new + wb = p.workbook + + filename = 'merge_styles_2' + bold = wb.styles.add_style b: true + + wb.add_worksheet do |sheet| + sheet.add_row ['A1', 'B1'], style: [nil, bold] + sheet.add_row ['A2', 'B2'], style: bold + sheet.add_row ['A3', 'B3'] + sheet.add_style 'A1:A2', i: true + end + wb.apply_styles + assert_equal 3, wb.styles.style_index.count + p.serialize("tmp/#{filename}.xlsx") + assert_equal true, wb.styles_applied + end + + def test_merge_styles_3 + p = Axlsx::Package.new + wb = p.workbook + + filename = 'merge_styles_3' + bold = wb.styles.add_style b: true + + wb.add_worksheet do |sheet| + sheet.add_row ['A1', 'B1'], style: [nil, bold] + sheet.add_row ['A2', 'B2'] + sheet.add_style 'B1:B2', bg_color: 'FF0000' + end + wb.apply_styles + assert_equal 3, wb.styles.style_index.count + p.serialize("tmp/#{filename}.xlsx") + assert_equal true, wb.styles_applied + end + + def test_table_with_borders + p = Axlsx::Package.new + wb = p.workbook + + filename = 'borders_test' + wb.add_worksheet do |sheet| + sheet.add_row + sheet.add_row ['', 'Product', 'Category', 'Price'] + sheet.add_row ['', 'Butter', 'Dairy', 4.99] + sheet.add_row ['', 'Bread', 'Baked Goods', 3.45] + sheet.add_row ['', 'Broccoli', 'Produce', 2.99] + sheet.add_row ['', 'Pizza', 'Frozen Foods', 4.99] + sheet.column_widths 5, 20, 20, 20 + + sheet.add_style 'B2:D2', b: true + sheet.add_style 'B2:B6', b: true + sheet.add_style 'B2:D2', bg_color: '95AFBA' + sheet.add_style 'B3:D6', bg_color: 'E2F89C' + sheet.add_style 'D3:D6', alignment: { horizontal: :left } + sheet.add_border 'B2:D6' + sheet.add_border 'B3:D3', [:top] + sheet.add_border 'B3:D3', edges: [:bottom], style: :medium + sheet.add_border 'B3:D3', edges: [:bottom], style: :medium, color: '32f332' + end + p.serialize("tmp/#{filename}.xlsx") + assert_equal true, wb.styles_applied + assert_equal 12, wb.styles.style_index.count + assert_equal 12 + 2, wb.styles.style_index.keys.max + end + + def test_duplicate_borders + p = Axlsx::Package.new + wb = p.workbook + + filename = 'duplicate_borders_test' + wb.add_worksheet do |sheet| + sheet.add_row + sheet.add_row ['', 'B2', 'C2', 'D2'] + sheet.add_row ['', 'B3', 'C3', 'D3'] + sheet.add_row ['', 'B4', 'C4', 'D4'] + + sheet.add_border 'B2:D4' + sheet.add_border 'B2:D4' + end + p.serialize("tmp/#{filename}.xlsx") + assert_equal true, wb.styles_applied + assert_equal 8, wb.styles.style_index.count + assert_equal 8, wb.styled_cells.count + end + + def test_multiple_style_borders_on_same_cells + p = Axlsx::Package.new + wb = p.workbook + + filename = 'multiple_style_borders' + wb.add_worksheet do |sheet| + sheet.add_row + sheet.add_row ['', 'B2', 'C2', 'D2'] + sheet.add_row ['', 'B3', 'C3', 'D3'] + + sheet.add_border 'B2:D3', :all + sheet.add_border 'B2:D2', edges: [:bottom], style: :thick, color: 'ff0000' + end + p.serialize("tmp/#{filename}.xlsx") + assert_equal true, wb.styles_applied + assert_equal 6, wb.styles.style_index.count + assert_equal 6, wb.styled_cells.count + + b2_cell_style = { + border: { + style: :thick, + color: 'ff0000', + edges: [:bottom, :left, :top] + }, + type: :xf, + name: 'Arial', + sz: 11, + family: 1 + } + assert_equal b2_cell_style, wb.styles.style_index.values.find{|x| x == b2_cell_style} + + d3_cell_style = { + border: { + style: :thin, + color: '000000', + edges: [:bottom, :right] + }, + type: :xf, + name: 'Arial', + sz: 11, + family: 1 + } + assert_equal d3_cell_style, wb.styles.style_index.values.find{|x| x == d3_cell_style} + end + + def test_mixed_borders_1 + p = Axlsx::Package.new + wb = p.workbook + + filename = 'mixed_borders_1' + wb.add_worksheet do |sheet| + sheet.add_row + sheet.add_row ['', '1', '2', '3'] + sheet.add_row ['', '4', '5', '6'] + sheet.add_row ['', '7', '8', '9'] + sheet.add_style 'B2:D4', border: { style: :thin, color: '000000' } + sheet.add_border 'C3:D4', style: :medium + end + wb.apply_styles + assert_equal 9, wb.styled_cells.count + assert_equal 2, wb.styles.style_index.count + p.serialize("tmp/#{filename}.xlsx") + assert_equal true, wb.styles_applied + end + + def test_mixed_borders_2 + p = Axlsx::Package.new + wb = p.workbook + + filename = 'mixed_borders_2' + wb.add_worksheet do |sheet| + sheet.add_row + sheet.add_row ['', '1', '2', '3'] + sheet.add_row ['', '4', '5', '6'] + sheet.add_row ['', '7', '8', '9'] + sheet.add_border 'B2:D4', style: :medium + sheet.add_style 'D2:D4', border: { style: :thin, color: '000000' } + end + wb.apply_styles + assert_equal 8, wb.styled_cells.count + assert_equal 6, wb.styles.style_index.count + p.serialize("tmp/#{filename}.xlsx") + assert_equal true, wb.styles_applied + end + + def test_dxf_cell + p = Axlsx::Package.new + wb = p.workbook + + wb.add_worksheet do |sheet| + sheet.add_row (1..2).to_a + sheet.add_style "A1:A1", { bg_color: "AA0000" } + + sheet.add_row (1..2).to_a + sheet.add_style "B1:B1", { bg_color: "CC0000" } + + sheet.add_row (1..2).to_a + sheet.add_style "A3:B3", { bg_color: "00FF00" } + + wb.styles.add_style(bg_color: "0000FF", type: :dxf) + end + + p.serialize("tmp/test_dxf_cell.xlsx") + assert_equal true, wb.styles_applied + + assert_equal 1, wb.styles.dxfs.count + + assert_equal 6, wb.styles.cellXfs.count + end + + def test_default_font_with_style_index + p = Axlsx::Package.new + wb = p.workbook + + wb.styles.fonts[0].name = 'Pontiac' ### TODO, is this a valid font name in all environments + wb.styles.fonts[0].sz = 12 + + wb.add_worksheet do |sheet| + sheet.add_row [1,2,3] + sheet.add_style "A1:C1", { color: "FFFFFF" } + end + + wb.apply_styles + + assert_equal 1, wb.styles.style_index.size + + assert_equal( + { + type: :xf, + name: "Pontiac", + sz: 12, + family: 1, + color: "FFFFFF", + }, + wb.styles.style_index.values.first + ) + end + +end -- cgit v1.2.3 From 8694cab86130b9385231a21994b2f13f4c07924e Mon Sep 17 00:00:00 2001 From: Weston Ganger Date: Sun, 9 Oct 2022 13:50:56 -0700 Subject: Remove active_support dependency from axlsx_styler --- axlsx.gemspec | 1 - lib/axlsx.rb | 13 +++++++++++++ lib/axlsx/workbook/workbook.rb | 16 ++++++++++++++-- lib/axlsx/workbook/worksheet/cell.rb | 5 +---- test/tc_axlsx | 0 test/tc_axlsx.rb | 8 ++++++++ 6 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 test/tc_axlsx diff --git a/axlsx.gemspec b/axlsx.gemspec index e9b1f0a9..5da4d73f 100644 --- a/axlsx.gemspec +++ b/axlsx.gemspec @@ -18,7 +18,6 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'rubyzip', '>= 1.3.0', '< 3' s.add_runtime_dependency "htmlentities", "~> 4.3", '>= 4.3.4' s.add_runtime_dependency "marcel", '~> 1.0' - s.add_runtime_dependency "activesupport" ### TODO: replace with local? s.add_development_dependency 'yard', "~> 0.9.8" s.add_development_dependency 'kramdown', '~> 2.3' diff --git a/lib/axlsx.rb b/lib/axlsx.rb index f2403893..c30fcf26 100644 --- a/lib/axlsx.rb +++ b/lib/axlsx.rb @@ -166,6 +166,19 @@ module Axlsx end end + # utility method for performing a deep merge on a Hash + # @param [Hash] Hash to merge into + # @param [Hash] Hash to be added + def self.hash_deep_merge(first_hash, second_hash) + first_hash.merge(second_hash) do |key, this_val, other_val| + if this_val.is_a?(Hash) && other_val.is_a?(Hash) + Axlsx.hash_deep_merge(this_val, other_val) + else + other_val + end + end + end + # Instructs the serializer to not try to escape cell value input. # This will give you a huge speed bonus, but if you content has <, > or other xml character data # the workbook will be invalid and excel will complain. diff --git a/lib/axlsx/workbook/workbook.rb b/lib/axlsx/workbook/workbook.rb index f9e857fc..417e15a3 100644 --- a/lib/axlsx/workbook/workbook.rb +++ b/lib/axlsx/workbook/workbook.rb @@ -196,7 +196,6 @@ require 'axlsx/workbook/worksheet/selection.rb' # A helper to apply styles that were added using `worksheet.add_style` # @return [Boolean] - require 'active_support/core_ext/hash/deep_merge' ### TODO: keep or replace with local solution def apply_styles return false if !styled_cells @@ -204,7 +203,7 @@ require 'axlsx/workbook/worksheet/selection.rb' current_style = styles.style_index[cell.style] if current_style - new_style = current_style.deep_merge(cell.raw_style) + new_style = Axlsx.hash_deep_merge(current_style, cell.raw_style) else new_style = cell.raw_style end @@ -419,5 +418,18 @@ require 'axlsx/workbook/worksheet/selection.rb' str << '' end + private + + # Utility method for performing a deep merge on a Hash + def hash_deep_merge(first_hash, second_hash) + first_hash.merge(second_hash) do |key, this_val, other_val| + if this_val.is_a?(Hash) && other_val.is_a?(Hash) + this_val.deep_merge(other_val, &block) + else + other_val + end + end + end + end end diff --git a/lib/axlsx/workbook/worksheet/cell.rb b/lib/axlsx/workbook/worksheet/cell.rb index 626cf60f..9ab93e61 100644 --- a/lib/axlsx/workbook/worksheet/cell.rb +++ b/lib/axlsx/workbook/worksheet/cell.rb @@ -84,7 +84,6 @@ module Axlsx attr_accessor :raw_style - require 'active_support/core_ext/hash/deep_merge' ### TODO: can/should we remove this dependency # The index of the cellXfs item to be applied to this cell. # @param [Hash] styles # @see Axlsx::Styles @@ -92,9 +91,7 @@ module Axlsx def add_style(style) self.raw_style ||= {} - # using deep_merge from active_support: - # with regular Hash#merge adding borders fails miserably - new_style = raw_style.deep_merge(style) + new_style = Axlsx.hash_deep_merge(raw_style, style) all_edges = [:top, :right, :bottom, :left] diff --git a/test/tc_axlsx b/test/tc_axlsx new file mode 100644 index 00000000..e69de29b diff --git a/test/tc_axlsx.rb b/test/tc_axlsx.rb index e58ebafe..3903fc42 100644 --- a/test/tc_axlsx.rb +++ b/test/tc_axlsx.rb @@ -132,4 +132,12 @@ class TestAxlsx < Test::Unit::TestCase nil_subject = InstanceValuesSubject.new(nil_obj: nil) assert_equal({"nil_obj" => nil}, Axlsx.instance_values_for(nil_subject), 'should return nil ivars') end + + def test_hash_deep_merge + h1 = {foo: {bar: true}} + h2 = {foo: {baz: true}} + assert_equal({foo: {baz: true}}, h1.merge(h2)) + assert_equal({foo: {bar: true, baz: true}}, Axlsx.hash_deep_merge(h1, h2)) + end + end -- cgit v1.2.3 From 99b25655ef0e5c953007ff81b5bc08058831da8c Mon Sep 17 00:00:00 2001 From: Weston Ganger Date: Sun, 9 Oct 2022 14:14:20 -0700 Subject: Cleanup Stylesheet#add_styles --- lib/axlsx/stylesheet/styles.rb | 43 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/lib/axlsx/stylesheet/styles.rb b/lib/axlsx/stylesheet/styles.rb index 3d557a1a..a84e6df7 100644 --- a/lib/axlsx/stylesheet/styles.rb +++ b/lib/axlsx/stylesheet/styles.rb @@ -223,18 +223,16 @@ module Axlsx # f = File.open('example_differential_styling', 'wb') # p.serialize(f) # - # - # - # # An index for cell styles where keys are styles codes as per Axlsx::Style and values are Cell#raw_style # The reason for the backward key/value ordering is that style lookup must be most efficient, while `add_style` can be less efficient def add_style(options={}) - ### TODO: Refractor this + # Default to :xf + options[:type] ||= :xf - if options[:type] == :dxf - style_id = original_add_style(options) - else - # Add styles to style_index cache for re-use + raise ArgumentError, "Type must be one of [:xf, :dxf]" unless [:xf, :dxf].include?(options[:type] ) + + if options[:type] == :xf + # Check to see if style in cache already font_defaults = {name: @fonts.first.name, sz: @fonts.first.sz, family: @fonts.first.family} @@ -244,23 +242,13 @@ module Axlsx raw_style.delete(:num_fmt) end - style_id = style_index.key(raw_style) - - if !style_id - style_id = original_add_style(options) + xf_index = style_index.key(raw_style) - style_index[style_id] = raw_style + if xf_index + return xf_index end end - return style_id - end - - def original_add_style(options={}) - # Default to :xf - options[:type] ||= :xf - raise ArgumentError, "Type must be one of [:xf, :dxf]" unless [:xf, :dxf].include?(options[:type] ) - fill = parse_fill_options options font = parse_font_options options numFmt = parse_num_fmt_options options @@ -275,7 +263,18 @@ module Axlsx style = Xf.new :fillId=>fill || 0, :fontId=>font || 0, :numFmtId=>numFmt || 0, :borderId=>border || 0, :alignment => alignment, :protection => protection, :applyFill=>!fill.nil?, :applyFont=>!font.nil?, :applyNumberFormat =>!numFmt.nil?, :applyBorder=>!border.nil?, :applyAlignment => !alignment.nil?, :applyProtection => !protection.nil? end - options[:type] == :xf ? cellXfs << style : dxfs << style + if options[:type] == :xf + xf_index = (cellXfs << style) + + # Add styles to style_index cache for re-use + style_index[xf_index] = raw_style + + return xf_index + else + dxf_index = (dxfs << style) + + return dxf_index + end end # parses add_style options for protection styles -- cgit v1.2.3 From 03bad903f474fecccc7dacdc14ef17605d9e2aa2 Mon Sep 17 00:00:00 2001 From: Weston Ganger Date: Sun, 9 Oct 2022 14:40:24 -0700 Subject: Improvements --- lib/axlsx.rb | 11 ++++++++ lib/axlsx/workbook/workbook.rb | 17 +++--------- lib/axlsx/workbook/worksheet/cell.rb | 2 -- lib/caxlsx.rb | 10 ------- test/workbook/worksheet/tc_border_creator.rb | 40 ++++++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 26 deletions(-) create mode 100644 test/workbook/worksheet/tc_border_creator.rb diff --git a/lib/axlsx.rb b/lib/axlsx.rb index c30fcf26..e02256e6 100644 --- a/lib/axlsx.rb +++ b/lib/axlsx.rb @@ -28,8 +28,19 @@ require 'zip' #core dependencies require 'bigdecimal' +require 'set' require 'time' +begin + require "axlsx_styler" + + if defined?(AxlsxStyler) + raise StandardError.new("Please remove `axlsx_styler` from your Gemfile, the associated functionality is now built-in to `caxlsx` directly.") + end +rescue LoadError + # Do nothing, all good +end + # xlsx generation with charts, images, automated column width, customizable styles # and full schema validation. Axlsx excels at helping you generate beautiful # Office Open XML Spreadsheet documents without having to understand the entire diff --git a/lib/axlsx/workbook/workbook.rb b/lib/axlsx/workbook/workbook.rb index 417e15a3..ef56debd 100644 --- a/lib/axlsx/workbook/workbook.rb +++ b/lib/axlsx/workbook/workbook.rb @@ -188,7 +188,9 @@ require 'axlsx/workbook/worksheet/selection.rb' end # An array that holds all cells with styles - attr_accessor :styled_cells + def styled_cells + @styled_cells ||= Set.new + end # Checks if styles are indexed to make it work for pre 0.1.5 version # users that still explicitly call @workbook.apply_styles @@ -418,18 +420,5 @@ require 'axlsx/workbook/worksheet/selection.rb' str << '' end - private - - # Utility method for performing a deep merge on a Hash - def hash_deep_merge(first_hash, second_hash) - first_hash.merge(second_hash) do |key, this_val, other_val| - if this_val.is_a?(Hash) && other_val.is_a?(Hash) - this_val.deep_merge(other_val, &block) - else - other_val - end - end - end - end end diff --git a/lib/axlsx/workbook/worksheet/cell.rb b/lib/axlsx/workbook/worksheet/cell.rb index 9ab93e61..125ca051 100644 --- a/lib/axlsx/workbook/worksheet/cell.rb +++ b/lib/axlsx/workbook/worksheet/cell.rb @@ -87,7 +87,6 @@ module Axlsx # The index of the cellXfs item to be applied to this cell. # @param [Hash] styles # @see Axlsx::Styles - require 'set' ### TODO: move to appropriate place def add_style(style) self.raw_style ||= {} @@ -106,7 +105,6 @@ module Axlsx wb = row.worksheet.workbook - wb.styled_cells ||= Set.new wb.styled_cells << self end diff --git a/lib/caxlsx.rb b/lib/caxlsx.rb index 1dcc6005..a82d49fb 100644 --- a/lib/caxlsx.rb +++ b/lib/caxlsx.rb @@ -1,12 +1,2 @@ # encoding: UTF-8 require 'axlsx.rb' - -begin - require "axlsx_styler" - - if defined?(AxlsxStyler) - raise StandardError.new("Please remove `axlsx_styler` from your Gemfile, the associated functionality is now built-in to `caxlsx` directly.") - end -rescue LoadError - # Do nothing, all good -end diff --git a/test/workbook/worksheet/tc_border_creator.rb b/test/workbook/worksheet/tc_border_creator.rb new file mode 100644 index 00000000..95a85b18 --- /dev/null +++ b/test/workbook/worksheet/tc_border_creator.rb @@ -0,0 +1,40 @@ +require 'tc_helper.rb' + +class TestBorderCreator < Test::Unit::TestCase + def setup + @p = Axlsx::Package.new + @wb = @p.workbook + @ws = @wb.add_worksheet + end + + def test_defaults + 3.times do + @ws.add_row [1,2,3] + end + + bc = Axlsx::BorderCreator.new(@ws, @ws["A1:B2"], {}) + assert_equal bc.instance_variable_get(:@edges), :all + assert_equal bc.instance_variable_get(:@width), :thin + assert_equal bc.instance_variable_get(:@color), "000000" + + bc = Axlsx::BorderCreator.new(@ws, @ws["A1:B2"], [:top]) + assert_equal bc.instance_variable_get(:@edges), [:top] + assert_equal bc.instance_variable_get(:@width), :thin + assert_equal bc.instance_variable_get(:@color), "000000" + + bc = Axlsx::BorderCreator.new(@ws, @ws["A1:B2"], {edges: [:top], style: :thick, color: "ffffff"}) + assert_equal bc.instance_variable_get(:@edges), [:top] + assert_equal bc.instance_variable_get(:@width), :thick + assert_equal bc.instance_variable_get(:@color), "ffffff" + end + + def test_draw + 5.times do + @ws.add_row [1,2,3,4,5] + end + + bc = Axlsx::BorderCreator.new(@ws, @ws["A1:C3"], {}) + bc.draw + # TODO add more expectations + end +end -- cgit v1.2.3 From 56f0977033d87c29fbcb5a20f0bd61d8fe3fb1ec Mon Sep 17 00:00:00 2001 From: Weston Ganger Date: Sun, 9 Oct 2022 14:46:36 -0700 Subject: Cleanup serialize calls from axlsx_styler tests --- test/tc_axlsx_styler.rb | 63 +++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/test/tc_axlsx_styler.rb b/test/tc_axlsx_styler.rb index 1ce25481..e790a458 100644 --- a/test/tc_axlsx_styler.rb +++ b/test/tc_axlsx_styler.rb @@ -3,23 +3,18 @@ require 'tc_helper.rb' class TestAxlsxStyler < Test::Unit::TestCase - def setup - FileUtils.mkdir_p("tmp/") ### TODO: remove - end - def test_to_stream_automatically_performs_apply_styles p = Axlsx::Package.new wb = p.workbook - filename = 'to_stream_automatically_performs_apply_styles' assert_nil wb.styles_applied wb.add_worksheet do |sheet| sheet.add_row ['A1', 'B1'] sheet.add_style 'A1:B1', b: true end - File.open("tmp/#{filename}.xlsx", 'wb') do |f| - f.write p.to_stream.read - end + + p.to_stream + assert_equal 1, wb.styles.style_index.count end @@ -27,22 +22,26 @@ class TestAxlsxStyler < Test::Unit::TestCase p = Axlsx::Package.new wb = p.workbook - filename = 'without_apply_styles_serialize' assert_nil wb.styles_applied wb.add_worksheet do |sheet| sheet.add_row ['A1', 'B1'] sheet.add_style 'A1:B1', b: true end - p.serialize("tmp/#{filename}.xlsx") + + @fname = 'axlsx_test_serialization.xlsx' + + p.serialize(@fname) + assert_equal true, wb.styles_applied assert_equal 1, wb.styles.style_index.count + + File.delete(@fname) end def test_merge_styles_1 p = Axlsx::Package.new wb = p.workbook - filename = 'merge_styles_1' bold = wb.styles.add_style b: true wb.add_worksheet do |sheet| @@ -53,17 +52,16 @@ class TestAxlsxStyler < Test::Unit::TestCase sheet.add_style 'B2:D4', b: true sheet.add_border 'B2:D4', { style: :thin, color: '000000' } end + wb.apply_styles + assert_equal 9, wb.styles.style_index.count - p.serialize("tmp/#{filename}.xlsx") - assert_equal true, wb.styles_applied end def test_merge_styles_2 p = Axlsx::Package.new wb = p.workbook - filename = 'merge_styles_2' bold = wb.styles.add_style b: true wb.add_worksheet do |sheet| @@ -72,17 +70,16 @@ class TestAxlsxStyler < Test::Unit::TestCase sheet.add_row ['A3', 'B3'] sheet.add_style 'A1:A2', i: true end + wb.apply_styles + assert_equal 3, wb.styles.style_index.count - p.serialize("tmp/#{filename}.xlsx") - assert_equal true, wb.styles_applied end def test_merge_styles_3 p = Axlsx::Package.new wb = p.workbook - filename = 'merge_styles_3' bold = wb.styles.add_style b: true wb.add_worksheet do |sheet| @@ -90,17 +87,16 @@ class TestAxlsxStyler < Test::Unit::TestCase sheet.add_row ['A2', 'B2'] sheet.add_style 'B1:B2', bg_color: 'FF0000' end + wb.apply_styles + assert_equal 3, wb.styles.style_index.count - p.serialize("tmp/#{filename}.xlsx") - assert_equal true, wb.styles_applied end def test_table_with_borders p = Axlsx::Package.new wb = p.workbook - filename = 'borders_test' wb.add_worksheet do |sheet| sheet.add_row sheet.add_row ['', 'Product', 'Category', 'Price'] @@ -120,7 +116,9 @@ class TestAxlsxStyler < Test::Unit::TestCase sheet.add_border 'B3:D3', edges: [:bottom], style: :medium sheet.add_border 'B3:D3', edges: [:bottom], style: :medium, color: '32f332' end - p.serialize("tmp/#{filename}.xlsx") + + wb.apply_styles + assert_equal true, wb.styles_applied assert_equal 12, wb.styles.style_index.count assert_equal 12 + 2, wb.styles.style_index.keys.max @@ -130,7 +128,6 @@ class TestAxlsxStyler < Test::Unit::TestCase p = Axlsx::Package.new wb = p.workbook - filename = 'duplicate_borders_test' wb.add_worksheet do |sheet| sheet.add_row sheet.add_row ['', 'B2', 'C2', 'D2'] @@ -140,7 +137,9 @@ class TestAxlsxStyler < Test::Unit::TestCase sheet.add_border 'B2:D4' sheet.add_border 'B2:D4' end - p.serialize("tmp/#{filename}.xlsx") + + wb.apply_styles + assert_equal true, wb.styles_applied assert_equal 8, wb.styles.style_index.count assert_equal 8, wb.styled_cells.count @@ -150,7 +149,6 @@ class TestAxlsxStyler < Test::Unit::TestCase p = Axlsx::Package.new wb = p.workbook - filename = 'multiple_style_borders' wb.add_worksheet do |sheet| sheet.add_row sheet.add_row ['', 'B2', 'C2', 'D2'] @@ -159,7 +157,9 @@ class TestAxlsxStyler < Test::Unit::TestCase sheet.add_border 'B2:D3', :all sheet.add_border 'B2:D2', edges: [:bottom], style: :thick, color: 'ff0000' end - p.serialize("tmp/#{filename}.xlsx") + + wb.apply_styles + assert_equal true, wb.styles_applied assert_equal 6, wb.styles.style_index.count assert_equal 6, wb.styled_cells.count @@ -195,7 +195,6 @@ class TestAxlsxStyler < Test::Unit::TestCase p = Axlsx::Package.new wb = p.workbook - filename = 'mixed_borders_1' wb.add_worksheet do |sheet| sheet.add_row sheet.add_row ['', '1', '2', '3'] @@ -204,18 +203,17 @@ class TestAxlsxStyler < Test::Unit::TestCase sheet.add_style 'B2:D4', border: { style: :thin, color: '000000' } sheet.add_border 'C3:D4', style: :medium end + wb.apply_styles + assert_equal 9, wb.styled_cells.count assert_equal 2, wb.styles.style_index.count - p.serialize("tmp/#{filename}.xlsx") - assert_equal true, wb.styles_applied end def test_mixed_borders_2 p = Axlsx::Package.new wb = p.workbook - filename = 'mixed_borders_2' wb.add_worksheet do |sheet| sheet.add_row sheet.add_row ['', '1', '2', '3'] @@ -224,11 +222,11 @@ class TestAxlsxStyler < Test::Unit::TestCase sheet.add_border 'B2:D4', style: :medium sheet.add_style 'D2:D4', border: { style: :thin, color: '000000' } end + wb.apply_styles + assert_equal 8, wb.styled_cells.count assert_equal 6, wb.styles.style_index.count - p.serialize("tmp/#{filename}.xlsx") - assert_equal true, wb.styles_applied end def test_dxf_cell @@ -248,8 +246,7 @@ class TestAxlsxStyler < Test::Unit::TestCase wb.styles.add_style(bg_color: "0000FF", type: :dxf) end - p.serialize("tmp/test_dxf_cell.xlsx") - assert_equal true, wb.styles_applied + wb.apply_styles assert_equal 1, wb.styles.dxfs.count -- cgit v1.2.3 From 28d59a1dba55a9d98ceed26ac3bed6267cf18481 Mon Sep 17 00:00:00 2001 From: Weston Ganger Date: Wed, 12 Oct 2022 23:02:49 -0700 Subject: Resolve all TODOs --- CHANGELOG.md | 3 +- lib/axlsx/stylesheet/styles.rb | 4 + lib/axlsx/workbook/workbook.rb | 5 +- lib/axlsx/workbook/worksheet/border_creator.rb | 50 ++--- lib/axlsx/workbook/worksheet/worksheet.rb | 6 +- test/tc_axlsx | 0 test/tc_axlsx_styler.rb | 284 ------------------------- test/tc_package.rb | 35 +++ test/workbook/worksheet/tc_border_creator.rb | 43 +++- test/workbook/worksheet/tc_worksheet.rb | 244 +++++++++++++++++++++ 10 files changed, 351 insertions(+), 323 deletions(-) delete mode 100644 test/tc_axlsx delete mode 100644 test/tc_axlsx_styler.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index fac4015a..95bb0781 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,8 @@ CHANGELOG - `worksheet.add_border "A1", {style: :thin}` - `worksheet.add_border "A1:B2", {style: :thin}` - `worksheet.add_border ["A1", "B2:C7", "D8:E9"], {style: :thin}` - - Add `BorderCreator` - TODO: Do we mention this at all? + - Add `Axlsx::BorderCreator` the class used under the hood for `worksheet.add_border` + - Allow specifying `:all` in `border: {edges: :all}` which is a shortcut for `border: {edges: [:left, :right, :top, :bottom]}` - **Unreleased** - [PR #155](https://github.com/caxlsx/caxlsx/pull/155) - Add `hideDropDown` alias for `showDropDown` setting, as the latter is confusing to use (because its logic seems inverted). diff --git a/lib/axlsx/stylesheet/styles.rb b/lib/axlsx/stylesheet/styles.rb index a84e6df7..1ddbb788 100644 --- a/lib/axlsx/stylesheet/styles.rb +++ b/lib/axlsx/stylesheet/styles.rb @@ -231,6 +231,10 @@ module Axlsx raise ArgumentError, "Type must be one of [:xf, :dxf]" unless [:xf, :dxf].include?(options[:type] ) + if options[:border].is_a?(Hash) && options[:border][:edges] == :all + options[:border][:edges] = Axlsx::Border::EDGES + end + if options[:type] == :xf # Check to see if style in cache already diff --git a/lib/axlsx/workbook/workbook.rb b/lib/axlsx/workbook/workbook.rb index ef56debd..938d4aee 100644 --- a/lib/axlsx/workbook/workbook.rb +++ b/lib/axlsx/workbook/workbook.rb @@ -188,12 +188,13 @@ require 'axlsx/workbook/worksheet/selection.rb' end # An array that holds all cells with styles + # @return Set def styled_cells @styled_cells ||= Set.new end - # Checks if styles are indexed to make it work for pre 0.1.5 version - # users that still explicitly call @workbook.apply_styles + # Are the styles added with workbook.add_styles applied yet + # @return Boolean attr_accessor :styles_applied # A helper to apply styles that were added using `worksheet.add_style` diff --git a/lib/axlsx/workbook/worksheet/border_creator.rb b/lib/axlsx/workbook/worksheet/border_creator.rb index a38e78b3..a4146ee1 100644 --- a/lib/axlsx/workbook/worksheet/border_creator.rb +++ b/lib/axlsx/workbook/worksheet/border_creator.rb @@ -8,49 +8,43 @@ module Axlsx @worksheet = worksheet @cells = cells if args.is_a?(Hash) - @edges = args[:edges] || :all + @edges = args[:edges] || Axlsx::Border::EDGES @width = args[:style] || :thin @color = args[:color] || '000000' else - @edges = args || :all + @edges = args || Axlsx::Border::Edges @width = :thin @color = '000000' end - end - - def draw - selected_edges(edges).each { |edge| add_border(edge, width, color) } - end - - private - def selected_edges(edges) - all_edges = [:top, :right, :bottom, :left] - if edges == :all - all_edges - elsif edges.is_a?(Array) && edges - all_edges == [] - edges.uniq + if @edges == :all + @edges = Axlsx::Border::EDGES + elsif @edges.is_a?(Array) + @edges = (@edges.map(&:to_sym).uniq & Axlsx::Border::EDGES) else - [] + @edges = [] end end - def add_border(position, width, color) - style = { - border: { - style: width, color: color, edges: [position.to_sym] - } - } - worksheet.add_style border_cells[position.to_sym], style + def draw + @edges.each do |edge| + worksheet.add_style( + border_cells[edge], + { + border: {style: @width, color: @color, edges: [edge]} + } + ) + end end + private + def border_cells - # example range "B2:D5" { - top: "#{first_cell}:#{last_col}#{first_row}", # "B2:D2" - right: "#{last_col}#{first_row}:#{last_cell}", # "D2:D5" - bottom: "#{first_col}#{last_row}:#{last_cell}", # "B5:D5" - left: "#{first_cell}:#{first_col}#{last_row}" # "B2:B5" + top: "#{first_cell}:#{last_col}#{first_row}", + right: "#{last_col}#{first_row}:#{last_cell}", + bottom: "#{first_col}#{last_row}:#{last_cell}", + left: "#{first_cell}:#{first_col}#{last_row}", } end diff --git a/lib/axlsx/workbook/worksheet/worksheet.rb b/lib/axlsx/workbook/worksheet/worksheet.rb index 527d2e71..a240e8e9 100644 --- a/lib/axlsx/workbook/worksheet/worksheet.rb +++ b/lib/axlsx/workbook/worksheet/worksheet.rb @@ -565,7 +565,7 @@ module Axlsx # Set the style for cells in a specific column # @param [String|Array] cell references - # @param styles TODO: how to specify this + # @param [Hash] styles def add_style(cell_refs, *styles) if !cell_refs.is_a?(Array) cell_refs = [cell_refs] @@ -586,8 +586,8 @@ module Axlsx # Set the style for cells in a specific column # @param [String|Array] cell references - # @param [Hash|Symbol] options TODO: describe this - def add_border(cell_refs, options = :all) ### TODO: will we support the :all argument + # @param [Hash|Array|Symbol] border options + def add_border(cell_refs, options = Axlsx::Border::EDGES) if !cell_refs.is_a?(Array) cell_refs = [cell_refs] end diff --git a/test/tc_axlsx b/test/tc_axlsx deleted file mode 100644 index e69de29b..00000000 diff --git a/test/tc_axlsx_styler.rb b/test/tc_axlsx_styler.rb deleted file mode 100644 index e790a458..00000000 --- a/test/tc_axlsx_styler.rb +++ /dev/null @@ -1,284 +0,0 @@ -# encoding: UTF-8 -require 'tc_helper.rb' - -class TestAxlsxStyler < Test::Unit::TestCase - - def test_to_stream_automatically_performs_apply_styles - p = Axlsx::Package.new - wb = p.workbook - - assert_nil wb.styles_applied - wb.add_worksheet do |sheet| - sheet.add_row ['A1', 'B1'] - sheet.add_style 'A1:B1', b: true - end - - p.to_stream - - assert_equal 1, wb.styles.style_index.count - end - - def test_serialize_automatically_performs_apply_styles - p = Axlsx::Package.new - wb = p.workbook - - assert_nil wb.styles_applied - wb.add_worksheet do |sheet| - sheet.add_row ['A1', 'B1'] - sheet.add_style 'A1:B1', b: true - end - - @fname = 'axlsx_test_serialization.xlsx' - - p.serialize(@fname) - - assert_equal true, wb.styles_applied - assert_equal 1, wb.styles.style_index.count - - File.delete(@fname) - end - - def test_merge_styles_1 - p = Axlsx::Package.new - wb = p.workbook - - bold = wb.styles.add_style b: true - - wb.add_worksheet do |sheet| - sheet.add_row - sheet.add_row ['', '1', '2', '3'], style: [nil, bold] - sheet.add_row ['', '4', '5', '6'], style: bold - sheet.add_row ['', '7', '8', '9'] - sheet.add_style 'B2:D4', b: true - sheet.add_border 'B2:D4', { style: :thin, color: '000000' } - end - - wb.apply_styles - - assert_equal 9, wb.styles.style_index.count - end - - def test_merge_styles_2 - p = Axlsx::Package.new - wb = p.workbook - - bold = wb.styles.add_style b: true - - wb.add_worksheet do |sheet| - sheet.add_row ['A1', 'B1'], style: [nil, bold] - sheet.add_row ['A2', 'B2'], style: bold - sheet.add_row ['A3', 'B3'] - sheet.add_style 'A1:A2', i: true - end - - wb.apply_styles - - assert_equal 3, wb.styles.style_index.count - end - - def test_merge_styles_3 - p = Axlsx::Package.new - wb = p.workbook - - bold = wb.styles.add_style b: true - - wb.add_worksheet do |sheet| - sheet.add_row ['A1', 'B1'], style: [nil, bold] - sheet.add_row ['A2', 'B2'] - sheet.add_style 'B1:B2', bg_color: 'FF0000' - end - - wb.apply_styles - - assert_equal 3, wb.styles.style_index.count - end - - def test_table_with_borders - p = Axlsx::Package.new - wb = p.workbook - - wb.add_worksheet do |sheet| - sheet.add_row - sheet.add_row ['', 'Product', 'Category', 'Price'] - sheet.add_row ['', 'Butter', 'Dairy', 4.99] - sheet.add_row ['', 'Bread', 'Baked Goods', 3.45] - sheet.add_row ['', 'Broccoli', 'Produce', 2.99] - sheet.add_row ['', 'Pizza', 'Frozen Foods', 4.99] - sheet.column_widths 5, 20, 20, 20 - - sheet.add_style 'B2:D2', b: true - sheet.add_style 'B2:B6', b: true - sheet.add_style 'B2:D2', bg_color: '95AFBA' - sheet.add_style 'B3:D6', bg_color: 'E2F89C' - sheet.add_style 'D3:D6', alignment: { horizontal: :left } - sheet.add_border 'B2:D6' - sheet.add_border 'B3:D3', [:top] - sheet.add_border 'B3:D3', edges: [:bottom], style: :medium - sheet.add_border 'B3:D3', edges: [:bottom], style: :medium, color: '32f332' - end - - wb.apply_styles - - assert_equal true, wb.styles_applied - assert_equal 12, wb.styles.style_index.count - assert_equal 12 + 2, wb.styles.style_index.keys.max - end - - def test_duplicate_borders - p = Axlsx::Package.new - wb = p.workbook - - wb.add_worksheet do |sheet| - sheet.add_row - sheet.add_row ['', 'B2', 'C2', 'D2'] - sheet.add_row ['', 'B3', 'C3', 'D3'] - sheet.add_row ['', 'B4', 'C4', 'D4'] - - sheet.add_border 'B2:D4' - sheet.add_border 'B2:D4' - end - - wb.apply_styles - - assert_equal true, wb.styles_applied - assert_equal 8, wb.styles.style_index.count - assert_equal 8, wb.styled_cells.count - end - - def test_multiple_style_borders_on_same_cells - p = Axlsx::Package.new - wb = p.workbook - - wb.add_worksheet do |sheet| - sheet.add_row - sheet.add_row ['', 'B2', 'C2', 'D2'] - sheet.add_row ['', 'B3', 'C3', 'D3'] - - sheet.add_border 'B2:D3', :all - sheet.add_border 'B2:D2', edges: [:bottom], style: :thick, color: 'ff0000' - end - - wb.apply_styles - - assert_equal true, wb.styles_applied - assert_equal 6, wb.styles.style_index.count - assert_equal 6, wb.styled_cells.count - - b2_cell_style = { - border: { - style: :thick, - color: 'ff0000', - edges: [:bottom, :left, :top] - }, - type: :xf, - name: 'Arial', - sz: 11, - family: 1 - } - assert_equal b2_cell_style, wb.styles.style_index.values.find{|x| x == b2_cell_style} - - d3_cell_style = { - border: { - style: :thin, - color: '000000', - edges: [:bottom, :right] - }, - type: :xf, - name: 'Arial', - sz: 11, - family: 1 - } - assert_equal d3_cell_style, wb.styles.style_index.values.find{|x| x == d3_cell_style} - end - - def test_mixed_borders_1 - p = Axlsx::Package.new - wb = p.workbook - - wb.add_worksheet do |sheet| - sheet.add_row - sheet.add_row ['', '1', '2', '3'] - sheet.add_row ['', '4', '5', '6'] - sheet.add_row ['', '7', '8', '9'] - sheet.add_style 'B2:D4', border: { style: :thin, color: '000000' } - sheet.add_border 'C3:D4', style: :medium - end - - wb.apply_styles - - assert_equal 9, wb.styled_cells.count - assert_equal 2, wb.styles.style_index.count - end - - def test_mixed_borders_2 - p = Axlsx::Package.new - wb = p.workbook - - wb.add_worksheet do |sheet| - sheet.add_row - sheet.add_row ['', '1', '2', '3'] - sheet.add_row ['', '4', '5', '6'] - sheet.add_row ['', '7', '8', '9'] - sheet.add_border 'B2:D4', style: :medium - sheet.add_style 'D2:D4', border: { style: :thin, color: '000000' } - end - - wb.apply_styles - - assert_equal 8, wb.styled_cells.count - assert_equal 6, wb.styles.style_index.count - end - - def test_dxf_cell - p = Axlsx::Package.new - wb = p.workbook - - wb.add_worksheet do |sheet| - sheet.add_row (1..2).to_a - sheet.add_style "A1:A1", { bg_color: "AA0000" } - - sheet.add_row (1..2).to_a - sheet.add_style "B1:B1", { bg_color: "CC0000" } - - sheet.add_row (1..2).to_a - sheet.add_style "A3:B3", { bg_color: "00FF00" } - - wb.styles.add_style(bg_color: "0000FF", type: :dxf) - end - - wb.apply_styles - - assert_equal 1, wb.styles.dxfs.count - - assert_equal 6, wb.styles.cellXfs.count - end - - def test_default_font_with_style_index - p = Axlsx::Package.new - wb = p.workbook - - wb.styles.fonts[0].name = 'Pontiac' ### TODO, is this a valid font name in all environments - wb.styles.fonts[0].sz = 12 - - wb.add_worksheet do |sheet| - sheet.add_row [1,2,3] - sheet.add_style "A1:C1", { color: "FFFFFF" } - end - - wb.apply_styles - - assert_equal 1, wb.styles.style_index.size - - assert_equal( - { - type: :xf, - name: "Pontiac", - sz: 12, - family: 1, - color: "FFFFFF", - }, - wb.styles.style_index.values.first - ) - end - -end diff --git a/test/tc_package.rb b/test/tc_package.rb index 79fe20f5..0788d029 100644 --- a/test/tc_package.rb +++ b/test/tc_package.rb @@ -157,6 +157,26 @@ class TestPackage < Test::Unit::TestCase end end + def test_serialize_automatically_performs_apply_styles + p = Axlsx::Package.new + wb = p.workbook + + assert_nil wb.styles_applied + wb.add_worksheet do |sheet| + sheet.add_row ['A1', 'B1'] + sheet.add_style 'A1:B1', b: true + end + + @fname = 'axlsx_test_serialization.xlsx' + + p.serialize(@fname) + + assert_equal true, wb.styles_applied + assert_equal 1, wb.styles.style_index.count + + File.delete(@fname) + end + def assert_zip_file_matches_package(fname, package) zf = Zip::File.open(fname) package.send(:parts).each{ |part| zf.get_entry(part[:entry]) } @@ -305,6 +325,21 @@ class TestPackage < Test::Unit::TestCase assert(Axlsx::Relationship.ids_cache.empty?) end + def test_to_stream_automatically_performs_apply_styles + p = Axlsx::Package.new + wb = p.workbook + + assert_nil wb.styles_applied + wb.add_worksheet do |sheet| + sheet.add_row ['A1', 'B1'] + sheet.add_style 'A1:B1', b: true + end + + p.to_stream + + assert_equal 1, wb.styles.style_index.count + end + def test_encrypt # this is no where near close to ready yet assert(@package.encrypt('your_mom.xlsxl', 'has a password') == false) diff --git a/test/workbook/worksheet/tc_border_creator.rb b/test/workbook/worksheet/tc_border_creator.rb index 95a85b18..86b47fc1 100644 --- a/test/workbook/worksheet/tc_border_creator.rb +++ b/test/workbook/worksheet/tc_border_creator.rb @@ -13,16 +13,26 @@ class TestBorderCreator < Test::Unit::TestCase end bc = Axlsx::BorderCreator.new(@ws, @ws["A1:B2"], {}) - assert_equal bc.instance_variable_get(:@edges), :all + assert_equal bc.instance_variable_get(:@edges), Axlsx::Border::EDGES assert_equal bc.instance_variable_get(:@width), :thin assert_equal bc.instance_variable_get(:@color), "000000" - bc = Axlsx::BorderCreator.new(@ws, @ws["A1:B2"], [:top]) + bc = Axlsx::BorderCreator.new(@ws, @ws["A1:B2"], ["top"]) assert_equal bc.instance_variable_get(:@edges), [:top] assert_equal bc.instance_variable_get(:@width), :thin assert_equal bc.instance_variable_get(:@color), "000000" - bc = Axlsx::BorderCreator.new(@ws, @ws["A1:B2"], {edges: [:top], style: :thick, color: "ffffff"}) + bc = Axlsx::BorderCreator.new(@ws, @ws["A1:B2"], :all) + assert_equal bc.instance_variable_get(:@edges), Axlsx::Border::EDGES + assert_equal bc.instance_variable_get(:@width), :thin + assert_equal bc.instance_variable_get(:@color), "000000" + + bc = Axlsx::BorderCreator.new(@ws, @ws["A1:B2"], [:foo]) + assert_equal bc.instance_variable_get(:@edges), [] + assert_equal bc.instance_variable_get(:@width), :thin + assert_equal bc.instance_variable_get(:@color), "000000" + + bc = Axlsx::BorderCreator.new(@ws, @ws["A1:B2"], {edges: ["top"], style: :thick, color: "ffffff"}) assert_equal bc.instance_variable_get(:@edges), [:top] assert_equal bc.instance_variable_get(:@width), :thick assert_equal bc.instance_variable_get(:@color), "ffffff" @@ -33,8 +43,31 @@ class TestBorderCreator < Test::Unit::TestCase @ws.add_row [1,2,3,4,5] end - bc = Axlsx::BorderCreator.new(@ws, @ws["A1:C3"], {}) + bc = Axlsx::BorderCreator.new(@ws, @ws["A1:C3"], {edges: ["top", :left], style: :thick, color: "ffffff"}) + bc.draw - # TODO add more expectations + + assert_equal 2, @ws.styles.borders.size + + @wb.apply_styles + + assert_equal 5, @ws.styles.borders.size + + assert_equal 2, @ws.styles.borders[2].prs.size + assert_equal ["FFFFFFFF"], @ws.styles.borders[2].prs.map(&:color).map(&:rgb).uniq + assert_equal [:thick], @ws.styles.borders[2].prs.map(&:style).uniq + assert_equal [:left, :top], @ws.styles.borders[2].prs.map(&:name) + + + assert_equal 1, @ws.styles.borders[3].prs.size + assert_equal ["FFFFFFFF"], @ws.styles.borders[3].prs.map(&:color).map(&:rgb).uniq + assert_equal [:thick], @ws.styles.borders[3].prs.map(&:style).uniq + assert_equal [:top], @ws.styles.borders[3].prs.map(&:name) + + assert_equal 1, @ws.styles.borders[4].prs.size + assert_equal ["FFFFFFFF"], @ws.styles.borders[4].prs.map(&:color).map(&:rgb).uniq + assert_equal [:thick], @ws.styles.borders[4].prs.map(&:style).uniq + assert_equal [:left], @ws.styles.borders[4].prs.map(&:name) end + end diff --git a/test/workbook/worksheet/tc_worksheet.rb b/test/workbook/worksheet/tc_worksheet.rb index c679e18c..6dbea530 100644 --- a/test/workbook/worksheet/tc_worksheet.rb +++ b/test/workbook/worksheet/tc_worksheet.rb @@ -629,4 +629,248 @@ class TestWorksheet < Test::Unit::TestCase assert_equal(doc.xpath('//xmlns:worksheet/xmlns:sheetPr/xmlns:outlinePr').size, 1) assert_equal(doc.xpath('//xmlns:worksheet/xmlns:sheetPr/xmlns:outlinePr[@summaryBelow=0][@summaryRight=1]').size, 1) end + + def test_merge_styles_1 + p = Axlsx::Package.new + wb = p.workbook + + bold = wb.styles.add_style b: true + + wb.add_worksheet do |sheet| + sheet.add_row + sheet.add_row ['', '1', '2', '3'], style: [nil, bold] + sheet.add_row ['', '4', '5', '6'], style: bold + sheet.add_row ['', '7', '8', '9'] + sheet.add_style 'B2:D4', b: true + sheet.add_border 'B2:D4', { style: :thin, color: '000000' } + end + + wb.apply_styles + + assert_equal 9, wb.styles.style_index.count + end + + def test_merge_styles_2 + p = Axlsx::Package.new + wb = p.workbook + + bold = wb.styles.add_style b: true + + wb.add_worksheet do |sheet| + sheet.add_row ['A1', 'B1'], style: [nil, bold] + sheet.add_row ['A2', 'B2'], style: bold + sheet.add_row ['A3', 'B3'] + sheet.add_style 'A1:A2', i: true + end + + wb.apply_styles + + assert_equal 3, wb.styles.style_index.count + end + + def test_merge_styles_3 + p = Axlsx::Package.new + wb = p.workbook + + bold = wb.styles.add_style b: true + + wb.add_worksheet do |sheet| + sheet.add_row ['A1', 'B1'], style: [nil, bold] + sheet.add_row ['A2', 'B2'] + sheet.add_style 'B1:B2', bg_color: 'FF0000' + end + + wb.apply_styles + + assert_equal 3, wb.styles.style_index.count + end + + def test_table_with_borders + p = Axlsx::Package.new + wb = p.workbook + + wb.add_worksheet do |sheet| + sheet.add_row + sheet.add_row ['', 'Product', 'Category', 'Price'] + sheet.add_row ['', 'Butter', 'Dairy', 4.99] + sheet.add_row ['', 'Bread', 'Baked Goods', 3.45] + sheet.add_row ['', 'Broccoli', 'Produce', 2.99] + sheet.add_row ['', 'Pizza', 'Frozen Foods', 4.99] + sheet.column_widths 5, 20, 20, 20 + + sheet.add_style 'B2:D2', b: true + sheet.add_style 'B2:B6', b: true + sheet.add_style 'B2:D2', bg_color: '95AFBA' + sheet.add_style 'B3:D6', bg_color: 'E2F89C' + sheet.add_style 'D3:D6', alignment: { horizontal: :left } + sheet.add_border 'B2:D6' + sheet.add_border 'B3:D3', [:top] + sheet.add_border 'B3:D3', edges: [:bottom], style: :medium + sheet.add_border 'B3:D3', edges: [:bottom], style: :medium, color: '32f332' + end + + wb.apply_styles + + assert_equal true, wb.styles_applied + assert_equal 12, wb.styles.style_index.count + assert_equal 12 + 2, wb.styles.style_index.keys.max + end + + def test_duplicate_borders + p = Axlsx::Package.new + wb = p.workbook + + wb.add_worksheet do |sheet| + sheet.add_row + sheet.add_row ['', 'B2', 'C2', 'D2'] + sheet.add_row ['', 'B3', 'C3', 'D3'] + sheet.add_row ['', 'B4', 'C4', 'D4'] + + sheet.add_border 'B2:D4' + sheet.add_border 'B2:D4' + end + + wb.apply_styles + + assert_equal true, wb.styles_applied + assert_equal 8, wb.styles.style_index.count + assert_equal 8, wb.styled_cells.count + end + + def test_multiple_style_borders_on_same_cells + p = Axlsx::Package.new + wb = p.workbook + + wb.add_worksheet do |sheet| + sheet.add_row + sheet.add_row ['', 'B2', 'C2', 'D2'] + sheet.add_row ['', 'B3', 'C3', 'D3'] + + sheet.add_border 'B2:D3', :all + sheet.add_border 'B2:D2', edges: [:bottom], style: :thick, color: 'ff0000' + end + + wb.apply_styles + + assert_equal true, wb.styles_applied + assert_equal 6, wb.styles.style_index.count + assert_equal 6, wb.styled_cells.count + + b2_cell_style = { + border: { + style: :thick, + color: 'ff0000', + edges: [:bottom, :left, :top] + }, + type: :xf, + name: 'Arial', + sz: 11, + family: 1 + } + assert_equal b2_cell_style, wb.styles.style_index.values.find{|x| x == b2_cell_style} + + d3_cell_style = { + border: { + style: :thin, + color: '000000', + edges: [:bottom, :right] + }, + type: :xf, + name: 'Arial', + sz: 11, + family: 1 + } + assert_equal d3_cell_style, wb.styles.style_index.values.find{|x| x == d3_cell_style} + end + + def test_mixed_borders_1 + p = Axlsx::Package.new + wb = p.workbook + + wb.add_worksheet do |sheet| + sheet.add_row + sheet.add_row ['', '1', '2', '3'] + sheet.add_row ['', '4', '5', '6'] + sheet.add_row ['', '7', '8', '9'] + sheet.add_style 'B2:D4', border: { style: :thin, color: '000000' } + sheet.add_border 'C3:D4', style: :medium + end + + wb.apply_styles + + assert_equal 9, wb.styled_cells.count + assert_equal 2, wb.styles.style_index.count + end + + def test_mixed_borders_2 + p = Axlsx::Package.new + wb = p.workbook + + wb.add_worksheet do |sheet| + sheet.add_row + sheet.add_row ['', '1', '2', '3'] + sheet.add_row ['', '4', '5', '6'] + sheet.add_row ['', '7', '8', '9'] + sheet.add_border 'B2:D4', style: :medium + sheet.add_style 'D2:D4', border: { style: :thin, color: '000000' } + end + + wb.apply_styles + + assert_equal 8, wb.styled_cells.count + assert_equal 6, wb.styles.style_index.count + end + + def test_dxf_cell + p = Axlsx::Package.new + wb = p.workbook + + wb.add_worksheet do |sheet| + sheet.add_row (1..2).to_a + sheet.add_style "A1:A1", { bg_color: "AA0000" } + + sheet.add_row (1..2).to_a + sheet.add_style "B1:B1", { bg_color: "CC0000" } + + sheet.add_row (1..2).to_a + sheet.add_style "A3:B3", { bg_color: "00FF00" } + + wb.styles.add_style(bg_color: "0000FF", type: :dxf) + end + + wb.apply_styles + + assert_equal 1, wb.styles.dxfs.count + + assert_equal 6, wb.styles.cellXfs.count + end + + def test_default_font_with_style_index + p = Axlsx::Package.new + wb = p.workbook + + wb.styles.fonts[0].name = 'Times New Roman' + wb.styles.fonts[0].sz = 12 + + wb.add_worksheet do |sheet| + sheet.add_row [1,2,3] + sheet.add_style "A1:C1", { color: "FFFFFF" } + end + + wb.apply_styles + + assert_equal 1, wb.styles.style_index.size + + assert_equal( + { + type: :xf, + name: "Times New Roman", + sz: 12, + family: 1, + color: "FFFFFF", + }, + wb.styles.style_index.values.first + ) + end + end -- cgit v1.2.3 From d5db40a886e6675214b247b8eb8c649f30a84f18 Mon Sep 17 00:00:00 2001 From: Weston Ganger Date: Wed, 12 Oct 2022 23:23:31 -0700 Subject: Add example images, Fix axlsx_styler check --- examples/add_border_example.md | 2 +- examples/append_styles_example.md | 4 ++-- examples/images/add_border_example.png | Bin 0 -> 7026 bytes examples/images/append_styles_example.png | Bin 0 -> 8034 bytes lib/axlsx.rb | 8 +++----- 5 files changed, 6 insertions(+), 8 deletions(-) create mode 100644 examples/images/add_border_example.png create mode 100644 examples/images/append_styles_example.png diff --git a/examples/add_border_example.md b/examples/add_border_example.md index 934cf183..d64b940d 100644 --- a/examples/add_border_example.md +++ b/examples/add_border_example.md @@ -25,4 +25,4 @@ p.serialize "add_border.xlsx" ## Output -![Output](images/add_border.png "Output") +![Output](images/add_border_example.png "Output") diff --git a/examples/append_styles_example.md b/examples/append_styles_example.md index 0dc7792c..d8cb4696 100644 --- a/examples/append_styles_example.md +++ b/examples/append_styles_example.md @@ -21,11 +21,11 @@ wb.add_worksheet do |sheet| sheet.add_style "B3:D5", bg_color: "E2F89C" sheet.add_style "D3:D5", alignment: { horizontal: :left } sheet.add_style ["C3:C4", "D3:D4"], fg_color: "00FF00" -nd +end p.serialize "append_styles.xlsx" ``` ## Output -![Output](images/append_styles.png "Output") +![Output](images/append_styles_example.png "Output") diff --git a/examples/images/add_border_example.png b/examples/images/add_border_example.png new file mode 100644 index 00000000..f18ac144 Binary files /dev/null and b/examples/images/add_border_example.png differ diff --git a/examples/images/append_styles_example.png b/examples/images/append_styles_example.png new file mode 100644 index 00000000..5b8b2d55 Binary files /dev/null and b/examples/images/append_styles_example.png differ diff --git a/lib/axlsx.rb b/lib/axlsx.rb index e02256e6..23082b71 100644 --- a/lib/axlsx.rb +++ b/lib/axlsx.rb @@ -32,13 +32,11 @@ require 'set' require 'time' begin - require "axlsx_styler" - - if defined?(AxlsxStyler) + if Gem.loaded_specs.has_key?("axlsx_styler") raise StandardError.new("Please remove `axlsx_styler` from your Gemfile, the associated functionality is now built-in to `caxlsx` directly.") end -rescue LoadError - # Do nothing, all good +rescue + # Do nothing end # xlsx generation with charts, images, automated column width, customizable styles -- cgit v1.2.3 From 449056492f8c9fd44684dbf7bbe18f401fe5e6ad Mon Sep 17 00:00:00 2001 From: Weston Ganger Date: Thu, 20 Oct 2022 17:02:43 -0700 Subject: Remove axlsx_styler gem from readme --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 3d0fb760..e8de7f92 100644 --- a/README.md +++ b/README.md @@ -120,8 +120,6 @@ Currently the following additional gems are available: * Provides a `.axlsx` renderer to Rails so you can move all your spreadsheet code from your controller into view files. - [activeadmin-caxlsx](https://github.com/caxlsx/activeadmin-caxlsx) * An Active Admin plugin that includes DSL to create downloadable reports. -- [axlsx_styler](https://github.com/axlsx-styler-gem/axlsx_styler) - * Allows you to build clean and maintainable styles for your axlsx spreadsheets. Build your spreadsheeet with data and then apply styles later. ## Known Software Interoperability Issues -- cgit v1.2.3