diff options
| author | Randy Morgan <[email protected]> | 2012-06-07 09:03:57 +0900 |
|---|---|---|
| committer | Randy Morgan <[email protected]> | 2012-06-07 09:03:57 +0900 |
| commit | 70bf38b72a42b25976f750ff86e7521c356c157e (patch) | |
| tree | 36fddd470dc1bf157b2c4a2a57bf016523f40793 | |
| parent | 713bd69c8bce9094602fcd731d5e4cce9916b6c6 (diff) | |
| parent | 2d6d18c2e0b8e1b68adae27500c002cfb4cd01b4 (diff) | |
| download | caxlsx-70bf38b72a42b25976f750ff86e7521c356c157e.tar.gz caxlsx-70bf38b72a42b25976f750ff86e7521c356c157e.zip | |
Merge branch 'master' into pane
29 files changed, 476 insertions, 219 deletions
@@ -16,7 +16,7 @@ Axlsx: Office Open XML Spreadsheet Generation **License**: MIT License -**Latest Version**: 1.1.5 +**Latest Version**: 1.1.7 **Ruby Version**: 1.8.7, 1.9.2, 1.9.3 @@ -24,7 +24,7 @@ Axlsx: Office Open XML Spreadsheet Generation **Rubinius Version**: rubinius 2.0.0dev * lower versions may run, this gem always tests against head. -**Release Date**: May 13rd 2012 +**Release Date**: June 5th 2012 If you are working in rails, or with active record see: http://github.com/randym/acts_as_xlsx @@ -32,6 +32,9 @@ http://github.com/randym/acts_as_xlsx There are guides for using axlsx and acts_as_xlsx here: [http://axlsx.blogspot.com](http://axlsx.blogspot.com) +The examples directory contains a number of more specific examples as +well. + Synopsis -------- @@ -63,7 +66,8 @@ Feature List **9. Cell level style overrides for default and customized style objects -**10. Support for formulas +**10. Support for formulas, merging, row and column outlining as well as +cell level input data validation. **11. Support for cell merging as well as column and row outline @@ -75,6 +79,8 @@ Feature List **15. Support for page margins and print options +**16. Support for password and non password based sheet protection. + Installing ---------- @@ -86,12 +92,14 @@ To install Axlsx, use the following command: ------ The example listing is getting overly large to maintain here. -If you are using Yard, you will be able to see the examples inline below. +If you are using Yard, you will be able to see the examples in line below. If not, please refer to the Please see the {file:examples/example.rb} file. + + {include:file:examples/example.rb} -There is much, much more you can do with this gem. If you get stuck, grab me on IRC or submit an issue to Github. Chances are that it has already been implemented. If it hasn't - let's take a look at adding it in. +There is much, much more you can do with this gem. If you get stuck, grab me on IRC or submit an issue to GitHub. Chances are that it has already been implemented. If it hasn't - let's take a look at adding it in. #Documentation -------------- @@ -107,14 +115,31 @@ This gem has 100% test coverage using test/unit. To execute tests for this gem, #Change log --------- -- ** May.13.12**: 1.1.5 release +- **June.5.12**: 1.1.7 release + - fix chart rendering issue when label offset is specified as a + percentage in serialization and ensure that formula are not stored +in value caches + - fix bug that causes repair warnings when using a text only title reference. + +- **May.30.12**: 1.1.6 release + - data protection with passwords for sheets + - cell level input validators + - added support for two cell anchors for images + - test coverage now back up to 100% + - bugfix for merge cell sorting algorithm + - added fit_to method for page_setup to simplify managing witdh/height + - added ph (phonetics) and s (style) attributes for row. + - resolved all warnings generating from this gem. + - improved comment relationship management for multiple comments + +- **May.13.12**: 1.1.5 release - MOAR print options! You can now specify paper size, orientation, fit to width, page margings and gridlines for printing. - - Support for adding comments ot your worksheets + - Support for adding comments to your worksheets - bugfix for applying style to empty cells - - bugfix for parsing formula with multipe '=' + - bugfix for parsing formula with multiple '=' -- ** May.3.12:**: 1.1.4 release +- **May.3.12:**: 1.1.4 release - MOAR examples - added outline level for rows and columns - rebuild of numeric and axis data sources for charts @@ -159,6 +184,8 @@ Please see the {file:CHANGELOG.md} document for past release information. [scpike](https://github.com/scpike) - for keeping numbers fixed even when they are rational and a super clean implementation of conditional formatting. +[janhuehne](https://github.com/janhuehne) - for working out the decoder ring and adding in cell level validation. + #Copyright and License ---------- diff --git a/examples/basic_charts.rb b/examples/basic_charts.rb new file mode 100644 index 00000000..63cb715b --- /dev/null +++ b/examples/basic_charts.rb @@ -0,0 +1,46 @@ +$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib" +require 'axlsx' +p = Axlsx::Package.new +wb = p.workbook + +# Pie Chart +wb.add_worksheet(:name => "Pie Chart") do |sheet| + sheet.add_row ["First", "Second", "Third", "Fourth"] + sheet.add_row [1, 2, 3, 4] + sheet.add_chart(Axlsx::Pie3DChart, :start_at => [0,2], :end_at => [5, 15], :title=> 'dark corner here') do |chart| + chart.add_series :data => sheet["A2:D2"], :labels => sheet["A1:D1"] + end +end + +# line chart + wb.add_worksheet(:name => "Line Chart") do |sheet| + sheet.add_row ['1', '2', '3', '4'] + sheet.add_row [1, 2, 3, '=sum(A2:C2)'] + sheet.add_chart(Axlsx::Line3DChart, :start_at => [0,2], :end_at => [5, 15], :title => "Chart") do |chart| + chart.add_series :data => sheet["A2:D2"], :labels => sheet["A1:D1"], :title => 'bob' + end + end + +# bar chart + wb.add_worksheet(:name => "Bar Chart") do |sheet| + sheet.add_row ["A Simple Bar Chart"] + sheet.add_row ["First", "Second", "Third"] + sheet.add_row [1, 2, 3] + sheet.add_chart(Axlsx::Bar3DChart, :start_at => "A4", :end_at => "F17") do |chart| + chart.add_series :data => sheet["A3:C3"], :labels => sheet["A2:C2"], :title => sheet["A1"] + chart.valAxis.label_rotation = -45 + chart.catAxis.label_rotation = 45 + end + end + +# specifying colors and title +wb.add_worksheet(:name => "Colored Pie Chart") do |sheet| + sheet.add_row ["First", "Second", "Third", "Fourth"] + sheet.add_row [1, 2, 3, "=PRODUCT(A2:C2)"] + sheet.add_chart(Axlsx::Pie3DChart, :start_at => [0,2], :end_at => [5, 15], :title => "example 3: Pie Chart") do |chart| + chart.add_series :data => sheet["A2:D2"], :labels => ["A1:D1"], :colors => ['FF0000', '00FF00', '0000FF'] + end +end + +p.serialize('basic_charts.xlsx') + diff --git a/examples/example.rb b/examples/example.rb index 315c7146..446dd79c 100755 --- a/examples/example.rb +++ b/examples/example.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -w -s # -*- coding: utf-8 -*- -# $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib" +$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib" #```ruby require 'axlsx' diff --git a/examples/sheet_protection.rb b/examples/sheet_protection.rb index 68d1fe8d..e8d87e12 100644 --- a/examples/sheet_protection.rb +++ b/examples/sheet_protection.rb @@ -4,7 +4,6 @@ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib" require 'axlsx' p = Axlsx::Package.new -p.workbook.add_worksheet(:name => 'ECMA-376') { |ws| ws.sheet_protection.propper_password = 'fish' } p.workbook.add_worksheet(:name => 'Open Office') { |ws| ws.sheet_protection.password = 'fish' } p.serialize 'sheet_protection.xlsx' diff --git a/examples/two_cell_anchor_image.rb b/examples/two_cell_anchor_image.rb new file mode 100644 index 00000000..4fe4b566 --- /dev/null +++ b/examples/two_cell_anchor_image.rb @@ -0,0 +1,11 @@ +#!/usr/bin/env ruby -w -s +# -*- coding: utf-8 -*- +$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib" +require 'axlsx' + +p = Axlsx::Package.new +src = "#{File.dirname(__FILE__)}/image1.png" +p.workbook.add_worksheet(:name => 'double_anchor') do |ws| + ws.add_image(:image_src => src, :start_at => [0,0], :end_at => [2,4]) +end +p.serialize('two_cell_anchor_image.xlsx') diff --git a/lib/axlsx.rb b/lib/axlsx.rb index 3963f822..92c58b33 100644 --- a/lib/axlsx.rb +++ b/lib/axlsx.rb @@ -84,4 +84,11 @@ module Axlsx Axlsx::col_ref(c_index).to_s << (r_index+1).to_s end + # performs the increadible feat of changing snake_case to CamelCase + # @param [String] s The snake case string to camelize + # @return [String] + def self.camel(s="") + s = s.capitalize.gsub(/_(.)/){ $1.upcase } + end + end diff --git a/lib/axlsx/content_type/default.rb b/lib/axlsx/content_type/default.rb index c7cedd14..21e89217 100644 --- a/lib/axlsx/content_type/default.rb +++ b/lib/axlsx/content_type/default.rb @@ -5,35 +5,41 @@ module Axlsx # The extension of the content type. # @return [String] - attr_reader :Extension + attr_reader :extension + alias :Extension :extension # The type of content. # @return [String] - attr_reader :ContentType + attr_reader :content_type + alias :ContentType :content_type #Creates a new Default object - # @option options [String] Extension - # @option options [String] ContentType - # @raise [ArgumentError] An argument error is raised if both Extension and ContentType are not specified. + # @option options [String] extension + # @option options [String] content_type + # @raise [ArgumentError] An argument error is raised if both extension and content_type are not specified. def initialize(options={}) - raise ArgumentError, "Extension and ContentType are required" unless options[:Extension] && options[:ContentType] + raise ArgumentError, "extension and content_type are required" unless (options[:Extension] || options[:extension]) && (options[:content_type] || options[:ContentType]) options.each do |o| self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}=" end end + + # Sets the file extension for this content type. - def Extension=(v) Axlsx::validate_string v; @Extension = v end + def extension=(v) Axlsx::validate_string v; @extension = v end + alias :Extension= :extension= # Sets the content type # @see Axlsx#validate_content_type - def ContentType=(v) Axlsx::validate_content_type v; @ContentType = v end + def content_type=(v) Axlsx::validate_content_type v; @content_type = v end + alias :ContentType= :content_type= # Serializes the object # @param [String] str # @return [String] def to_xml_string(str = '') str << '<Default ' - str << instance_values.map { |key, value| '' << key.to_s << '="' << value.to_s << '"' }.join(' ') + str << instance_values.map { |key, value| '' << Axlsx::camel(key) << '="' << value.to_s << '"' }.join(' ') str << '/>' end diff --git a/lib/axlsx/content_type/override.rb b/lib/axlsx/content_type/override.rb index eadf8e78..d3911a6f 100644 --- a/lib/axlsx/content_type/override.rb +++ b/lib/axlsx/content_type/override.rb @@ -5,36 +5,40 @@ module Axlsx # The type of content. # @return [String] - attr_reader :ContentType + attr_reader :content_type + alias :ContentType :content_type # The name and location of the part. # @return [String] - attr_reader :PartName + attr_reader :part_name + alias :PartName :part_name #Creates a new Override object # @option options [String] PartName # @option options [String] ContentType # @raise [ArgumentError] An argument error is raised if both PartName and ContentType are not specified. def initialize(options={}) - raise ArgumentError, "PartName and ContentType are required" unless options[:PartName] && options[:ContentType] + raise ArgumentError, "PartName and ContentType are required" unless (options[:PartName] || options[:part_name]) && (options[:ContentType] || options[:content_type]) options.each do |o| self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}=" end end # The name and location of the part. - def PartName=(v) Axlsx::validate_string v; @PartName = v end + def part_name=(v) Axlsx::validate_string v; @part_name = v end + alias :PartName= :part_name= # The content type. # @see Axlsx#validate_content_type - def ContentType=(v) Axlsx::validate_content_type v; @ContentType = v end + def content_type=(v) Axlsx::validate_content_type v; @content_type = v end + alias :ContentType= :content_type= # Serializes the object # @param [String] str # @return [String] def to_xml_string(str = '') str << '<Override ' - str << instance_values.map { |key, value| '' << key.to_s << '="' << value.to_s << '"' }.join(' ') + str << instance_values.map { |key, value| '' << Axlsx::camel(key) << '="' << value.to_s << '"' }.join(' ') str << '/>' end diff --git a/lib/axlsx/doc_props/app.rb b/lib/axlsx/doc_props/app.rb index 9f8b318b..73bb6599 100644 --- a/lib/axlsx/doc_props/app.rb +++ b/lib/axlsx/doc_props/app.rb @@ -11,163 +11,216 @@ module Axlsx class App # @return [String] The name of the document template. - attr_reader :Template + attr_reader :template + alias :Template :template # @return [String] The name of the manager for the document. - attr_reader :Manager + attr_reader :manager + alias :Manager :manager # @return [String] The name of the company generating the document. - attr_reader :Company + attr_reader :company + alias :Company :company # @return [Integer] The number of pages in the document. - attr_reader :Pages + attr_reader :pages + alias :Pages :pages # @return [Integer] The number of words in the document. - attr_reader :Words + attr_reader :words + alias :Words :words # @return [Integer] The number of characters in the document. - attr_reader :Characters + attr_reader :characters + alias :Characters :characters # @return [String] The intended format of the presentation. - attr_reader :PresentationFormat + attr_reader :presentation_format + alias :PresentationFormat :presentation_format # @return [Integer] The number of lines in the document. - attr_reader :Lines + attr_reader :lines + alias :Lines :lines # @return [Integer] The number of paragraphs in the document - attr_reader :Paragraphs + attr_reader :paragraphs + alias :Paragraphs :paragraphs # @return [Intger] The number of slides in the document. - attr_reader :Slides + attr_reader :slides + alias :Slides :slides # @return [Integer] The number of slides that have notes. - attr_reader :Notes + attr_reader :notes + alias :Notes :notes # @return [Integer] The total amount of time spent editing. - attr_reader :TotalTime + attr_reader :total_time + alias :TotalTime :total_time # @return [Integer] The number of hidden slides. - attr_reader :HiddenSlides + attr_reader :hidden_slides + alias :HiddenSlides :hidden_slides # @return [Integer] The total number multimedia clips - attr_reader :MMClips + attr_reader :m_m_clips + alias :MMClips :m_m_clips # @return [Boolean] The display mode for the document thumbnail. - attr_reader :ScaleCrop + attr_reader :scale_crop + alias :ScaleCrop :scale_crop # @return [Boolean] The links in the document are up to date. - attr_reader :LinksUpToDate + attr_reader :links_up_to_date + alias :LinksUpToDate :links_up_to_date # @return [Integer] The number of characters in the document including spaces. - attr_reader :CharactersWithSpaces + attr_reader :characters_with_spaces + alias :CharactersWithSpaces :characters_with_spaces # @return [Boolean] Indicates if the document is shared. - attr_reader :SharedDoc + attr_reader :shared_doc + alias :SharedDoc :shared_doc # @return [String] The base for hyper links in the document. - attr_reader :HyperlinkBase + attr_reader :hyperlink_base + alias :HyperlinkBase :hyperlink_base # @return [Boolean] Indicates that the hyper links in the document have been changed. - attr_reader :HyperlinksChanged - + attr_reader :hyperlinks_changed + alias :HyperlinksChanged :hyperlinks_changed + # @return [String] The name of the application - attr_reader :Application + attr_reader :application + alias :Applicatoin :application # @return [String] The version of the application. - attr_reader :AppVersion + attr_reader :app_version + alias :AppVersion :app_version # @return [Integer] Document security - attr_reader :DocSecurity + attr_reader :doc_security + alias :DocSecurity :doc_security # Creates an App object - # @option options [String] Template - # @option options [String] Manager - # @option options [Integer] Pages - # @option options [Integer] Words - # @option options [Integer] Characters - # @option options [String] PresentationFormat - # @option options [Integer] Lines - # @option options [Integer] Paragraphs - # @option options [Integer] Slides - # @option options [Integer] Notes - # @option options [Integer] TotalTime - # @option options [Integer] HiddenSlides - # @option options [Integer] MMClips - # @option options [Boolean] ScaleCrop - # @option options [Boolean] LinksUpToDate - # @option options [Integer] CharactersWithSpaces - # @option options [Boolean] ShareDoc - # @option options [String] HyperLinkBase - # @option options [String] HyperlinksChanged - # @option options [String] Application - # @option options [String] AppVersion - # @option options [Integer] DocSecurity + # @option options [String] template + # @option options [String] manager + # @option options [Integer] pages + # @option options [Integer] words + # @option options [Integer] characters + # @option options [String] presentation_format + # @option options [Integer] lines + # @option options [Integer] paragraphs + # @option options [Integer] slides + # @option options [Integer] notes + # @option options [Integer] total_time + # @option options [Integer] hidden_slides + # @option options [Integer] m_m_clips + # @option options [Boolean] scale_crop + # @option options [Boolean] links_up_to_date + # @option options [Integer] characters_with_spaces + # @option options [Boolean] share_doc + # @option options [String] hyperlink_base + # @option options [String] hyperlinks_changed + # @option options [String] application + # @option options [String] app_version + # @option options [Integer] doc_security def initialize(options={}) options.each do |o| self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}=" end end - # Sets the Template property of your app.xml file - def Template=(v) Axlsx::validate_string v; @Template = v; end - - # Sets the Manager property of your app.xml file - def Manager=(v) Axlsx::validate_string v; @Manager = v; end - - # Sets the Company property of your app.xml file - def Company=(v) Axlsx::validate_string v; @Company = v; end - - # Sets the Pages property of your app.xml file - def Pages=(v) Axlsx::validate_int v; @Pages = v; end - - # Sets the Words property of your app.xml file - def Words=(v) Axlsx::validate_int v; @Words = v; end - - # Sets the Characters property of your app.xml file - def Characters=(v) Axlsx::validate_int v; @Characters = v; end - - - # Sets the PresentationFormat property of your app.xml file - def PresentationFormat=(v) Axlsx::validate_string v; @PresentationFormat = v; end - # Sets the Lines property of your app.xml file - def Lines=(v) Axlsx::validate_int v; @Lines = v; end - # Sets the Paragraphs property of your app.xml file - def Paragraphs=(v) Axlsx::validate_int v; @Paragraphs = v; end - # Sets the Slides property of your app.xml file - def Slides=(v) Axlsx::validate_int v; @Slides = v; end - # Sets the Notes property of your app.xml file - def Notes=(v) Axlsx::validate_int v; @Notes = v; end - # Sets the TotalTime property of your app.xml file - def TotalTime=(v) Axlsx::validate_int v; @TotalTime = v; end - # Sets the HiddenSlides property of your app.xml file - def HiddenSlides=(v) Axlsx::validate_int v; @HiddenSlides = v; end - # Sets the MMClips property of your app.xml file - def MMClips=(v) Axlsx::validate_int v; @MMClips = v; end - # Sets the ScaleCrop property of your app.xml file - def ScaleCrop=(v) Axlsx::validate_boolean v; @ScaleCrop = v; end - # Sets the LinksUpToDate property of your app.xml file - def LinksUpToDate=(v) Axlsx::validate_boolean v; @LinksUpToDate = v; end - # Sets the CharactersWithSpaces property of your app.xml file - def CharactersWithSpaces=(v) Axlsx::validate_int v; @CharactersWithSpaces = v; end - # Sets the ShareDoc property of your app.xml file - def ShareDoc=(v) Axlsx::validate_boolean v; @ShareDoc = v; end - # Sets the HyperLinkBase property of your app.xml file - def HyperLinkBase=(v) Axlsx::validate_string v; @HyperLinkBase = v; end + # Sets the template property of your app.xml file + def template=(v) Axlsx::validate_string v; @template = v; end + + # Sets the manager property of your app.xml file + def manager=(v) Axlsx::validate_string v; @manager = v; end + + # Sets the company property of your app.xml file + def company=(v) Axlsx::validate_string v; @company = v; end + + # Sets the pages property of your app.xml file + def pages=(v) Axlsx::validate_int v; @pages = v; end + + # Sets the words property of your app.xml file + def words=(v) Axlsx::validate_int v; @words = v; end + alias :Words= :words= + + # Sets the characters property of your app.xml file + def characters=(v) Axlsx::validate_int v; @characters = v; end + alias :Characters= :characters= + + # Sets the presentation_format property of your app.xml file + def presentation_format=(v) Axlsx::validate_string v; @presentation_format = v; end + alias :PresentationFormat= :presentation_format= + + # Sets the lines property of your app.xml file + def lines=(v) Axlsx::validate_int v; @lines = v; end + alias :Lines= :lines= + + # Sets the paragraphs property of your app.xml file + def paragraphs=(v) Axlsx::validate_int v; @paragraphs = v; end + alias :Paragraphs= :paragraphs= + + # sets the slides property of your app.xml file + def slides=(v) Axlsx::validate_int v; @slides = v; end + alias :Slides= :slides= + + # sets the notes property of your app.xml file + def notes=(v) Axlsx::validate_int v; @notes = v; end + alias :Notes= :notes= + + # Sets the total_time property of your app.xml file + def total_time=(v) Axlsx::validate_int v; @total_time = v; end + alias :TotalTime= :total_time= + + # Sets the hidden_slides property of your app.xml file + def hidden_slides=(v) Axlsx::validate_int v; @hidden_slides = v; end + alias :HiddenSlides= :hidden_slides= + + # Sets the m_m_clips property of your app.xml file + def m_m_clips=(v) Axlsx::validate_int v; @m_m_clips = v; end + alias :MMClips= :m_m_clips= + + # Sets the scale_crop property of your app.xml file + def scale_crop=(v) Axlsx::validate_boolean v; @scale_crop = v; end + alias :ScaleCrop= :scale_crop= + + # Sets the links_up_to_date property of your app.xml file + def links_up_to_date=(v) Axlsx::validate_boolean v; @links_up_to_date = v; end + alias :LinksUpToDate= :links_up_to_date= + + # Sets the characters_with_spaces property of your app.xml file + def characters_with_spaces=(v) Axlsx::validate_int v; @characters_with_spaces = v; end + alias :CharactersWithSpaces= :characters_with_spaces= + + # Sets the share_doc property of your app.xml file + def shared_doc=(v) Axlsx::validate_boolean v; @shared_doc = v; end + alias :SharedDoc= :shared_doc= + + # Sets the hyperlink_base property of your app.xml file + def hyperlink_base=(v) Axlsx::validate_string v; @hyperlink_base = v; end + alias :HyperlinkBase= :hyperlink_base= + # Sets the HyperLinksChanged property of your app.xml file - def HyperlinksChanged=(v) Axlsx::validate_boolean v; @HyperlinksChanged = v; end - # Sets the Application property of your app.xml file - def Application=(v) Axlsx::validate_string v; @Application = v; end - # Sets the AppVersion property of your app.xml file - def AppVersion=(v) Axlsx::validate_string v; @AppVersion = v; end - # Sets the DocSecurity property of your app.xml file - def DocSecurity=(v) Axlsx::validate_int v; @DocSecurity = v; end + def hyperlinks_changed=(v) Axlsx::validate_boolean v; @hyperlinks_changed = v; end + alias :HyperLinksChanged= :hyperlinks_changed= + + # Sets the app_version property of your app.xml file + def app_version=(v) Axlsx::validate_string v; @app_version = v; end + alias :AppVersion= :app_version= + # Sets the doc_security property of your app.xml file + def doc_security=(v) Axlsx::validate_int v; @doc_security = v; end + alias :DocSecurity= :doc_security= + # Serialize the app.xml document # @return [String] def to_xml_string(str = '') str << '<?xml version="1.0" encoding="UTF-8"?>' str << '<Properties xmlns="' << APP_NS << '" xmlns:vt="' << APP_NS_VT << '">' - str << instance_values.map { |key, value| '<' << key.to_s << '>' << value.to_s << '</' << key.to_s << '>' }.join + str << instance_values.map { |key, value| '<' << Axlsx.camel(key) << '>' << value.to_s << '</' << Axlsx.camel(key) << '>' }.join str << '</Properties>' end diff --git a/lib/axlsx/drawing/axis.rb b/lib/axlsx/drawing/axis.rb index 1cc23448..84713943 100644 --- a/lib/axlsx/drawing/axis.rb +++ b/lib/axlsx/drawing/axis.rb @@ -5,11 +5,13 @@ module Axlsx # the id of the axis. # @return [Integer] - attr_reader :axId + attr_reader :ax_id + alias :axID :ax_id # The perpendicular axis # @return [Integer] - attr_reader :crossAx + attr_reader :cross_ax + alias :crossAx :cross_ax # The scaling of the axis # @see Scaling @@ -19,12 +21,14 @@ module Axlsx # The position of the axis # must be one of [:l, :r, :t, :b] # @return [Symbol] - attr_reader :axPos + attr_reader :ax_pos + alias :axPos :ax_pos # the position of the tick labels # must be one of [:nextTo, :high, :low] # @return [Symbol] - attr_reader :tickLblPos + attr_reader :tick_lbl_pos + alias :tickLblPos :tick_lbl_pos # The number format format code for this axis # default :General @@ -49,22 +53,22 @@ module Axlsx attr_reader :delete # Creates an Axis object - # @param [Integer] axId the id of this axis - # @param [Integer] crossAx the id of the perpendicular axis - # @option options [Symbol] axPos + # @param [Integer] ax_id the id of this axis + # @param [Integer] cross_ax the id of the perpendicular axis + # @option options [Symbol] ax_pos # @option options [Symbol] crosses - # @option options [Symbol] tickLblPos - # @raise [ArgumentError] If axId or crossAx are not unsigned integers - def initialize(axId, crossAx, options={}) - Axlsx::validate_unsigned_int(axId) - Axlsx::validate_unsigned_int(crossAx) - @axId = axId - @crossAx = crossAx + # @option options [Symbol] tick_lbl_pos + # @raise [ArgumentError] If axi_id or cross_ax are not unsigned integers + def initialize(ax_id, cross_ax, options={}) + Axlsx::validate_unsigned_int(ax_id) + Axlsx::validate_unsigned_int(cross_ax) + @ax_id = ax_id + @cross_ax = cross_ax @format_code = "General" @delete = @label_rotation = 0 @scaling = Scaling.new(:orientation=>:minMax) - self.axPos = :b - self.tickLblPos = :nextTo + self.ax_pos = :b + self.tick_lbl_pos = :nextTo self.format_code = "General" self.crosses = :autoZero self.gridlines = true @@ -72,13 +76,16 @@ module Axlsx self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}=" end end + # The position of the axis # must be one of [:l, :r, :t, :b] - def axPos=(v) RestrictionValidator.validate "#{self.class}.axPos", [:l, :r, :b, :t], v; @axPos = v; end + def ax_pos=(v) RestrictionValidator.validate "#{self.class}.ax_pos", [:l, :r, :b, :t], v; @ax_pos = v; end + alias :axPos= :ax_pos= # the position of the tick labels # must be one of [:nextTo, :high, :low1] - def tickLblPos=(v) RestrictionValidator.validate "#{self.class}.tickLblPos", [:nextTo, :high, :low], v; @tickLblPos = v; end + def tick_lbl_pos=(v) RestrictionValidator.validate "#{self.class}.tick_lbl_pos", [:nextTo, :high, :low], v; @tick_lbl_pos = v; end + alias :tickLblPos= :tick_lbl_pos= # The number format format code for this axis # default :General @@ -111,10 +118,10 @@ module Axlsx # @param [String] str # @return [String] def to_xml_string(str = '') - str << '<c:axId val="' << @axId.to_s << '"/>' + str << '<c:axId val="' << @ax_id.to_s << '"/>' @scaling.to_xml_string str str << '<c:delete val="'<< @delete.to_s << '"/>' - str << '<c:axPos val="' << @axPos.to_s << '"/>' + str << '<c:axPos val="' << @ax_pos.to_s << '"/>' str << '<c:majorGridlines>' if gridlines == false str << '<c:spPr>' @@ -127,10 +134,10 @@ module Axlsx str << '<c:numFmt formatCode="' << @format_code << '" sourceLinked="1"/>' str << '<c:majorTickMark val="none"/>' str << '<c:minorTickMark val="none"/>' - str << '<c:tickLblPos val="' << @tickLblPos.to_s << '"/>' + str << '<c:tickLblPos val="' << @tick_lbl_pos.to_s << '"/>' # some potential value in implementing this in full. Very detailed! str << '<c:txPr><a:bodyPr rot="' << @label_rotation.to_s << '"/><a:lstStyle/><a:p><a:pPr><a:defRPr/></a:pPr><a:endParaRPr/></a:p></c:txPr>' - str << '<c:crossAx val="' << @crossAx.to_s << '"/>' + str << '<c:crossAx val="' << @cross_ax.to_s << '"/>' str << '<c:crosses val="' << @crosses.to_s << '"/>' end diff --git a/lib/axlsx/drawing/bar_series.rb b/lib/axlsx/drawing/bar_series.rb index 5863dacc..182f94c5 100644 --- a/lib/axlsx/drawing/bar_series.rb +++ b/lib/axlsx/drawing/bar_series.rb @@ -42,7 +42,7 @@ module Axlsx def colors=(v) DataTypeValidator.validate "BarSeries.colors", [Array], v; @colors = v end # The shabe of the bars or columns - # must be one of [:percentStacked, :clustered, :standard, :stacked] + # must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax] def shape=(v) RestrictionValidator.validate "BarSeries.shape", [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax], v @shape = v diff --git a/lib/axlsx/drawing/cat_axis.rb b/lib/axlsx/drawing/cat_axis.rb index 6def7349..2e200bda 100644 --- a/lib/axlsx/drawing/cat_axis.rb +++ b/lib/axlsx/drawing/cat_axis.rb @@ -28,7 +28,7 @@ module Axlsx # regex for validating label offset - LBL_OFFSET_REGEX = /0*(([0-9])|([1-9][0-9])|([1-9][0-9][0-9])|1000)%/ + LBL_OFFSET_REGEX = /0*(([0-9])|([1-9][0-9])|([1-9][0-9][0-9])|1000)/ # Creates a new CatAxis object # @param [Integer] axId the id of this axis. Inherited @@ -46,7 +46,7 @@ module Axlsx @tickMarkSkip = 1 self.auto = 1 self.lblAlgn = :ctr - self.lblOffset = "100%" + self.lblOffset = "100" super(axId, crossAx, options) end @@ -77,7 +77,7 @@ module Axlsx super(str) str << '<c:auto val="' << @auto.to_s << '"/>' str << '<c:lblAlgn val="' << @lblAlgn.to_s << '"/>' - str << '<c:lblOffset val="' << @lblOffset.to_s << '"/>' + str << '<c:lblOffset val="' << @lblOffset.to_i.to_s << '"/>' str << '<c:tickLblSkip val="' << @tickLblSkip.to_s << '"/>' str << '<c:tickMarkSkip val="' << @tickMarkSkip.to_s << '"/>' str << '</c:catAx>' diff --git a/lib/axlsx/drawing/chart.rb b/lib/axlsx/drawing/chart.rb index 0f26c551..f0f0185b 100644 --- a/lib/axlsx/drawing/chart.rb +++ b/lib/axlsx/drawing/chart.rb @@ -44,7 +44,7 @@ module Axlsx # @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={}) - @style = 2 + @style = 18 @view3D = nil @graphic_frame=frame @graphic_frame.anchor.drawing.worksheet.workbook.charts << self @@ -120,13 +120,13 @@ module Axlsx # @return [String] def to_xml_string(str = '') str << '<?xml version="1.0" encoding="UTF-8"?>' - str << '<c:chartSpace xmlns:c="' << XML_NS_C << '" xmlns:a="' << XML_NS_A << '">' + str << '<c:chartSpace xmlns:c="' << XML_NS_C << '" xmlns:a="' << XML_NS_A << '" xmlns:r="' << XML_NS_R << '">' str << '<c:date1904 val="' << Axlsx::Workbook.date1904.to_s << '"/>' str << '<c:style val="' << style.to_s << '"/>' str << '<c:chart>' @title.to_xml_string str # do these need the c: namespace as well??? - str << '<c:autoTitleDeleted val="0"/>' + str << '<c:autoTitleDeleted val="' << (@title == nil).to_s << '"/>' @view3D.to_xml_string(str) if @view3D str << '<c:floor><c:thickness val="0"/></c:floor>' str << '<c:sideWall><c:thickness val="0"/></c:sideWall>' diff --git a/lib/axlsx/drawing/drawing.rb b/lib/axlsx/drawing/drawing.rb index 943c0f2d..1553809a 100644 --- a/lib/axlsx/drawing/drawing.rb +++ b/lib/axlsx/drawing/drawing.rb @@ -68,11 +68,16 @@ module Axlsx @anchors = SimpleTypedList.new [TwoCellAnchor, OneCellAnchor] end - # Adds an image to the chart + # Adds an image to the chart If th end_at option is specified we create a two cell anchor. By default we use a one cell anchor. # @note The recommended way to manage images is to use Worksheet.add_image. Please refer to that method for documentation. # @see Worksheet#add_image + # @return [Pic] def add_image(options={}) - OneCellAnchor.new(self, options) + if options[:end_at] + TwoCellAnchor.new(self, options).add_pic(options) + else + OneCellAnchor.new(self, options) + end @anchors.last.object end @@ -150,7 +155,6 @@ module Axlsx # @return [String] def to_xml_string(str = '') str << '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' -# str << '<xdr:wsDr xmlns:xdr="' << XML_NS_XDR << '" xmlns:a="' << XML_NS_A << '" xmlns:c="' << XML_NS_C << '">' str << '<xdr:wsDr xmlns:xdr="' << XML_NS_XDR << '" xmlns:a="' << XML_NS_A << '">' anchors.each { |anchor| anchor.to_xml_string(str) } diff --git a/lib/axlsx/drawing/graphic_frame.rb b/lib/axlsx/drawing/graphic_frame.rb index fd65aa19..a829e5ea 100644 --- a/lib/axlsx/drawing/graphic_frame.rb +++ b/lib/axlsx/drawing/graphic_frame.rb @@ -33,9 +33,9 @@ module Axlsx # @return [String] def to_xml_string(str = '') # macro attribute should be optional! - str << '<xdr:graphicFrame macro="">' + str << '<xdr:graphicFrame>' str << '<xdr:nvGraphicFramePr>' - str << '<xdr:cNvPr id="2" name="' << chart.title.text << '"/>' + str << '<xdr:cNvPr id="' << @anchor.drawing.index.to_s << '" name="' << 'item_' << @anchor.drawing.index.to_s << '"/>' str << '<xdr:cNvGraphicFramePr/>' str << '</xdr:nvGraphicFramePr>' str << '<xdr:xfrm>' diff --git a/lib/axlsx/drawing/num_data.rb b/lib/axlsx/drawing/num_data.rb index 802a0216..ee6b145e 100644 --- a/lib/axlsx/drawing/num_data.rb +++ b/lib/axlsx/drawing/num_data.rb @@ -25,8 +25,8 @@ module Axlsx def data=(values=[]) @tag_name = values.first.is_a?(Cell) ? :numCache : :numLit values.each do |value| - v = value.is_a?(Cell) ? value.value : value - @pt << NumVal.new(:v => v) + value = value.is_formula? ? 0 : value.value if value.is_a?(Cell) + @pt << NumVal.new(:v => value) end end diff --git a/lib/axlsx/drawing/pic.rb b/lib/axlsx/drawing/pic.rb index e5e005fa..3eb99e7d 100644 --- a/lib/axlsx/drawing/pic.rb +++ b/lib/axlsx/drawing/pic.rb @@ -90,8 +90,7 @@ module Axlsx # @return [String] def extname File.extname(image_src).delete('.') unless image_src.nil? - end - + end # The index of this image in the workbooks images collections # @return [Index] def index @@ -113,27 +112,32 @@ module Axlsx # @param [Integer] v # @see OneCellAnchor.width def width + return unless @anchor.is_a?(OneCellAnchor) @anchor.width end # @see width def width=(v) + use_one_cell_anchor unless @anchor.is_a?(OneCellAnchor) @anchor.width = v end # providing access to update the anchor's height attribute # @param [Integer] v # @see OneCellAnchor.width + # @note this is a noop if you are using a TwoCellAnchor def height @anchor.height end # @see height + # @note This is a noop if you are using a TwoCellAnchor def height=(v) + use_one_cell_anchor unless @anchor.is_a?(OneCellAnchor) @anchor.height = v end - - # This is a short cut method to set the start anchor position + + # This is a short cut method to set the start anchor position # If you need finer granularity in positioning use # graphic_frame.anchor.from.colOff / rowOff # @param [Integer] x The column @@ -142,6 +146,18 @@ module Axlsx def start_at(x, y) @anchor.from.col = x @anchor.from.row = y + @anchor.from + end + + # noop if not using a two cell anchor + # @param [Integer] x The column + # @param [Integer] y The row + # @return [Marker] + def end_at(x, y) + use_two_cell_anchor unless @anchor.is_a?(TwoCellAnchor) + @anchor.to.col = x + @anchor.to.row = y + @anchor.to end # Serializes the object @@ -162,6 +178,30 @@ module Axlsx str << '<a:prstGeom prst="rect"><a:avLst/></a:prstGeom></xdr:spPr></xdr:pic>' end + + private + + # Changes the anchor to a one cell anchor. + def use_one_cell_anchor + return if @anchor.is_a?(OneCellAnchor) + swap_anchor(OneCellAnchor.new(@anchor.drawing, :from => @anchor.from)) + end + + #changes the anchor type to a two cell anchor + def use_two_cell_anchor + return if @anchor.is_a?(TwoCellAnchor) + swap_anchor(TwoCellAnchor.new(@anchor.drawing)).tap do |new_anchor| + new_anchor.from.col = @anchor.from.col + new_anchor.from.row = @anchor.from.row + end + end + + # refactoring of swapping code, law of demeter be damned! + def swap_anchor(new_anchor) + new_anchor.drawing.anchors.delete(new_anchor) + @anchor.drawing.anchors[@anchor.drawing.anchors.index(@anchor)] = new_anchor + @anchor = new_anchor + end end end diff --git a/lib/axlsx/drawing/title.rb b/lib/axlsx/drawing/title.rb index a85d8e11..5292a177 100644 --- a/lib/axlsx/drawing/title.rb +++ b/lib/axlsx/drawing/title.rb @@ -46,15 +46,27 @@ module Axlsx str << '<c:title>' unless @text.empty? str << '<c:tx>' - str << '<c:strRef>' - str << '<c:f>' << Axlsx::cell_range([@cell]) << '</c:f>' - str << '<c:strCache>' - str << '<c:ptCount val="1"/>' - str << '<c:pt idx="0">' - str << '<c:v>' << @text << '</c:v>' - str << '</c:pt>' - str << '</c:strCache>' - str << '</c:strRef>' + if @cell.is_a?(Cell) + str << '<c:strRef>' + str << '<c:f>' << Axlsx::cell_range([@cell]) << '</c:f>' + str << '<c:strCache>' + str << '<c:ptCount val="1"/>' + str << '<c:pt idx="0">' + str << '<c:v>' << @text << '</c:v>' + str << '</c:pt>' + str << '</c:strCache>' + str << '</c:strRef>' + else + str << '<c:rich>' + str << '<a:bodyPr/>' + str << '<a:lstStyle/>' + str << '<a:p>' + str << '<a:r>' + str << '<a:t>' << @text.to_s << '</a:t>' + str << '</a:r>' + str << '</a:p>' + str << '</c:rich>' + end str << '</c:tx>' end str << '<c:layout/>' diff --git a/lib/axlsx/drawing/two_cell_anchor.rb b/lib/axlsx/drawing/two_cell_anchor.rb index b496bd8a..8071515c 100644 --- a/lib/axlsx/drawing/two_cell_anchor.rb +++ b/lib/axlsx/drawing/two_cell_anchor.rb @@ -34,7 +34,7 @@ module Axlsx # @param [Drawing] drawing # @param [Class] chart_type This is passed to the graphic frame for instantiation. must be Chart or a subclass of Chart # @param object The object this anchor holds. - # @option options [Array] start_at the col, row to start at + # @option options [Array] start_at the col, row to start at THIS IS DOCUMENTED BUT NOT IMPLEMENTED HERE! # @option options [Array] end_at the col, row to end at def initialize(drawing, options={}) @drawing = drawing @@ -49,6 +49,11 @@ module Axlsx @object.chart end + # Creates an image associated with this anchor. + def add_pic(options={}) + @object = Pic.new(self, options) + end + # The index of this anchor in the drawing # @return [Integer] def index diff --git a/lib/axlsx/version.rb b/lib/axlsx/version.rb index 740038de..d33616ba 100644 --- a/lib/axlsx/version.rb +++ b/lib/axlsx/version.rb @@ -5,6 +5,6 @@ module Axlsx # When using bunle exec rake and referencing the gem on github or locally # it will use the gemspec, which preloads this constant for the gem's version. # We check to make sure that it has not already been loaded - VERSION="1.1.5" unless defined? Axlsx::VERSION + VERSION="1.1.7" unless defined? Axlsx::VERSION end diff --git a/lib/axlsx/workbook/worksheet/cell.rb b/lib/axlsx/workbook/worksheet/cell.rb index 745809f9..4453529b 100644 --- a/lib/axlsx/workbook/worksheet/cell.rb +++ b/lib/axlsx/workbook/worksheet/cell.rb @@ -317,6 +317,10 @@ module Axlsx str << '</c>' end + def is_formula? + @type == :string && @value.start_with?('=') + end + private # Utility method for setting inline style attributes diff --git a/lib/axlsx/workbook/worksheet/data_validation.rb b/lib/axlsx/workbook/worksheet/data_validation.rb index 8eca9375..e790bc77 100644 --- a/lib/axlsx/workbook/worksheet/data_validation.rb +++ b/lib/axlsx/workbook/worksheet/data_validation.rb @@ -13,14 +13,14 @@ module Axlsx # Available for type whole, decimal, date, time, textLength, list, custom # @see type # @return [String] - # @default nil + # default nil attr_reader :formula1 # Formula2 # Available for type whole, decimal, date, time, textLength # @see type # @return [String] - # @default nil + # default nil attr_reader :formula2 # Allow Blank @@ -29,7 +29,7 @@ module Axlsx # Available for type whole, decimal, date, time, textLength, list, custom # @see type # @return [Boolean] - # @default true + # default true attr_reader :allowBlank # Error Message @@ -37,7 +37,7 @@ module Axlsx # Available for type whole, decimal, date, time, textLength, list, custom # @see type # @return [String] - # @default nil + # default nil attr_reader :error # Error Style (ST_DataValidationErrorStyle) @@ -49,7 +49,7 @@ module Axlsx # Available for type whole, decimal, date, time, textLength, list, custom # @see type # @return [Symbol] - # @default :stop + # default :stop attr_reader :errorStyle # Error Title @@ -57,7 +57,7 @@ module Axlsx # Available for type whole, decimal, date, time, textLength, list, custom # @see type # @return [String] - # @default nil + # default nil attr_reader :errorTitle # Operator (ST_DataValidationOperator) @@ -74,7 +74,7 @@ module Axlsx # Available for type whole, decimal, date, time, textLength # @see type # @return [Symbol] - # @default nil + # default nil attr_reader :operator # Input prompt @@ -82,7 +82,7 @@ module Axlsx # Available for type whole, decimal, date, time, textLength, list, custom # @see type # @return [String] - # @default nil + # default nil attr_reader :prompt # Prompt title @@ -90,7 +90,7 @@ module Axlsx # Available for type whole, decimal, date, time, textLength, list, custom # @see type # @return [String] - # @default nil + # default nil attr_reader :promptTitle # Show drop down @@ -99,7 +99,7 @@ module Axlsx # Available for type list # @see type # @return [Boolean] - # @default false + # default false attr_reader :showDropDown # Show error message @@ -108,7 +108,7 @@ module Axlsx # Available for type whole, decimal, date, time, textLength, list, custom # @see type # @return [Boolean] - # @default false + # default false attr_reader :showErrorMessage # Show input message @@ -116,14 +116,14 @@ module Axlsx # Available for type whole, decimal, date, time, textLength, list, custom # @see type # @return [Boolean] - # @default false + # default false attr_reader :showInputMessage # Range over which data validation is applied, in "A1:B2" format # Available for type whole, decimal, date, time, textLength, list, custom # @see type # @return [String] - # @default nil + # default nil attr_reader :sqref # The type (ST_DataValidationType) of data validation. @@ -137,7 +137,7 @@ module Axlsx # * time: Data validation which checks for time values satisfying the given condition. # * whole: Data validation which checks for whole number values satisfying the given condition. # @return [Symbol] - # @default none + # default none attr_reader :type # Creates a new {DataValidation} object @@ -242,4 +242,4 @@ module Axlsx attributes.flatten! end end -end
\ No newline at end of file +end diff --git a/lib/axlsx/workbook/worksheet/sheet_protection.rb b/lib/axlsx/workbook/worksheet/sheet_protection.rb index d8855008..104be53b 100644 --- a/lib/axlsx/workbook/worksheet/sheet_protection.rb +++ b/lib/axlsx/workbook/worksheet/sheet_protection.rb @@ -7,67 +7,67 @@ module Axlsx # If 1 or true then AutoFilters should not be allowed to operate when the sheet is protected. # If 0 or false then AutoFilters should be allowed to operate when the sheet is protected. # @return [Boolean] - # @default true + # default true attr_reader :auto_filter # If 1 or true then deleting columns should not be allowed when the sheet is protected. # If 0 or false then deleting columns should be allowed when the sheet is protected. # @return [Boolean] - # @default true + # default true attr_reader :delete_columns # If 1 or true then deleting rows should not be allowed when the sheet is protected. # If 0 or false then deleting rows should be allowed when the sheet is protected. # @return [Boolean] - # @default true + # default true attr_reader :delete_rows # If 1 or true then formatting cells should not be allowed when the sheet is protected. # If 0 or false then formatting cells should be allowed when the sheet is protected. # @return [Boolean] - # @default true + # default true attr_reader :format_cells # If 1 or true then formatting columns should not be allowed when the sheet is protected. # If 0 or false then formatting columns should be allowed when the sheet is protected. # @return [Boolean] - # @default true + # default true attr_reader :format_columns # If 1 or true then formatting rows should not be allowed when the sheet is protected. # If 0 or false then formatting rows should be allowed when the sheet is protected. # @return [Boolean] - # @default true + # default true attr_reader :format_rows # If 1 or true then inserting columns should not be allowed when the sheet is protected. # If 0 or false then inserting columns should be allowed when the sheet is protected. # @return [Boolean] - # @default true + # default true attr_reader :insert_columns # If 1 or true then inserting hyperlinks should not be allowed when the sheet is protected. # If 0 or false then inserting hyperlinks should be allowed when the sheet is protected. # @return [Boolean] - # @default true + # default true attr_reader :insert_hyperlinks # If 1 or true then inserting rows should not be allowed when the sheet is protected. # If 0 or false then inserting rows should be allowed when the sheet is protected. # @return [Boolean] - # @default true + # default true attr_reader :insert_rows # If 1 or true then editing of objects should not be allowed when the sheet is protected. # If 0 or false then objects are allowed to be edited when the sheet is protected. # @return [Boolean] - # @default false + # default false attr_reader :objects # If 1 or true then PivotTables should not be allowed to operate when the sheet is protected. # If 0 or false then PivotTables should be allowed to operate when the sheet is protected. # @return [Boolean] - # @default true + # default true attr_reader :pivot_tables # Specifies the salt which was prepended to the user-supplied password before it was hashed using the hashing algorithm @@ -77,36 +77,36 @@ module Axlsx # If 1 or true then Scenarios should not be edited when the sheet is protected. # If 0 or false then Scenarios are allowed to be edited when the sheet is protected. # @return [Boolean] - # @default false + # default false attr_reader :scenarios # If 1 or true then selection of locked cells should not be allowed when the sheet is protected. # If 0 or false then selection of locked cells should be allowed when the sheet is protected. # @return [Boolean] - # @default false + # default false attr_reader :select_locked_cells # If 1 or true then selection of unlocked cells should not be allowed when the sheet is protected. # If 0 or false then selection of unlocked cells should be allowed when the sheet is protected. # @return [Boolean] - # @default false + # default false attr_reader :select_unlocked_cells # If 1 or true then the sheet is protected. # If 0 or false then the sheet is not protected. # @return [Boolean] - # @default true + # default true attr_reader :sheet # If 1 or true then sorting should not be allowed when the sheet is protected. # If 0 or false then sorting should be allowed when the sheet is protected. # @return [Boolean] - # @default true + # default true attr_reader :sort # Password hash # @return [String] - # @default nil + # default nil attr_reader :password # Creates a new SheetProtection instance diff --git a/lib/axlsx/workbook/worksheet/worksheet.rb b/lib/axlsx/workbook/worksheet/worksheet.rb index be814207..741e38b1 100644 --- a/lib/axlsx/workbook/worksheet/worksheet.rb +++ b/lib/axlsx/workbook/worksheet/worksheet.rb @@ -220,11 +220,9 @@ module Axlsx # Add data validation to this worksheet. # - # @param - # @example - # - # @see - # @see + # @param [String] cells The cells the validation will apply to. + # @param [hash] data_validation options defining the validation to apply. + # @see examples/data_validation.rb for an example def add_data_validation(cells, data_validation) dv = DataValidation.new(data_validation) dv.sqref = cells diff --git a/test/drawing/tc_cat_axis.rb b/test/drawing/tc_cat_axis.rb index a4f25a1c..6529b45d 100644 --- a/test/drawing/tc_cat_axis.rb +++ b/test/drawing/tc_cat_axis.rb @@ -10,7 +10,7 @@ class TestCatAxis < Test::Unit::TestCase def test_initialization assert_equal(@axis.auto, 1, "axis auto default incorrect") assert_equal(@axis.lblAlgn, :ctr, "label align default incorrect") - assert_equal(@axis.lblOffset, "100%", "label offset default incorrect") + assert_equal(@axis.lblOffset, "100", "label offset default incorrect") end def test_auto @@ -24,8 +24,8 @@ class TestCatAxis < Test::Unit::TestCase end def test_lblOffset - assert_raise(ArgumentError, "requires valid label offset") { @axis.lblOffset = 100 } - assert_nothing_raised("accepts valid label offset") { @axis.lblOffset = "20%" } + assert_raise(ArgumentError, "requires valid label offset") { @axis.lblOffset = 'foo' } + assert_nothing_raised("accepts valid label offset") { @axis.lblOffset = "20" } end end diff --git a/test/drawing/tc_drawing.rb b/test/drawing/tc_drawing.rb index ce77ef9b..4d213d56 100644 --- a/test/drawing/tc_drawing.rb +++ b/test/drawing/tc_drawing.rb @@ -32,7 +32,12 @@ class TestDrawing < Test::Unit::TestCase assert_equal(600, image.width) assert_equal(400, image.height) end - + def test_add_two_cell_anchor_image + src = File.dirname(__FILE__) + "/../../examples/image1.jpeg" + image = @ws.add_image(:image_src => src, :start_at=>[0,0], :end_at => [15,0]) + assert(@ws.drawing.anchors.last.is_a?(Axlsx::TwoCellAnchor)) + assert(image.is_a?(Axlsx::Pic)) + end def test_charts assert(@ws.drawing.charts.empty?) chart = @ws.add_chart(Axlsx::Pie3DChart, :title=>"bob", :start_at=>[0,0], :end_at=>[1,1]) diff --git a/test/drawing/tc_num_data.rb b/test/drawing/tc_num_data.rb index 85bf5614..2549af4d 100644 --- a/test/drawing/tc_num_data.rb +++ b/test/drawing/tc_num_data.rb @@ -9,7 +9,11 @@ class TestNumData < Test::Unit::TestCase def test_initialize assert_equal(@num_data.format_code, "General") end - + + def test_formula_based_cell + + end + def test_format_code assert_raise(ArgumentError) {@num_data.format_code = 7} assert_nothing_raised {@num_data.format_code = 'foo_bar'} diff --git a/test/drawing/tc_pic.rb b/test/drawing/tc_pic.rb index 5fc1f1c3..a892678d 100644 --- a/test/drawing/tc_pic.rb +++ b/test/drawing/tc_pic.rb @@ -18,6 +18,25 @@ class TestPic < Test::Unit::TestCase assert_equal(@image.image_src, @test_img) end + def test_anchor_swapping + #swap from one cell to two cell when end_at is specified + assert(@image.anchor.is_a?(Axlsx::OneCellAnchor)) + start_at = @image.anchor.from + @image.end_at 10,5 + assert(@image.anchor.is_a?(Axlsx::TwoCellAnchor)) + assert_equal(start_at.col, @image.anchor.from.col) + assert_equal(start_at.row, @image.anchor.from.row) + assert_equal(10,@image.anchor.to.col) + assert_equal(5, @image.anchor.to.row) + + #swap from two cell to one cell when width or height are specified + @image.width = 200 + assert(@image.anchor.is_a?(Axlsx::OneCellAnchor)) + assert_equal(start_at.col, @image.anchor.from.col) + assert_equal(start_at.row, @image.anchor.from.row) + assert_equal(200, @image.width) + + end def test_hyperlink assert_equal(@image.hyperlink.href, "https://github.com/randym") @image.hyperlink = "http://axlsx.blogspot.com" diff --git a/test/workbook/worksheet/tc_data_validation.rb b/test/workbook/worksheet/tc_data_validation.rb index c30ce251..17622d7d 100644 --- a/test/workbook/worksheet/tc_data_validation.rb +++ b/test/workbook/worksheet/tc_data_validation.rb @@ -256,4 +256,10 @@ class TestDataValidation < Test::Unit::TestCase [@promptTitle='Be carful!'][@prompt='Only values from list'][@errorTitle='Wrong input'][@error='Only values from list'] [@showErrorMessage='true'][@allowBlank='true'][@showInputMessage='true'][@showDropDown='true'][@type='list'][@errorStyle='stop']") end -end
\ No newline at end of file + + def test_empty_attributes + v = Axlsx::DataValidation.new + assert_equal(nil, v.send(:get_valid_attributes)) + + end +end |
