diff options
26 files changed, 286 insertions, 75 deletions
diff --git a/.travis.yml b/.travis.yml index 088ab1da..4e4b6a59 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,9 @@ notifications: rvm: - 1.9.2 - 1.9.3 - - 2.0.0 - - 2.1.0 + - 2.0 + - 2.1 + - 2.2 - rbx - jruby-19mode - ruby-head @@ -1,9 +1,10 @@ -source "https://rubygems.org" +source 'https://rubygems.org' gemspec group :test do - gem "rake", ">= 0.8.7" - gem "simplecov" + gem 'rake', '>= 0.8.7' + gem 'simplecov' + gem 'test-unit' end group :profile do @@ -2,7 +2,7 @@ Axlsx: Office Open XML Spreadsheet Generation ==================================== [](http://travis-ci.org/randym/axlsx/) -If you are using axlsx for comercial purposes, or just want to show your +If you are using axlsx for commercial purposes, or just want to show your appreciation for the gem, please don't hesitate to make a donation. [](http://www.pledgie.com/campaigns/17814) @@ -52,7 +52,7 @@ If you are working with ActiveAdmin see: [activeadmin-axlsx](http://github.com/randym/activeadmin-axlsx) -It provies a plugin and dsl for generating downloadable reports. +It provides a plugin and dsl for generating downloadable reports. The examples directory contains a number of more specific examples as well. diff --git a/axlsx.gemspec b/axlsx.gemspec index 7d4ab2b6..8e3cd9ca 100644 --- a/axlsx.gemspec +++ b/axlsx.gemspec @@ -3,12 +3,12 @@ require File.expand_path('../lib/axlsx/version', __FILE__) Gem::Specification.new do |s| s.name = 'axlsx' s.version = Axlsx::VERSION - s.author = "Randy Morgan" + s.author = ["Randy Morgan", "Jurriaan Pruis"] s.email = '[email protected]' - s.homepage = 'https://github.com/randym/axlsx' + s.homepage = 'https://github.com/randym/axlsx' s.platform = Gem::Platform::RUBY s.date = Time.now.strftime('%Y-%m-%d') - s.summary = "excel OOXML (xlsx) with charts, styles, images and autowidth columns." + s.summary = "Excel OOXML (xlsx) with charts, styles, images and autowidth columns." s.has_rdoc = 'axlsx' s.license = 'MIT' s.description = <<-eof @@ -18,8 +18,9 @@ Gem::Specification.new do |s| s.test_files = Dir.glob("{test/**/*}") s.add_runtime_dependency 'nokogiri', '>= 1.4.1' - s.add_runtime_dependency 'rubyzip', '~> 1.1.1' + s.add_runtime_dependency 'rubyzip', '~> 1.1.7' s.add_runtime_dependency "htmlentities", "~> 4.3.1" + s.add_runtime_dependency "mimemagic", "~> 0.3" s.add_development_dependency 'yard' s.add_development_dependency 'kramdown' diff --git a/examples/IMAGE1UP.JPEG b/examples/IMAGE1UP.JPEG Binary files differdeleted file mode 100644 index ce1d0c56..00000000 --- a/examples/IMAGE1UP.JPEG +++ /dev/null diff --git a/examples/conditional_formatting/example_conditional_formatting.rb b/examples/conditional_formatting/example_conditional_formatting.rb index 320ae9f1..37df52f0 100644 --- a/examples/conditional_formatting/example_conditional_formatting.rb +++ b/examples/conditional_formatting/example_conditional_formatting.rb @@ -9,6 +9,7 @@ book = p.workbook # define your regular styles percent = book.styles.add_style(:format_code => "0.00%", :border => Axlsx::STYLE_THIN_BORDER) money = book.styles.add_style(:format_code => '0,000', :border => Axlsx::STYLE_THIN_BORDER) +status = book.styles.add_style(:border => Axlsx::STYLE_THIN_BORDER) # define the style for conditional formatting profitable = book.styles.add_style( :fg_color => "428751", :type => :dxf ) @@ -71,4 +72,18 @@ book.add_worksheet(:name => "Icon Set") do |ws| ws.add_conditional_formatting("B3:B100", { :type => :iconSet, :dxfId => profitable, :priority => 1, :icon_set => icon_set }) end +book.add_worksheet(:name => "Contains Text") do |ws| + ws.add_row ["Previous Year Quarterly Profits (JPY)"] + ws.add_row ["Quarter", "Profit", "% of Total", "Status"] + offset = 3 + rows = 20 + offset.upto(rows + offset) do |i| + ws.add_row ["Q#{i}", 10000*((rows/2-i) * (rows/2-i)), "=100*B#{i}/SUM(B3:B#{rows+offset})", (10000*((rows/2-i) * (rows/2-i))) > 100000 ? "PROFIT" : "LOSS"], :style=>[nil, money, percent, status] + end + +# Apply conditional formatting to range D3:D100 in the worksheet + ws.add_conditional_formatting("D3:D100", { :type => :containsText, :operator => :equal, :text => "PROFIT", :dxfId => profitable, :priority => 1 }) + ws.add_conditional_formatting("D3:D100", { :type => :containsText, :operator => :equal, :text => "LOSS", :dxfId => unprofitable, :priority => 1 }) +end + p.serialize('example_conditional_formatting.xlsx') diff --git a/examples/example.rb b/examples/example.rb index 116ce730..4d4c2630 100755 --- a/examples/example.rb +++ b/examples/example.rb @@ -14,6 +14,7 @@ examples << :surrounding_border examples << :deep_custom_borders examples << :row_column_style examples << :fixed_column_width +examples << :height examples << :outline_level examples << :merge_cells examples << :images @@ -50,6 +51,7 @@ examples << :no_autowidth examples << :cached_formula examples << :page_breaks examples << :rich_text +examples << :tab_color p = Axlsx::Package.new wb = p.workbook @@ -210,6 +212,7 @@ if examples.include? :row_column_style head = s.add_style :bg_color => "00", :fg_color => "FF" percent = s.add_style :num_fmt => 9 wb.add_worksheet(:name => "Columns and Rows") do |sheet| + # Note: you must add rows to the document *BEFORE* applying column styles to them sheet.add_row ['col 1', 'col 2', 'col 3', 'col 4', 'col5'] sheet.add_row [1, 2, 0.3, 4, 5.0] sheet.add_row [1, 2, 0.2, 4, 5.0] @@ -246,6 +249,21 @@ if examples.include? :fixed_column_width end end + +##Specifying Row height + +#```ruby +if examples.include? :height + wb.styles do |s| + head = s.add_style :bg_color => "00", :fg_color => "FF" + wb.add_worksheet(:name => "fixed row height") do |sheet| + sheet.add_row ["This row will have a fixed height", "It will overwite the default row height"], :height => 30 + sheet.add_row ["This row can have a different height too"], :height => 10, :style => head + end + end +end + + #```ruby if examples.include? :outline_level wb.add_worksheet(name: 'outline_level') do |sheet| @@ -659,7 +677,7 @@ end ## Book Views # -## Book views let you specify which sheet the show as active when the user opens the work book as well as a bunch of other +## Book views let you specify which sheet the show as active when the user opens the work book as well as a bunch of other ## tuning values for the UI @see Axlsx::WorkbookView ## ```ruby if examples.include? :book_view @@ -683,6 +701,7 @@ end if examples.include? :conditional_formatting percent = wb.styles.add_style(:format_code => "0.00%", :border => Axlsx::STYLE_THIN_BORDER) money = wb.styles.add_style(:format_code => '0,000', :border => Axlsx::STYLE_THIN_BORDER) + status = wb.styles.add_style(:border => Axlsx::STYLE_THIN_BORDER) # define the style for conditional formatting profitable = wb.styles.add_style( :fg_color => "FF428751", :type => :dxf ) @@ -746,6 +765,19 @@ if examples.include? :conditional_formatting icon_set = Axlsx::IconSet.new sheet.add_conditional_formatting("B3:B100", { :type => :iconSet, :dxfId => profitable, :priority => 1, :icon_set => icon_set }) end + + wb.add_worksheet(:name => "Contains Text") do |sheet| + sheet.add_row ["Previous Year Quarterly Profits (JPY)"] + sheet.add_row ["Quarter", "Profit", "% of Total", "Status"] + offset = 3 + rows = 20 + offset.upto(rows + offset) do |i| + sheet.add_row ["Q#{i}", 10000*((rows/2-i) * (rows/2-i)), "=100*B#{i}/SUM(B3:B#{rows+offset})", (10000*((rows/2-i) * (rows/2-i))) > 100000 ? "PROFIT" : "LOSS"], :style=>[nil, money, percent, status] + end + # Apply conditional formatting to range D3:D100 in the worksheet to match words. + sheet.add_conditional_formatting("D3:D100", { :type => :containsText, :operator => :equal, :text => "PROFIT", :dxfId => profitable, :priority => 1 }) + sheet.add_conditional_formatting("D3:D100", { :type => :containsText, :operator => :equal, :text => "LOSS", :dxfId => unprofitable, :priority => 1 }) + end end # Page Breaks @@ -825,4 +857,19 @@ if examples.include? :rich_text end p.serialize 'rich_text.xlsx' end -#```
\ No newline at end of file +#``` + +##Change tab color of sheet + +#```ruby +if examples.include? :tab_color + p = Axlsx::Package.new + p.use_shared_strings = true + wb = p.workbook + wb.add_worksheet(:name => "Change Tab Color") do |sheet| + sheet.add_row ["Check", "out", "the", "Tab Color", "below!"] + sheet.sheet_pr.tab_color = "FFFF6666" + end + p.serialize 'tab_color.xlsx' +end +##``` diff --git a/examples/image1_fake.jpg b/examples/image1_fake.jpg new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/examples/image1_fake.jpg diff --git a/lib/axlsx.rb b/lib/axlsx.rb index c6f01b19..c5d26c2b 100644 --- a/lib/axlsx.rb +++ b/lib/axlsx.rb @@ -1,6 +1,7 @@ # encoding: UTF-8 require 'htmlentities' require 'axlsx/version.rb' +require 'mimemagic' require 'axlsx/util/simple_typed_list.rb' require 'axlsx/util/constants.rb' @@ -11,6 +12,7 @@ require 'axlsx/util/options_parser' # to be included with parsable intitites. #require 'axlsx/util/parser.rb' require 'axlsx/util/string' +require 'axlsx/util/mime_type_utils' require 'axlsx/stylesheet/styles.rb' diff --git a/lib/axlsx/drawing/chart.rb b/lib/axlsx/drawing/chart.rb index 1d6b9293..e7fcc9e8 100644 --- a/lib/axlsx/drawing/chart.rb +++ b/lib/axlsx/drawing/chart.rb @@ -11,6 +11,7 @@ module Axlsx # @param [GraphicalFrame] frame The frame that holds this chart. # @option options [Cell, String] title # @option options [Boolean] show_legend + # @option options [Symbol] legend_position # @option options [Array|String|Cell] start_at The X, Y coordinates defining the top left corner of the chart. # @option options [Array|String|Cell] end_at The X, Y coordinates defining the bottom right corner of the chart. def initialize(frame, options={}) @@ -20,9 +21,11 @@ module Axlsx @graphic_frame.anchor.drawing.worksheet.workbook.charts << self @series = SimpleTypedList.new Series @show_legend = true + @legend_position = :r @display_blanks_as = :gap @series_type = Series @title = Title.new + @bg_color = nil parse_options options start_at(*options[:start_at]) if options[:start_at] end_at(*options[:end_at]) if options[:end_at] @@ -71,6 +74,17 @@ module Axlsx # @return [Boolean] attr_reader :show_legend + # Set the location of the chart's legend + # @return [Symbol] The position of this legend + # @note + # The following are allowed + # :b + # :l + # :r + # :t + # :tr + attr_reader :legend_position + # How to display blank values # Options are # * gap: Display nothing @@ -80,6 +94,10 @@ module Axlsx # Default :gap (although this really should vary by chart type and grouping) attr_reader :display_blanks_as + # Background color for the chart + # @return [String] + attr_reader :bg_color + # The relationship object for this chart. # @return [Relationship] def relationship @@ -126,6 +144,9 @@ module Axlsx # @param [Integer] v must be between 1 and 48 def style=(v) DataTypeValidator.validate "Chart.style", Integer, v, lambda { |arg| arg >= 1 && arg <= 48 }; @style = v; end + # @see legend_position + def legend_position=(v) RestrictionValidator.validate "Chart.legend_position", [:b, :l, :r, :t, :tr], v; @legend_position = v; end + # backwards compatibility to allow chart.to and chart.from access to anchor markers # @note This will be disconinued in version 2.0.0. Please use the end_at method def to @@ -146,6 +167,12 @@ module Axlsx @series.last end + # Assigns a background color to chart area + def bg_color=(v) + DataTypeValidator.validate(:color, Color, Color.new(:rgb => v)) + @bg_color = v + end + # Serializes the object # @param [String] str # @return [String] @@ -167,7 +194,7 @@ module Axlsx str << '</c:plotArea>' if @show_legend str << '<c:legend>' - str << '<c:legendPos val="r"/>' + str << ('<c:legendPos val="' << @legend_position.to_s << '"/>') str << '<c:layout/>' str << '<c:overlay val="0"/>' str << '</c:legend>' @@ -176,6 +203,16 @@ module Axlsx str << ('<c:dispBlanksAs val="' << display_blanks_as.to_s << '"/>') str << '<c:showDLblsOverMax val="1"/>' str << '</c:chart>' + if bg_color + str << '<c:spPr>' + str << '<a:solidFill>' + str << '<a:srgbClr val="' << bg_color << '"/>' + str << '</a:solidFill>' + str << '<a:ln>' + str << '<a:noFill/>' + str << '</a:ln>' + str << '</c:spPr>' + end str << '<c:printSettings>' str << '<c:headerFooter/>' str << '<c:pageMargins b="1.0" l="0.75" r="0.75" t="1.0" header="0.5" footer="0.5"/>' diff --git a/lib/axlsx/drawing/pic.rb b/lib/axlsx/drawing/pic.rb index 571e9047..275a6d06 100644 --- a/lib/axlsx/drawing/pic.rb +++ b/lib/axlsx/drawing/pic.rb @@ -9,12 +9,13 @@ module Axlsx # Creates a new Pic(ture) object # @param [Anchor] anchor the anchor that holds this image - # @option options [String] name - # @option options [String] descr - # @option options [String] image_src - # @option options [Array] start_at - # @option options [Intger] width - # @option options [Intger] height + # @option options [String] :name + # @option options [String] :descr + # @option options [String] :image_src + # @option options [Array] :start_at + # @option options [Integer] :width + # @option options [Integer] :height + # @option options [Float] :opacity - set the picture opacity, accepts a value between 0.0 and 1.0 def initialize(anchor, options={}) @anchor = anchor @hyperlink = nil @@ -23,10 +24,11 @@ module Axlsx start_at(*options[:start_at]) if options[:start_at] yield self if block_given? @picture_locking = PictureLocking.new(options) + @opacity = (options[:opacity] * 100000).round if options[:opacity] end - # allowed file extenstions - ALLOWED_EXTENSIONS = ['gif', 'jpeg', 'png', 'jpg'] + # allowed mime types + ALLOWED_MIME_TYPES = %w(image/jpeg image/png image/gif) # The name to use for this picture # @return [String] @@ -50,24 +52,28 @@ module Axlsx attr_reader :hyperlink + # Picture opacity + # @return [Fixnum] + attr_reader :opacity + # sets or updates a hyperlink for this image. # @param [String] v The href value for the hyper link # @option options @see Hyperlink#initialize All options available to the Hyperlink class apply - however href will be overridden with the v parameter value. def hyperlink=(v, options={}) options[:href] = v - if @hyperlink.is_a?(Hyperlink) + if hyperlink.is_a?(Hyperlink) options.each do |o| - @hyperlink.send("#{o[0]}=", o[1]) if @hyperlink.respond_to? "#{o[0]}=" + hyperlink.send("#{o[0]}=", o[1]) if hyperlink.respond_to? "#{o[0]}=" end else @hyperlink = Hyperlink.new(self, options) end - @hyperlink + hyperlink end def image_src=(v) Axlsx::validate_string(v) - RestrictionValidator.validate 'Pic.image_src', ALLOWED_EXTENSIONS, File.extname(v.downcase).delete('.') + RestrictionValidator.validate 'Pic.image_src', ALLOWED_MIME_TYPES, MimeTypeUtils.get_mime_type(v) raise ArgumentError, "File does not exist" unless File.exist?(v) @image_src = v end @@ -78,7 +84,6 @@ module Axlsx # @see descr def descr=(v) Axlsx::validate_string(v); @descr = v; end - # The file name of image_src without any path information # @return [String] def file_name @@ -166,12 +171,16 @@ module Axlsx str << '<xdr:pic>' str << '<xdr:nvPicPr>' str << ('<xdr:cNvPr id="2" name="' << name.to_s << '" descr="' << descr.to_s << '">') - @hyperlink.to_xml_string(str) if @hyperlink.is_a?(Hyperlink) + hyperlink.to_xml_string(str) if hyperlink.is_a?(Hyperlink) str << '</xdr:cNvPr><xdr:cNvPicPr>' picture_locking.to_xml_string(str) str << '</xdr:cNvPicPr></xdr:nvPicPr>' str << '<xdr:blipFill>' - str << ('<a:blip xmlns:r ="' << XML_NS_R << '" r:embed="' << relationship.Id << '"/>') + str << ('<a:blip xmlns:r ="' << XML_NS_R << '" r:embed="' << relationship.Id << '">') + if opacity + str << "<a:alphaModFix amt=\"#{opacity}\"/>" + end + str << '</a:blip>' str << '<a:stretch><a:fillRect/></a:stretch></xdr:blipFill><xdr:spPr>' str << '<a:xfrm><a:off x="0" y="0"/><a:ext cx="2336800" cy="2161540"/></a:xfrm>' str << '<a:prstGeom prst="rect"><a:avLst/></a:prstGeom></xdr:spPr></xdr:pic>' diff --git a/lib/axlsx/drawing/scatter_series.rb b/lib/axlsx/drawing/scatter_series.rb index 28962230..c0d6e8f1 100644 --- a/lib/axlsx/drawing/scatter_series.rb +++ b/lib/axlsx/drawing/scatter_series.rb @@ -21,9 +21,21 @@ module Axlsx # @return [String] attr_reader :color + # Line smoothing between data points + # @return [Boolean] + attr_reader :smooth + # Creates a new ScatterSeries def initialize(chart, options={}) @xData, @yData = nil + if options[:smooth].nil? + # If caller hasn't specified smoothing or not, turn smoothing on or off based on scatter style + @smooth = [:smooth, :smoothMarker].include?(chart.scatter_style) + else + # Set smoothing according to the option provided + Axlsx::validate_boolean(options[:smooth]) + @smooth = options[:smooth] + end super(chart, options) @xData = AxDataSource.new(:tag_name => :xVal, :data => options[:xData]) unless options[:xData].nil? @yData = NumDataSource.new({:tag_name => :yVal, :data => options[:yData]}) unless options[:yData].nil? @@ -34,6 +46,12 @@ module Axlsx @color = v end + # @see smooth + def smooth=(v) + Axlsx::validate_boolean(v) + @smooth = v + end + # Serializes the object # @param [String] str # @return [String] @@ -58,6 +76,7 @@ module Axlsx end @xData.to_xml_string(str) unless @xData.nil? @yData.to_xml_string(str) unless @yData.nil? + str << ('<c:smooth val="' << ((smooth) ? '1' : '0') << '"/>') end str end diff --git a/lib/axlsx/package.rb b/lib/axlsx/package.rb index cd03a173..8a4f29dc 100644 --- a/lib/axlsx/package.rb +++ b/lib/axlsx/package.rb @@ -314,7 +314,7 @@ module Axlsx c_types << Axlsx::Override.new(:PartName => "/xl/#{sheet.pn}", :ContentType => WORKSHEET_CT) end - exts = workbook.images.map { |image| image.extname } + exts = workbook.images.map { |image| image.extname.downcase } exts.uniq.each do |ext| ct = if ['jpeg', 'jpg'].include?(ext) JPEG_CT diff --git a/lib/axlsx/util/mime_type_utils.rb b/lib/axlsx/util/mime_type_utils.rb new file mode 100644 index 00000000..3fe2dbbd --- /dev/null +++ b/lib/axlsx/util/mime_type_utils.rb @@ -0,0 +1,11 @@ +module Axlsx + # This module defines some utils related with mime type detection + module MimeTypeUtils + # Detect a file mime type + # @param [String] v File path + # @return [String] File mime type + def self.get_mime_type(v) + MimeMagic.by_magic(File.open(v)).to_s + end + end +end diff --git a/lib/axlsx/version.rb b/lib/axlsx/version.rb index aa34cabb..df4bd9ed 100644 --- a/lib/axlsx/version.rb +++ b/lib/axlsx/version.rb @@ -1,5 +1,5 @@ module Axlsx # The current version - VERSION = "2.0.1" + VERSION = "2.1.0.pre" end diff --git a/lib/axlsx/workbook/worksheet/page_setup.rb b/lib/axlsx/workbook/worksheet/page_setup.rb index fc29b0c5..9558579e 100644 --- a/lib/axlsx/workbook/worksheet/page_setup.rb +++ b/lib/axlsx/workbook/worksheet/page_setup.rb @@ -44,13 +44,13 @@ module Axlsx # Number of horizontal pages to fit on. # @note PageSetup#fit_to is the recomended way to manage page fitting as only specifying one of width/height will result in the counterpart - # being set to 1. + # being set to 1. # @return [Integer] attr_reader :fit_to_width # Orientation of the page (:default, :landscape, :portrait) # @return [Symbol] - attr_reader :orientation + attr_reader :orientation # Height of paper (string containing a number followed by a unit identifier: "297mm", "11in") # @return [String] @@ -74,18 +74,18 @@ module Axlsx #7 = Executive paper (7.25 in. by 10.5 in.) #8 = A3 paper (297 mm by 420 mm) #9 = A4 paper (210 mm by 297 mm) - #10 = A4 small paper (210 mm by 297 mm) + #10 = A4 small paper (210 mm by 297 mm) #11 = A5 paper (148 mm by 210 mm) #12 = B4 paper (250 mm by 353 mm) #13 = B5 paper (176 mm by 250 mm) #14 = Folio paper (8.5 in. by 13 in.) - #15 = Quarto paper (215 mm by 275 mm) + #15 = Quarto paper (215 mm by 275 mm) #16 = Standard paper (10 in. by 14 in.) #17 = Standard paper (11 in. by 17 in.) #18 = Note paper (8.5 in. by 11 in.) - #19 = #9 envelope (3.875 in. by 8.875 in.) - #20 = #10 envelope (4.125 in. by 9.5 in.) - #21 = #11 envelope (4.5 in. by 10.375 in.) + #19 = #9 envelope (3.875 in. by 8.875 in.) + #20 = #10 envelope (4.125 in. by 9.5 in.) + #21 = #11 envelope (4.5 in. by 10.375 in.) #22 = #12 envelope (4.75 in. by 11 in.) #23 = #14 envelope (5 in. by 11.5 in.) 24 = C paper (17 in. by 22 in.) #25 = D paper (22 in. by 34 in.) @@ -105,7 +105,7 @@ module Axlsx #40 = German standard fanfold (8.5 in. by 12 in.) #41 = German legal fanfold (8.5 in. by 13 in.) #42 = ISO B4 (250 mm by 353 mm) - #43 = Japanese double postcard (200 mm by 148 mm) + #43 = Japanese double postcard (200 mm by 148 mm) #44 = Standard paper (9 in. by 11 in.) #45 = Standard paper (10 in. by 11 in.) #46 = Standard paper (15 in. by 11 in.) @@ -116,9 +116,9 @@ module Axlsx #53 = A4 extra paper (236 mm by 322 mm) #54 = Letter transverse paper (8.275 in. by 11 in.) #55 = A4 transverse paper (210 mm by 297 mm) - #56 = Letter extra transverse paper (9.275 in. by 12 in.) - #57 = SuperA/SuperA/A4 paper (227 mm by 356 mm) - #58 = SuperB/SuperB/A3 paper (305 mm by 487 mm) + #56 = Letter extra transverse paper (9.275 in. by 12 in.) + #57 = SuperA/SuperA/A4 paper (227 mm by 356 mm) + #58 = SuperB/SuperB/A3 paper (305 mm by 487 mm) #59 = Letter plus paper (8.5 in. by 12.69 in.) #60 = A4 plus paper (210 mm by 330 mm) #61 = A5 transverse paper (148 mm by 210 mm) @@ -128,8 +128,8 @@ module Axlsx #65 = ISO B5 extra paper (201 mm by 276 mm) #66 = A2 paper (420 mm by 594 mm) #67 = A3 transverse paper (297 mm by 420 mm) - #68 = A3 extra transverse paper (322 mm by 445 mm) - #69 = Japanese Double Postcard (200 mm x 148 mm) + #68 = A3 extra transverse paper (322 mm by 445 mm) + #69 = Japanese Double Postcard (200 mm x 148 mm) #70 = A6 (105 mm x 148 mm #71 = Japanese Envelope Kaku #2 #72 = Japanese Envelope Kaku #3 @@ -142,7 +142,7 @@ module Axlsx #79 = B4 (JIS) Rotated (364 mm x 257 mm) #80 = B5 (JIS) Rotated (257 mm x 182 mm) #81 = Japanese Postcard Rotated (148 mm x 100 mm) - #82 = Double Japanese Postcard Rotated (148 mm x 200 mm) + #82 = Double Japanese Postcard Rotated (148 mm x 200 mm) #83 = A6 Rotated (148 mm x 105 mm) #84 = Japanese Envelope Kaku #2 Rotated #85 = Japanese Envelope Kaku #3 Rotated @@ -210,20 +210,20 @@ module Axlsx # @see scale def scale=(v); Axlsx::validate_scale_10_400(v); @scale = v; end - # convenience method to achieve sanity when setting fit_to_width and fit_to_height + # convenience method to achieve sanity when setting fit_to_width and fit_to_height # as they both default to 1 if only their counterpart is specified. # @note This method will overwrite any value you explicitly set via the fit_to_height or fit_to_width methods. - # @option options [Integer] width The number of pages to fit this worksheet on horizontally. Default 9999 - # @option options [Integer] height The number of pages to fit this worksheet on vertically. Default 9999 + # @option options [Integer] width The number of pages to fit this worksheet on horizontally. Default 999 + # @option options [Integer] height The number of pages to fit this worksheet on vertically. Default 999 def fit_to(options={}) - self.fit_to_width = options[:width] || 9999 - self.fit_to_height = options[:height] || 9999 + self.fit_to_width = options[:width] || 999 + self.fit_to_height = options[:height] || 999 [@fit_to_width, @fit_to_height] end # helper method for worksheet to determine if the page setup is configured for fit to page printing - # We treat any page set up that has a value set for fit_to_width or fit_to_height value as fit_to_page. + # We treat any page set up that has a value set for fit_to_width or fit_to_height value as fit_to_page. # @return [Boolean] def fit_to_page? # is there some better what to express this? diff --git a/lib/axlsx/workbook/worksheet/row.rb b/lib/axlsx/workbook/worksheet/row.rb index 00ae71a9..078e281f 100644 --- a/lib/axlsx/workbook/worksheet/row.rb +++ b/lib/axlsx/workbook/worksheet/row.rb @@ -94,7 +94,7 @@ module Axlsx end end - # Adds a single sell to the row based on the data provided and updates the worksheet's autofit data. + # Adds a single cell to the row based on the data provided and updates the worksheet's autofit data. # @return [Cell] def add_cell(value = '', options = {}) c = Cell.new(self, value, options) diff --git a/lib/axlsx/workbook/worksheet/sheet_pr.rb b/lib/axlsx/workbook/worksheet/sheet_pr.rb index f271419b..a299bc0f 100644 --- a/lib/axlsx/workbook/worksheet/sheet_pr.rb +++ b/lib/axlsx/workbook/worksheet/sheet_pr.rb @@ -8,7 +8,7 @@ module Axlsx serializable_attributes :sync_horizontal, :sync_vertical, - :transtion_evaluation, + :transition_evaluation, :transition_entry, :published, :filter_mode, @@ -20,7 +20,7 @@ module Axlsx # waving magic show to set up the attriubte accessors boolean_attr_accessor :sync_horizontal, :sync_vertical, - :transtion_evaluation, + :transition_evaluation, :transition_entry, :published, :filter_mode, @@ -40,12 +40,17 @@ module Axlsx # @return [Worksheet] attr_reader :worksheet + # The tab color of the sheet. + # @return [Color] + attr_reader :tab_color + # Serialize the object # @param [String] str serialized output will be appended to this object if provided. # @return [String] def to_xml_string(str = '') update_properties str << "<sheetPr #{serialized_attributes}>" + tab_color.to_xml_string(str, 'tabColor') if tab_color page_setup_pr.to_xml_string(str) str << "</sheetPr>" end @@ -56,6 +61,11 @@ module Axlsx @page_setup_pr ||= PageSetUpPr.new end + # @see tab_color + def tab_color=(v) + @tab_color ||= Color.new(:rgb => v) + end + private def update_properties diff --git a/lib/axlsx/workbook/worksheet/worksheet.rb b/lib/axlsx/workbook/worksheet/worksheet.rb index 3a8aeb46..1d35b99d 100644 --- a/lib/axlsx/workbook/worksheet/worksheet.rb +++ b/lib/axlsx/workbook/worksheet/worksheet.rb @@ -91,7 +91,7 @@ module Axlsx # @see [SheetFormatPr] def sheet_format_pr @sheet_format_pr ||= SheetFormatPr.new - yeild @sheet_format_pr if block_given? + yield @sheet_format_pr if block_given? @sheet_format_pr end diff --git a/test/drawing/tc_pic.rb b/test/drawing/tc_pic.rb index b8bd2c36..2c58fcfd 100644 --- a/test/drawing/tc_pic.rb +++ b/test/drawing/tc_pic.rb @@ -5,8 +5,10 @@ class TestPic < Test::Unit::TestCase def setup @p = Axlsx::Package.new ws = @p.workbook.add_worksheet - @test_img = File.dirname(__FILE__) + "/../../examples/image1.jpeg" - @test_img_up = File.dirname(__FILE__) + "/../../examples/IMAGE1UP.JPEG" + @test_img = @test_img_jpg = File.dirname(__FILE__) + "/../../examples/image1.jpeg" + @test_img_png = File.dirname(__FILE__) + "/../../examples/image1.png" + @test_img_gif = File.dirname(__FILE__) + "/../../examples/image1.gif" + @test_img_fake = File.dirname(__FILE__) + "/../../examples/image1_fake.jpg" @image = ws.add_image :image_src => @test_img, :hyperlink => 'https://github.com/randym', :tooltip => "What's up doc?" end @@ -70,15 +72,12 @@ class TestPic < Test::Unit::TestCase end def test_image_src - assert_raise(ArgumentError) { @image.image_src = 49 } - assert_raise(ArgumentError) { @image.image_src = 'Unknown' } assert_raise(ArgumentError) { @image.image_src = __FILE__ } - assert_nothing_raised { @image.image_src = @test_img } - assert_equal(@image.image_src, @test_img) - end - - def test_image_src_downcase - assert_nothing_raised { @image.image_src = @test_img_up } + assert_raise(ArgumentError) { @image.image_src = @test_img_fake } + assert_nothing_raised { @image.image_src = @test_img_gif } + assert_nothing_raised { @image.image_src = @test_img_png } + assert_nothing_raised { @image.image_src = @test_img_jpg } + assert_equal(@image.image_src, @test_img_jpg) end def test_descr diff --git a/test/drawing/tc_scatter_series.rb b/test/drawing/tc_scatter_series.rb index b43ed171..62a338b1 100644 --- a/test/drawing/tc_scatter_series.rb +++ b/test/drawing/tc_scatter_series.rb @@ -6,13 +6,37 @@ class TestScatterSeries < Test::Unit::TestCase p = Axlsx::Package.new @ws = p.workbook.add_worksheet :name=>"hmmm" @chart = @ws.add_chart Axlsx::ScatterChart, :title => "Scatter Chart" - @series = @chart.add_series :xData=>[1,2,4], :yData=>[1,3,9], :title=>"exponents", :color => 'FF0000' + @series = @chart.add_series :xData=>[1,2,4], :yData=>[1,3,9], :title=>"exponents", :color => 'FF0000', :smooth => true end def test_initialize assert_equal(@series.title.text, "exponents", "series title has been applied") end + def test_smoothed_chart_default_smoothing + @chart = @ws.add_chart Axlsx::ScatterChart, :title => "Smooth Chart", :scatter_style => :smoothMarker + @series = @chart.add_series :xData=>[1,2,4], :yData=>[1,3,9], :title=>"smoothed exponents" + assert(@series.smooth, "series is smooth by default on smooth charts") + end + + def test_unsmoothed_chart_default_smoothing + @chart = @ws.add_chart Axlsx::ScatterChart, :title => "Unsmooth Chart", :scatter_style => :line + @series = @chart.add_series :xData=>[1,2,4], :yData=>[1,3,9], :title=>"unsmoothed exponents" + assert([email protected], "series is not smooth by default on non-smooth charts") + end + + def test_explicit_smoothing + @chart = @ws.add_chart Axlsx::ScatterChart, :title => "Unsmooth Chart, Smooth Series", :scatter_style => :line + @series = @chart.add_series :xData=>[1,2,4], :yData=>[1,3,9], :title=>"smoothed exponents", :smooth => true + assert(@series.smooth, "series is smooth when overriding chart default") + end + + def test_explicit_unsmoothing + @chart = @ws.add_chart Axlsx::ScatterChart, :title => "Smooth Chart, Unsmooth Series", :scatter_style => :smoothMarker + @series = @chart.add_series :xData=>[1,2,4], :yData=>[1,3,9], :title=>"unsmoothed exponents", :smooth => false + assert([email protected], "series is not smooth when overriding chart default") + end + def test_to_xml_string doc = Nokogiri::XML(@chart.to_xml_string) assert_equal(doc.xpath("//a:srgbClr[@val='#{@series.color}']").size,4) diff --git a/test/tc_helper.rb b/test/tc_helper.rb index af40a1e4..96f545cd 100644 --- a/test/tc_helper.rb +++ b/test/tc_helper.rb @@ -7,4 +7,4 @@ end require 'test/unit' require "timecop" -require "axlsx.rb" +require "axlsx.rb"
\ No newline at end of file diff --git a/test/tc_package.rb b/test/tc_package.rb index 0a33e248..0ad27f7d 100644 --- a/test/tc_package.rb +++ b/test/tc_package.rb @@ -54,7 +54,7 @@ class TestPackage < Test::Unit::TestCase end ws.add_chart(Axlsx::BubbleChart, :title => 'bubble chart') do |chart| - chart.add_series :xData => [1,2,3,4], :yData => [4,3,2,1], :yData => [1,3,2,4] + chart.add_series :xData => [1,2,3,4], :yData => [1,3,2,4] chart.d_lbls.show_val = true end diff --git a/test/util/tc_mime_type_utils.rb b/test/util/tc_mime_type_utils.rb new file mode 100644 index 00000000..ff54ae0a --- /dev/null +++ b/test/util/tc_mime_type_utils.rb @@ -0,0 +1,13 @@ +require 'tc_helper.rb' +class TestMimeTypeUtils < Test::Unit::TestCase + def setup + @test_img = File.dirname(__FILE__) + "/../../examples/image1.jpeg" + end + + def teardown + end + + def test_mime_type_utils + assert_equal(Axlsx::MimeTypeUtils::get_mime_type(@test_img), 'image/jpeg') + end +end diff --git a/test/workbook/worksheet/tc_page_setup.rb b/test/workbook/worksheet/tc_page_setup.rb index 4c78f4ae..097eb563 100644 --- a/test/workbook/worksheet/tc_page_setup.rb +++ b/test/workbook/worksheet/tc_page_setup.rb @@ -63,7 +63,7 @@ class TestPageSetup < Test::Unit::TestCase assert(@ps.fit_to_width == nil && @ps.fit_to_height == nil) assert(@ps.fit_to_page? == false) end - + def test_with_height_fit_to_page? assert(@ps.fit_to_width == nil && @ps.fit_to_height == nil) @ps.set(:fit_to_height => 1) @@ -131,9 +131,9 @@ class TestPageSetup < Test::Unit::TestCase def test_fit_to fits = @ps.fit_to(:width => 1) - assert_equal([1, 9999], fits) + assert_equal([1, 999], fits) fits = @ps.fit_to :height => 1 - assert_equal(fits, [9999,1]) + assert_equal(fits, [999 ,1]) fits = @ps.fit_to :height => 7, :width => 2 assert_equal(fits, [2, 7]) assert_raise(ArgumentError) { puts @ps.fit_to(:width => true)} diff --git a/test/workbook/worksheet/tc_sheet_pr.rb b/test/workbook/worksheet/tc_sheet_pr.rb index 43f2941d..be45438b 100644 --- a/test/workbook/worksheet/tc_sheet_pr.rb +++ b/test/workbook/worksheet/tc_sheet_pr.rb @@ -5,23 +5,45 @@ class TestSheetPr < Test::Unit::TestCase def setup worksheet = Axlsx::Package.new.workbook.add_worksheet - @options = { + @options = { :sync_horizontal => false, :sync_vertical => false, - :transtion_evaluation => true, + :transition_evaluation => true, :transition_entry => true, :published => false, :filter_mode => true, :enable_format_conditions_calculation => false, :code_name => '007', - :sync_ref => 'foo' + :sync_ref => 'foo', + :tab_color => 'FFFF6666' } @sheet_pr = Axlsx::SheetPr.new(worksheet, @options) end def test_initialization @options.each do |key, value| - assert_equal value, @sheet_pr.send(key) + if key==:tab_color + stored_value = @sheet_pr.send(key) + assert_equal Axlsx::Color, stored_value.class + assert_equal value, stored_value.rgb + else + assert_equal value, @sheet_pr.send(key) + end end end + + def test_to_xml_string + doc = Nokogiri::XML(@sheet_pr.to_xml_string) + assert_equal(doc.xpath("//sheetPr[@syncHorizontal='0']").size, 1) + assert_equal(doc.xpath("//sheetPr[@syncVertical='0']").size, 1) + assert_equal(doc.xpath("//sheetPr[@transitionEvaluation='1']").size, 1) + assert_equal(doc.xpath("//sheetPr[@transitionEntry='1']").size, 1) + assert_equal(doc.xpath("//sheetPr[@published='0']").size, 1) + assert_equal(doc.xpath("//sheetPr[@filterMode='1']").size, 1) + assert_equal(doc.xpath("//sheetPr[@enableFormatConditionsCalculation='0']").size, 1) + assert_equal(doc.xpath("//sheetPr[@codeName='007']").size, 1) + assert_equal(doc.xpath("//sheetPr[@syncRef='foo']").size, 1) + assert_equal(doc.xpath("//sheetPr/tabColor[@rgb='FFFF6666']").size, 1) + assert_equal(doc.xpath("//sheetPr/pageSetUpPr[@fitToPage='0']").size, 1) + end end |
