write_xlsx 1.08.1 → 1.09.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +10 -0
- data/Changes +17 -0
- data/README.md +1 -1
- data/examples/background.rb +19 -0
- data/examples/ignore_errors.rb +39 -0
- data/examples/keep_leading_zeros.rb +17 -0
- data/lib/write_xlsx/chart/axis.rb +3 -3
- data/lib/write_xlsx/chart/scatter.rb +0 -15
- data/lib/write_xlsx/chart/series.rb +1 -1
- data/lib/write_xlsx/chart.rb +28 -28
- data/lib/write_xlsx/chartsheet.rb +3 -3
- data/lib/write_xlsx/drawing.rb +39 -39
- data/lib/write_xlsx/format.rb +11 -179
- data/lib/write_xlsx/package/app.rb +2 -2
- data/lib/write_xlsx/package/button.rb +8 -8
- data/lib/write_xlsx/package/comments.rb +8 -8
- data/lib/write_xlsx/package/content_types.rb +18 -9
- data/lib/write_xlsx/package/core.rb +5 -5
- data/lib/write_xlsx/package/custom.rb +2 -2
- data/lib/write_xlsx/package/metadata.rb +159 -0
- data/lib/write_xlsx/package/packager.rb +21 -0
- data/lib/write_xlsx/package/shared_strings.rb +6 -6
- data/lib/write_xlsx/package/styles.rb +11 -11
- data/lib/write_xlsx/package/table.rb +23 -23
- data/lib/write_xlsx/package/theme.rb +1 -1
- data/lib/write_xlsx/package/vml.rb +43 -43
- data/lib/write_xlsx/shape.rb +17 -15
- data/lib/write_xlsx/sparkline.rb +340 -340
- data/lib/write_xlsx/utility.rb +4 -23
- data/lib/write_xlsx/version.rb +1 -1
- data/lib/write_xlsx/workbook.rb +171 -644
- data/lib/write_xlsx/worksheet/cell_data.rb +25 -3
- data/lib/write_xlsx/worksheet/data_validation.rb +20 -20
- data/lib/write_xlsx/worksheet/hyperlink.rb +4 -4
- data/lib/write_xlsx/worksheet/page_setup.rb +12 -12
- data/lib/write_xlsx/worksheet.rb +267 -4144
- data/test/perl_output/background.xlsx +0 -0
- data/test/perl_output/ignore_errors.xlsx +0 -0
- data/test/perl_output/keep_leading_zeros.xlsx +0 -0
- data/test/perl_output/multi_line.xlsx +0 -0
- data/test/regression/images/logo.gif +0 -0
- data/test/regression/images/logo.jpg +0 -0
- data/test/regression/images/red.gif +0 -0
- data/test/regression/test_background01.rb +23 -0
- data/test/regression/test_background02.rb +23 -0
- data/test/regression/test_background03.rb +24 -0
- data/test/regression/test_background04.rb +25 -0
- data/test/regression/test_background05.rb +25 -0
- data/test/regression/test_background06.rb +31 -0
- data/test/regression/test_background07.rb +37 -0
- data/test/regression/test_chart_axis47.rb +52 -0
- data/test/regression/test_chart_axis48.rb +53 -0
- data/test/regression/test_dynamic_array01.rb +25 -0
- data/test/regression/test_image56.rb +23 -0
- data/test/regression/test_image57.rb +23 -0
- data/test/regression/test_set_column10.rb +55 -0
- data/test/regression/test_set_column11.rb +48 -0
- data/test/regression/test_set_row01.rb +35 -0
- data/test/regression/test_set_row02.rb +35 -0
- data/test/regression/test_set_row03.rb +35 -0
- data/test/regression/test_set_row04.rb +35 -0
- data/test/regression/xlsx_files/background01.xlsx +0 -0
- data/test/regression/xlsx_files/background02.xlsx +0 -0
- data/test/regression/xlsx_files/background03.xlsx +0 -0
- data/test/regression/xlsx_files/background04.xlsx +0 -0
- data/test/regression/xlsx_files/background05.xlsx +0 -0
- data/test/regression/xlsx_files/background06.xlsx +0 -0
- data/test/regression/xlsx_files/background07.xlsx +0 -0
- data/test/regression/xlsx_files/chart_axis47.xlsx +0 -0
- data/test/regression/xlsx_files/chart_axis48.xlsx +0 -0
- data/test/regression/xlsx_files/dynamic_array01.xlsx +0 -0
- data/test/regression/xlsx_files/image56.xlsx +0 -0
- data/test/regression/xlsx_files/image57.xlsx +0 -0
- data/test/regression/xlsx_files/set_row01.xlsx +0 -0
- data/test/regression/xlsx_files/set_row03.xlsx +0 -0
- data/test/test_example_match.rb +73 -0
- data/test/worksheet/test_pixels_to_row_col.rb +46 -0
- metadata +86 -2
    
        data/lib/write_xlsx/format.rb
    CHANGED
    
    | @@ -2,177 +2,20 @@ | |
| 2 2 | 
             
            require 'write_xlsx/utility'
         | 
| 3 3 |  | 
| 4 4 | 
             
            module Writexlsx
         | 
| 5 | 
            -
              # ==CELL FORMATTING
         | 
| 6 | 
            -
              #
         | 
| 7 | 
            -
              # This section describes the methods and properties that are available
         | 
| 8 | 
            -
              # for formatting cells in Excel. The properties of a cell that can be
         | 
| 9 | 
            -
              # formatted include: fonts, colours, patterns, borders, alignment and
         | 
| 10 | 
            -
              # number formatting.
         | 
| 11 | 
            -
              #
         | 
| 12 | 
            -
              # ===Creating and using a Format object
         | 
| 13 | 
            -
              #
         | 
| 14 | 
            -
              # Cell formatting is defined through a Format object. Format objects
         | 
| 15 | 
            -
              # are created by calling the workbook add_format() method as follows:
         | 
| 16 | 
            -
              #
         | 
| 17 | 
            -
              #     format1 = workbook.add_format             # Set properties later
         | 
| 18 | 
            -
              #     format2 = workbook.add_format(props_hash) # Set at creation
         | 
| 19 | 
            -
              #
         | 
| 20 | 
            -
              # The format object holds all the formatting properties that can be applied
         | 
| 21 | 
            -
              # to a cell, a row or a column. The process of setting these properties is
         | 
| 22 | 
            -
              # discussed in the next section.
         | 
| 23 | 
            -
              #
         | 
| 24 | 
            -
              # Once a Format object has been constructed and its properties have been
         | 
| 25 | 
            -
              # set it can be passed as an argument to the worksheet write methods as
         | 
| 26 | 
            -
              # follows:
         | 
| 27 | 
            -
              #
         | 
| 28 | 
            -
              #     worksheet.write( 0, 0, 'One', format )
         | 
| 29 | 
            -
              #     worksheet.write_string( 1, 0, 'Two', format )
         | 
| 30 | 
            -
              #     worksheet.write_number( 2, 0, 3, format )
         | 
| 31 | 
            -
              #     worksheet.write_blank( 3, 0, format )
         | 
| 32 | 
            -
              #
         | 
| 33 | 
            -
              # Formats can also be passed to the worksheet set_row() and set_column()
         | 
| 34 | 
            -
              # methods to define the default property for a row or column.
         | 
| 35 | 
            -
              #
         | 
| 36 | 
            -
              #     worksheet.set_row( 0, 15, format )
         | 
| 37 | 
            -
              #     worksheet.set_column( 0, 0, 15, format )
         | 
| 38 | 
            -
              #
         | 
| 39 | 
            -
              # ===Format methods and Format properties
         | 
| 40 | 
            -
              #
         | 
| 41 | 
            -
              # The following table shows the Excel format categories, the formatting
         | 
| 42 | 
            -
              # properties that can be applied and the equivalent object method:
         | 
| 43 | 
            -
              #
         | 
| 44 | 
            -
              #     Category   Description       Property        Method Name
         | 
| 45 | 
            -
              #     --------   -----------       --------        -----------
         | 
| 46 | 
            -
              #     Font       Font type         font            set_font()
         | 
| 47 | 
            -
              #                Font size         size            set_size()
         | 
| 48 | 
            -
              #                Font color        color           set_color()
         | 
| 49 | 
            -
              #                Bold              bold            set_bold()
         | 
| 50 | 
            -
              #                Italic            italic          set_italic()
         | 
| 51 | 
            -
              #                Underline         underline       set_underline()
         | 
| 52 | 
            -
              #                Strikeout         font_strikeout  set_font_strikeout()
         | 
| 53 | 
            -
              #                Super/Subscript   font_script     set_font_script()
         | 
| 54 | 
            -
              #                Outline           font_outline    set_font_outline()
         | 
| 55 | 
            -
              #                Shadow            font_shadow     set_font_shadow()
         | 
| 56 | 
            -
              #
         | 
| 57 | 
            -
              #     Number     Numeric format    num_format      set_num_format()
         | 
| 58 | 
            -
              #
         | 
| 59 | 
            -
              #     Protection Lock cells        locked          set_locked()
         | 
| 60 | 
            -
              #                Hide formulas     hidden          set_hidden()
         | 
| 61 | 
            -
              #
         | 
| 62 | 
            -
              #     Alignment  Horizontal align  align           set_align()
         | 
| 63 | 
            -
              #                Vertical align    valign          set_align()
         | 
| 64 | 
            -
              #                Rotation          rotation        set_rotation()
         | 
| 65 | 
            -
              #                Text wrap         text_wrap       set_text_wrap()
         | 
| 66 | 
            -
              #                Justify last      text_justlast   set_text_justlast()
         | 
| 67 | 
            -
              #                Center across     center_across   set_center_across()
         | 
| 68 | 
            -
              #                Indentation       indent          set_indent()
         | 
| 69 | 
            -
              #                Shrink to fit     shrink          set_shrink()
         | 
| 70 | 
            -
              #
         | 
| 71 | 
            -
              #     Pattern    Cell pattern      pattern         set_pattern()
         | 
| 72 | 
            -
              #                Background color  bg_color        set_bg_color()
         | 
| 73 | 
            -
              #                Foreground color  fg_color        set_fg_color()
         | 
| 74 | 
            -
              #
         | 
| 75 | 
            -
              #     Border     Cell border       border          set_border()
         | 
| 76 | 
            -
              #                Bottom border     bottom          set_bottom()
         | 
| 77 | 
            -
              #                Top border        top             set_top()
         | 
| 78 | 
            -
              #                Left border       left            set_left()
         | 
| 79 | 
            -
              #                Right border      right           set_right()
         | 
| 80 | 
            -
              #                Border color      border_color    set_border_color()
         | 
| 81 | 
            -
              #                Bottom color      bottom_color    set_bottom_color()
         | 
| 82 | 
            -
              #                Top color         top_color       set_top_color()
         | 
| 83 | 
            -
              #                Left color        left_color      set_left_color()
         | 
| 84 | 
            -
              #                Right color       right_color     set_right_color()
         | 
| 85 | 
            -
              #
         | 
| 86 | 
            -
              # There are two ways of setting Format properties: by using the object
         | 
| 87 | 
            -
              # method interface or by setting the property directly. For example,
         | 
| 88 | 
            -
              # a typical use of the method interface would be as follows:
         | 
| 89 | 
            -
              #
         | 
| 90 | 
            -
              #     format = workbook.add_format
         | 
| 91 | 
            -
              #     format.set_bold
         | 
| 92 | 
            -
              #     format.set_color( 'red' )
         | 
| 93 | 
            -
              #
         | 
| 94 | 
            -
              # By comparison the properties can be set directly by passing a hash
         | 
| 95 | 
            -
              # of properties to the Format constructor:
         | 
| 96 | 
            -
              #
         | 
| 97 | 
            -
              #     format = workbook.add_format( :bold => 1, :color => 'red' )
         | 
| 98 | 
            -
              #
         | 
| 99 | 
            -
              # or after the Format has been constructed by means of the
         | 
| 100 | 
            -
              # set_format_properties() method as follows:
         | 
| 101 | 
            -
              #
         | 
| 102 | 
            -
              #     format = workbook.add_format
         | 
| 103 | 
            -
              #     format.set_format_properties( :bold => 1, :color => 'red' )
         | 
| 104 | 
            -
              #
         | 
| 105 | 
            -
              # You can also store the properties in one or more named hashes and pass
         | 
| 106 | 
            -
              # them to the required method:
         | 
| 107 | 
            -
              #
         | 
| 108 | 
            -
              #     font = {
         | 
| 109 | 
            -
              #         :font  => 'Arial',
         | 
| 110 | 
            -
              #         :size  => 12,
         | 
| 111 | 
            -
              #         :color => 'blue',
         | 
| 112 | 
            -
              #         :bold  => 1
         | 
| 113 | 
            -
              #     }
         | 
| 114 | 
            -
              #
         | 
| 115 | 
            -
              #     shading = {
         | 
| 116 | 
            -
              #         :bg_color => 'green',
         | 
| 117 | 
            -
              #         :pattern  => 1
         | 
| 118 | 
            -
              #     }
         | 
| 119 | 
            -
              #
         | 
| 120 | 
            -
              #     format1 = workbook.add_format( font )           # Font only
         | 
| 121 | 
            -
              #     format2 = workbook.add_format( font, shading )  # Font and shading
         | 
| 122 | 
            -
              #
         | 
| 123 | 
            -
              # The provision of two ways of setting properties might lead you to wonder
         | 
| 124 | 
            -
              # which is the best way. The method mechanism may be better is you prefer
         | 
| 125 | 
            -
              # setting properties via method calls (which the author did when the code
         | 
| 126 | 
            -
              # was first written) otherwise passing properties to the constructor has
         | 
| 127 | 
            -
              # proved to be a little more flexible and self documenting in practice.
         | 
| 128 | 
            -
              # An additional advantage of working with property hashes is that it allows
         | 
| 129 | 
            -
              # you to share formatting between workbook objects as shown in the example
         | 
| 130 | 
            -
              # above.
         | 
| 131 | 
            -
              #
         | 
| 132 | 
            -
              # ===Working with formats
         | 
| 133 | 
            -
              #
         | 
| 134 | 
            -
              # The default format is Arial 10 with all other properties off.
         | 
| 135 | 
            -
              #
         | 
| 136 | 
            -
              # Each unique format in WriteXLSX must have a corresponding Format
         | 
| 137 | 
            -
              # object. It isn't possible to use a Format with a write() method and then
         | 
| 138 | 
            -
              # redefine the Format for use at a later stage. This is because a Format
         | 
| 139 | 
            -
              # is applied to a cell not in its current state but in its final state.
         | 
| 140 | 
            -
              # Consider the following example:
         | 
| 141 | 
            -
              #
         | 
| 142 | 
            -
              #     format = workbook.add_format
         | 
| 143 | 
            -
              #     format.set_bold
         | 
| 144 | 
            -
              #     format.set_color( 'red' )
         | 
| 145 | 
            -
              #     worksheet.write( 'A1', 'Cell A1', format )
         | 
| 146 | 
            -
              #     format.set_color( 'green' )
         | 
| 147 | 
            -
              #     worksheet.write( 'B1', 'Cell B1', format )
         | 
| 148 | 
            -
              #
         | 
| 149 | 
            -
              # Cell A1 is assigned the Format format which is initially set to the colour
         | 
| 150 | 
            -
              # red. However, the colour is subsequently set to green. When Excel displays
         | 
| 151 | 
            -
              # Cell A1 it will display the final state of the Format which in this case
         | 
| 152 | 
            -
              # will be the colour green.
         | 
| 153 | 
            -
              #
         | 
| 154 | 
            -
              # In general a method call without an argument will turn a property on,
         | 
| 155 | 
            -
              # for example:
         | 
| 156 | 
            -
              #
         | 
| 157 | 
            -
              #     format1 = workbook.add_format
         | 
| 158 | 
            -
              #     format1.set_bold         # Turns bold on
         | 
| 159 | 
            -
              #     format1.set_bold( 1 )    # Also turns bold on
         | 
| 160 | 
            -
              #     format1.set_bold( 0 )    # Turns bold off
         | 
| 161 | 
            -
              #
         | 
| 162 5 | 
             
              class Format
         | 
| 163 6 | 
             
                include Writexlsx::Utility
         | 
| 164 7 |  | 
| 165 | 
            -
                attr_reader :xf_index, :dxf_index, :num_format | 
| 8 | 
            +
                attr_reader :xf_index, :dxf_index, :num_format                                                 # :nodoc:
         | 
| 166 9 | 
             
                attr_reader :underline, :font_script, :size, :theme, :font, :font_family, :hyperlink, :xf_id   # :nodoc:
         | 
| 167 | 
            -
                attr_reader :diag_type, :diag_color, :font_only, :color, :color_indexed | 
| 168 | 
            -
                attr_reader :left, :left_color, :right, :right_color, :top, :top_color, :bottom, :bottom_color | 
| 169 | 
            -
                attr_reader :font_scheme | 
| 170 | 
            -
                attr_accessor :num_format_index, :border_index, :font_index | 
| 171 | 
            -
                attr_accessor :fill_index, :font_condense, :font_extend, :diag_border | 
| 172 | 
            -
                attr_accessor :bg_color, :fg_color, :pattern | 
| 10 | 
            +
                attr_reader :diag_type, :diag_color, :font_only, :color, :color_indexed                        # :nodoc:
         | 
| 11 | 
            +
                attr_reader :left, :left_color, :right, :right_color, :top, :top_color, :bottom, :bottom_color # :nodoc:
         | 
| 12 | 
            +
                attr_reader :font_scheme                                                                       # :nodoc:
         | 
| 13 | 
            +
                attr_accessor :num_format_index, :border_index, :font_index                                    # :nodoc:
         | 
| 14 | 
            +
                attr_accessor :fill_index, :font_condense, :font_extend, :diag_border                          # :nodoc:
         | 
| 15 | 
            +
                attr_accessor :bg_color, :fg_color, :pattern                                                   # :nodoc:
         | 
| 173 16 |  | 
| 174 | 
            -
                attr_accessor :dxf_bg_color, :dxf_fg_color | 
| 175 | 
            -
                attr_reader :rotation, :bold, :italic, :font_strikeout
         | 
| 17 | 
            +
                attr_accessor :dxf_bg_color, :dxf_fg_color                                                     # :nodoc:
         | 
| 18 | 
            +
                attr_reader :rotation, :bold, :italic, :font_strikeout                                         # :nodoc:
         | 
| 176 19 |  | 
| 177 20 | 
             
                def initialize(formats, params = {})   # :nodoc:
         | 
| 178 21 | 
             
                  @formats = formats
         | 
| @@ -268,17 +111,6 @@ module Writexlsx | |
| 268 111 | 
             
                #
         | 
| 269 112 | 
             
                # Convert hashes of properties to method calls.
         | 
| 270 113 | 
             
                #
         | 
| 271 | 
            -
                # The properties of an existing Format object can be also be set by means
         | 
| 272 | 
            -
                # of set_format_properties():
         | 
| 273 | 
            -
                #
         | 
| 274 | 
            -
                #     format = workbook.add_format
         | 
| 275 | 
            -
                #     format.set_format_properties(:bold => 1, :color => 'red');
         | 
| 276 | 
            -
                #
         | 
| 277 | 
            -
                # However, this method is here mainly for legacy reasons. It is preferable
         | 
| 278 | 
            -
                # to set the properties in the format constructor:
         | 
| 279 | 
            -
                #
         | 
| 280 | 
            -
                #     format = workbook.add_format(:bold => 1, :color => 'red');
         | 
| 281 | 
            -
                #
         | 
| 282 114 | 
             
                def set_format_properties(*properties)   # :nodoc:
         | 
| 283 115 | 
             
                  return if properties.empty?
         | 
| 284 116 | 
             
                  properties.each do |property|
         | 
| @@ -747,7 +579,7 @@ module Writexlsx | |
| 747 579 | 
             
                    writer.empty_tag('sz', [ ['val', size] ]) unless dxf_format
         | 
| 748 580 |  | 
| 749 581 | 
             
                    if theme == -1
         | 
| 750 | 
            -
             | 
| 582 | 
            +
                    # Ignore for excel2003_style
         | 
| 751 583 | 
             
                    elsif ptrue?(theme)
         | 
| 752 584 | 
             
                      write_color(writer, 'theme', theme)
         | 
| 753 585 | 
             
                    elsif ptrue?(@color_indexed)
         | 
| @@ -845,7 +677,7 @@ module Writexlsx | |
| 845 677 |  | 
| 846 678 | 
             
                def write_font_family_scheme(writer)
         | 
| 847 679 | 
             
                  if ptrue?(@font_family)
         | 
| 848 | 
            -
             | 
| 680 | 
            +
                    writer.empty_tag('family', [ ['val', @font_family] ])
         | 
| 849 681 | 
             
                  end
         | 
| 850 682 |  | 
| 851 683 | 
             
                  if ptrue?(@font_charset)
         | 
| @@ -105,8 +105,8 @@ module Writexlsx | |
| 105 105 |  | 
| 106 106 | 
             
                    schema   = 'http://schemas.openxmlformats.org/officeDocument/2006/'
         | 
| 107 107 | 
             
                    attributes = [
         | 
| 108 | 
            -
             | 
| 109 | 
            -
             | 
| 108 | 
            +
                      ['xmlns',     "#{schema}extended-properties"],
         | 
| 109 | 
            +
                      ['xmlns:vt',  "#{schema}docPropsVTypes"]
         | 
| 110 110 | 
             
                    ]
         | 
| 111 111 |  | 
| 112 112 | 
             
                    @writer.tag_elements('Properties', attributes) { yield }
         | 
| @@ -50,8 +50,8 @@ module Writexlsx | |
| 50 50 | 
             
                  # attributes for <v:fill> element.
         | 
| 51 51 | 
             
                  def fill_attributes
         | 
| 52 52 | 
             
                    [
         | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 53 | 
            +
                      ['color2',             'buttonFace [67]'],
         | 
| 54 | 
            +
                      ['o:detectmouseclick', 't']
         | 
| 55 55 | 
             
                    ]
         | 
| 56 56 | 
             
                  end
         | 
| 57 57 |  | 
| @@ -60,9 +60,9 @@ module Writexlsx | |
| 60 60 | 
             
                  #
         | 
| 61 61 | 
             
                  def write_rotation_lock
         | 
| 62 62 | 
             
                    attributes = [
         | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 63 | 
            +
                      ['v:ext',    'edit'],
         | 
| 64 | 
            +
                      ['rotation', 't']
         | 
| 65 | 
            +
                    ]
         | 
| 66 66 | 
             
                    @writer.empty_tag('o:lock', attributes)
         | 
| 67 67 | 
             
                  end
         | 
| 68 68 |  | 
| @@ -71,9 +71,9 @@ module Writexlsx | |
| 71 71 | 
             
                  #
         | 
| 72 72 | 
             
                  def write_textbox
         | 
| 73 73 | 
             
                    attributes = [
         | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 76 | 
            -
             | 
| 74 | 
            +
                      ['style', 'mso-direction-alt:auto'],
         | 
| 75 | 
            +
                      ['o:singleclick', 'f']
         | 
| 76 | 
            +
                    ]
         | 
| 77 77 |  | 
| 78 78 | 
             
                    @writer.tag_elements('v:textbox', attributes) do
         | 
| 79 79 | 
             
                      # Write the div element.
         | 
| @@ -177,8 +177,8 @@ module Writexlsx | |
| 177 177 | 
             
                  #
         | 
| 178 178 | 
             
                  def write_textbox
         | 
| 179 179 | 
             
                    attributes = [
         | 
| 180 | 
            -
             | 
| 181 | 
            -
             | 
| 180 | 
            +
                      ['style', 'mso-direction-alt:auto']
         | 
| 181 | 
            +
                    ]
         | 
| 182 182 |  | 
| 183 183 | 
             
                    @writer.tag_elements('v:textbox', attributes) do
         | 
| 184 184 | 
             
                      # Write the div element.
         | 
| @@ -191,8 +191,8 @@ module Writexlsx | |
| 191 191 | 
             
                  #
         | 
| 192 192 | 
             
                  def write_client_data
         | 
| 193 193 | 
             
                    attributes = [
         | 
| 194 | 
            -
             | 
| 195 | 
            -
             | 
| 194 | 
            +
                      ['ObjectType', 'Note']
         | 
| 195 | 
            +
                    ]
         | 
| 196 196 |  | 
| 197 197 | 
             
                    @writer.tag_elements('x:ClientData', attributes) do
         | 
| 198 198 | 
             
                      @writer.empty_tag('x:MoveWithCells')
         | 
| @@ -225,10 +225,10 @@ module Writexlsx | |
| 225 225 | 
             
                    @author      = options[:author]
         | 
| 226 226 | 
             
                    @start_cell  = options[:start_cell]
         | 
| 227 227 | 
             
                    @start_row, @start_col = if @start_cell
         | 
| 228 | 
            -
             | 
| 229 | 
            -
             | 
| 230 | 
            -
             | 
| 231 | 
            -
             | 
| 228 | 
            +
                                               substitute_cellref(@start_cell)
         | 
| 229 | 
            +
                                             else
         | 
| 230 | 
            +
                                               [ options[:start_row], options[:start_col] ]
         | 
| 231 | 
            +
                                             end
         | 
| 232 232 | 
             
                    @visible     = options[:visible]
         | 
| 233 233 | 
             
                    @x_offset    = options[:x_offset]       || default_x_offset(col)
         | 
| 234 234 | 
             
                    @y_offset    = options[:y_offset]       || default_y_offset(row)
         | 
| @@ -165,9 +165,9 @@ module Writexlsx | |
| 165 165 | 
             
                  #
         | 
| 166 166 | 
             
                  def add_table_name(table_name)
         | 
| 167 167 | 
             
                    add_override(
         | 
| 168 | 
            -
             | 
| 169 | 
            -
             | 
| 170 | 
            -
             | 
| 168 | 
            +
                      "/xl/tables/#{table_name}.xml",
         | 
| 169 | 
            +
                      "#{App_document}spreadsheetml.table+xml"
         | 
| 170 | 
            +
                    )
         | 
| 171 171 | 
             
                  end
         | 
| 172 172 |  | 
| 173 173 | 
             
                  #
         | 
| @@ -187,6 +187,15 @@ module Writexlsx | |
| 187 187 | 
             
                    add_override(custom, "#{App_document}custom-properties+xml")
         | 
| 188 188 | 
             
                  end
         | 
| 189 189 |  | 
| 190 | 
            +
                  #
         | 
| 191 | 
            +
                  # Add the metadata file to the ContentTypes overrides.
         | 
| 192 | 
            +
                  #
         | 
| 193 | 
            +
                  def add_metadata
         | 
| 194 | 
            +
                    add_override(
         | 
| 195 | 
            +
                      "/xl/metadata.xml",
         | 
| 196 | 
            +
                      "#{App_document}spreadsheetml.sheetMetadata+xml"
         | 
| 197 | 
            +
                    )
         | 
| 198 | 
            +
                  end
         | 
| 190 199 |  | 
| 191 200 | 
             
                  private
         | 
| 192 201 |  | 
| @@ -219,10 +228,10 @@ module Writexlsx | |
| 219 228 |  | 
| 220 229 | 
             
                  def write_default_or_override(tag, param0, a)
         | 
| 221 230 | 
             
                    @writer.empty_tag(tag,
         | 
| 222 | 
            -
             | 
| 223 | 
            -
             | 
| 224 | 
            -
             | 
| 225 | 
            -
             | 
| 231 | 
            +
                                      [
         | 
| 232 | 
            +
                                        [param0, a[0]],
         | 
| 233 | 
            +
                                        ['ContentType', a[1]]
         | 
| 234 | 
            +
                                      ])
         | 
| 226 235 | 
             
                  end
         | 
| 227 236 |  | 
| 228 237 | 
             
                  #
         | 
| @@ -231,8 +240,8 @@ module Writexlsx | |
| 231 240 | 
             
                  def write_types
         | 
| 232 241 | 
             
                    xmlns = 'http://schemas.openxmlformats.org/package/2006/content-types'
         | 
| 233 242 | 
             
                    attributes = [
         | 
| 234 | 
            -
             | 
| 235 | 
            -
             | 
| 243 | 
            +
                      ['xmlns', xmlns]
         | 
| 244 | 
            +
                    ]
         | 
| 236 245 |  | 
| 237 246 | 
             
                    @writer.tag_elements('Types', attributes) { yield }
         | 
| 238 247 | 
             
                  end
         | 
| @@ -68,11 +68,11 @@ module Writexlsx | |
| 68 68 | 
             
                    xmlns_xsi      = 'http://www.w3.org/2001/XMLSchema-instance'
         | 
| 69 69 |  | 
| 70 70 | 
             
                    attributes = [
         | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 71 | 
            +
                      ['xmlns:cp',       xmlns_cp],
         | 
| 72 | 
            +
                      ['xmlns:dc',       xmlns_dc],
         | 
| 73 | 
            +
                      ['xmlns:dcterms',  xmlns_dcterms],
         | 
| 74 | 
            +
                      ['xmlns:dcmitype', xmlns_dcmitype],
         | 
| 75 | 
            +
                      ['xmlns:xsi',      xmlns_xsi]
         | 
| 76 76 | 
             
                    ]
         | 
| 77 77 |  | 
| 78 78 | 
             
                    @writer.tag_elements('cp:coreProperties', attributes) { yield }
         | 
| @@ -47,7 +47,7 @@ module Writexlsx | |
| 47 47 | 
             
                      @properties.each do |property|
         | 
| 48 48 | 
             
                        # Write the property element.
         | 
| 49 49 | 
             
                        write_property(property)
         | 
| 50 | 
            -
             | 
| 50 | 
            +
                      end
         | 
| 51 51 | 
             
                    end
         | 
| 52 52 | 
             
                  end
         | 
| 53 53 |  | 
| @@ -112,7 +112,7 @@ module Writexlsx | |
| 112 112 | 
             
                    end
         | 
| 113 113 |  | 
| 114 114 | 
             
                    @writer.data_element('vt:bool', data)
         | 
| 115 | 
            -
             | 
| 115 | 
            +
                  end
         | 
| 116 116 |  | 
| 117 117 | 
             
                  #
         | 
| 118 118 | 
             
                  # Write the <vt:filetime> element.
         | 
| @@ -0,0 +1,159 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
            require 'write_xlsx/package/xml_writer_simple'
         | 
| 3 | 
            +
            require 'write_xlsx/utility'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Writexlsx
         | 
| 6 | 
            +
              module Package
         | 
| 7 | 
            +
                #
         | 
| 8 | 
            +
                # Metadata - A class for writing the Excel XLSX metadata.xml file.
         | 
| 9 | 
            +
                #
         | 
| 10 | 
            +
                class Metadata
         | 
| 11 | 
            +
                  include Writexlsx::Utility
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def initialize(workbook)
         | 
| 14 | 
            +
                    @writer = Package::XMLWriterSimple.new
         | 
| 15 | 
            +
                    @workbook      = workbook
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  def set_xml_writer(filename)
         | 
| 19 | 
            +
                    @writer.set_xml_writer(filename)
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  def assemble_xml_file
         | 
| 23 | 
            +
                    write_xml_declaration do
         | 
| 24 | 
            +
                      # Write the metadata element.
         | 
| 25 | 
            +
                      write_metadata
         | 
| 26 | 
            +
                      # Write the metadataTypes element.
         | 
| 27 | 
            +
                      write_metadata_types
         | 
| 28 | 
            +
                      # Write the futureMetadata element.
         | 
| 29 | 
            +
                      write_future_metadata
         | 
| 30 | 
            +
                      # Write the cellMetadata element.
         | 
| 31 | 
            +
                      write_cell_metadata
         | 
| 32 | 
            +
                      @writer.end_tag('metadata')
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  private
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  #
         | 
| 39 | 
            +
                  # Write the <metadata> element.
         | 
| 40 | 
            +
                  #
         | 
| 41 | 
            +
                  def write_metadata
         | 
| 42 | 
            +
                    xmlns = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'
         | 
| 43 | 
            +
                    xmlns_xda =
         | 
| 44 | 
            +
                      'http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray'
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                    attributes = [
         | 
| 47 | 
            +
                      ['xmlns',     xmlns],
         | 
| 48 | 
            +
                      ['xmlns:xda', xmlns_xda]
         | 
| 49 | 
            +
                    ]
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    @writer.start_tag('metadata', attributes)
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  #
         | 
| 55 | 
            +
                  # Write the <metadataTypes> element.
         | 
| 56 | 
            +
                  #
         | 
| 57 | 
            +
                  def write_metadata_types
         | 
| 58 | 
            +
                    attributes = [['count', 1 ]]
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                    @writer.tag_elements('metadataTypes', attributes) do
         | 
| 61 | 
            +
                      # Write the metadataType element.
         | 
| 62 | 
            +
                      write_metadata_type
         | 
| 63 | 
            +
                    end
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  #
         | 
| 67 | 
            +
                  # Write the <metadataType> element.
         | 
| 68 | 
            +
                  #
         | 
| 69 | 
            +
                  def write_metadata_type
         | 
| 70 | 
            +
                    attributes = [
         | 
| 71 | 
            +
                      ['name',                'XLDAPR'],
         | 
| 72 | 
            +
                      ['minSupportedVersion', 120000],
         | 
| 73 | 
            +
                      ['copy',                1],
         | 
| 74 | 
            +
                      ['pasteAll',            1],
         | 
| 75 | 
            +
                      ['pasteValues',         1],
         | 
| 76 | 
            +
                      ['merge',               1],
         | 
| 77 | 
            +
                      ['splitFirst',          1],
         | 
| 78 | 
            +
                      ['rowColShift',         1],
         | 
| 79 | 
            +
                      ['clearFormats',        1],
         | 
| 80 | 
            +
                      ['clearComments',       1],
         | 
| 81 | 
            +
                      ['assign',              1],
         | 
| 82 | 
            +
                      ['coerce',              1],
         | 
| 83 | 
            +
                      ['cellMeta',            1]
         | 
| 84 | 
            +
                    ]
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                    @writer.empty_tag('metadataType', attributes)
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                  #
         | 
| 90 | 
            +
                  # Write the <futureMetadata> element.
         | 
| 91 | 
            +
                  #
         | 
| 92 | 
            +
                  def write_future_metadata
         | 
| 93 | 
            +
                    attributes = [
         | 
| 94 | 
            +
                      ['name',  'XLDAPR'],
         | 
| 95 | 
            +
                      ['count', 1]
         | 
| 96 | 
            +
                    ]
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                    @writer.tag_elements('futureMetadata', attributes) do
         | 
| 99 | 
            +
                      @writer.tag_elements('bk') do
         | 
| 100 | 
            +
                        @writer.tag_elements('extLst') do
         | 
| 101 | 
            +
                          # Write the ext element.
         | 
| 102 | 
            +
                          write_ext();
         | 
| 103 | 
            +
                        end
         | 
| 104 | 
            +
                      end
         | 
| 105 | 
            +
                    end
         | 
| 106 | 
            +
                  end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                  #
         | 
| 109 | 
            +
                  # Write the <ext> element.
         | 
| 110 | 
            +
                  #
         | 
| 111 | 
            +
                  def write_ext
         | 
| 112 | 
            +
                    attributes = [[ 'uri', '{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}']]
         | 
| 113 | 
            +
                    @writer.tag_elements('ext', attributes) do
         | 
| 114 | 
            +
                      # Write the xda:dynamicArrayProperties element.
         | 
| 115 | 
            +
                      write_xda_dynamic_array_properties
         | 
| 116 | 
            +
                    end
         | 
| 117 | 
            +
                  end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                  #
         | 
| 120 | 
            +
                  # Write the <xda:dynamicArrayProperties> element.
         | 
| 121 | 
            +
                  #
         | 
| 122 | 
            +
                  def write_xda_dynamic_array_properties
         | 
| 123 | 
            +
                    attributes = [
         | 
| 124 | 
            +
                      ['fDynamic',   1],
         | 
| 125 | 
            +
                      ['fCollapsed', 0]
         | 
| 126 | 
            +
                    ]
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                    @writer.empty_tag('xda:dynamicArrayProperties', attributes)
         | 
| 129 | 
            +
                  end
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                  #
         | 
| 132 | 
            +
                  # Write the <cellMetadata> element.
         | 
| 133 | 
            +
                  #
         | 
| 134 | 
            +
                  def write_cell_metadata
         | 
| 135 | 
            +
                    count = 1
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                    attributes = [['count', count]]
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                    @writer.tag_elements('cellMetadata', attributes) do
         | 
| 140 | 
            +
                      @writer.tag_elements('bk') do
         | 
| 141 | 
            +
                        # Write the rc element.
         | 
| 142 | 
            +
                        write_rc
         | 
| 143 | 
            +
                      end
         | 
| 144 | 
            +
                    end
         | 
| 145 | 
            +
                  end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                  #
         | 
| 148 | 
            +
                  # Write the <rc> element.
         | 
| 149 | 
            +
                  #
         | 
| 150 | 
            +
                  def write_rc
         | 
| 151 | 
            +
                    attributes = [
         | 
| 152 | 
            +
                      ['t', 1],
         | 
| 153 | 
            +
                      ['v', 0]
         | 
| 154 | 
            +
                    ]
         | 
| 155 | 
            +
                    @writer.empty_tag('rc', attributes)
         | 
| 156 | 
            +
                  end
         | 
| 157 | 
            +
                end
         | 
| 158 | 
            +
              end
         | 
| 159 | 
            +
            end
         | 
| @@ -6,6 +6,7 @@ require 'write_xlsx/package/comments' | |
| 6 6 | 
             
            require 'write_xlsx/package/content_types'
         | 
| 7 7 | 
             
            require 'write_xlsx/package/core'
         | 
| 8 8 | 
             
            require 'write_xlsx/package/custom'
         | 
| 9 | 
            +
            require 'write_xlsx/package/metadata'
         | 
| 9 10 | 
             
            require 'write_xlsx/package/relationships'
         | 
| 10 11 | 
             
            require 'write_xlsx/package/shared_strings'
         | 
| 11 12 | 
             
            require 'write_xlsx/package/styles'
         | 
| @@ -56,6 +57,7 @@ module Writexlsx | |
| 56 57 | 
             
                    write_drawing_rels_files
         | 
| 57 58 | 
             
                    add_image_files
         | 
| 58 59 | 
             
                    add_vba_project
         | 
| 60 | 
            +
                    write_metadata_file
         | 
| 59 61 | 
             
                  end
         | 
| 60 62 |  | 
| 61 63 | 
             
                  private
         | 
| @@ -175,6 +177,20 @@ module Writexlsx | |
| 175 177 | 
             
                    core.assemble_xml_file
         | 
| 176 178 | 
             
                  end
         | 
| 177 179 |  | 
| 180 | 
            +
                  #
         | 
| 181 | 
            +
                  # Write the metadata.xml file.
         | 
| 182 | 
            +
                  #
         | 
| 183 | 
            +
                  def write_metadata_file
         | 
| 184 | 
            +
                    metadata = Package::Metadata.new(@workbook)
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                    return unless @workbook.has_metadata?
         | 
| 187 | 
            +
             | 
| 188 | 
            +
                    FileUtils.mkdir_p("#{@package_dir}/xl")
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                    metadata.set_xml_writer( "#{@package_dir}/xl/metadata.xml")
         | 
| 191 | 
            +
                    metadata.assemble_xml_file
         | 
| 192 | 
            +
                  end
         | 
| 193 | 
            +
             | 
| 178 194 | 
             
                  #
         | 
| 179 195 | 
             
                  # Write the custom.xml file.
         | 
| 180 196 | 
             
                  #
         | 
| @@ -211,6 +227,8 @@ module Writexlsx | |
| 211 227 | 
             
                    content.add_vba_project if @workbook.vba_project
         | 
| 212 228 | 
             
                    # Add the custom properties if present.
         | 
| 213 229 | 
             
                    content.add_custom_properties unless @workbook.custom_properties.empty?
         | 
| 230 | 
            +
                    # Add the metadata file if present.
         | 
| 231 | 
            +
                    content.add_metadata if @workbook.has_metadata?
         | 
| 214 232 |  | 
| 215 233 | 
             
                    content.set_xml_writer("#{@package_dir}/[Content_Types].xml")
         | 
| 216 234 | 
             
                    content.assemble_xml_file
         | 
| @@ -305,6 +323,9 @@ module Writexlsx | |
| 305 323 | 
             
                      rels.add_ms_package_relationship('/vbaProject', 'vbaProject.bin')
         | 
| 306 324 | 
             
                    end
         | 
| 307 325 |  | 
| 326 | 
            +
                    # Add the metadata file if required.
         | 
| 327 | 
            +
                    rels.add_document_relationship('/sheetMetadata', 'metadata.xml') if @workbook.has_metadata?
         | 
| 328 | 
            +
             | 
| 308 329 | 
             
                    rels.set_xml_writer("#{@package_dir}/xl/_rels/workbook.xml.rels")
         | 
| 309 330 | 
             
                    rels.assemble_xml_file
         | 
| 310 331 | 
             
                  end
         | 
| @@ -63,9 +63,9 @@ module Writexlsx | |
| 63 63 |  | 
| 64 64 | 
             
                    attributes =
         | 
| 65 65 | 
             
                      [
         | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 66 | 
            +
                        ['xmlns',       schema + '/spreadsheetml/2006/main'],
         | 
| 67 | 
            +
                        ['count',       total_count],
         | 
| 68 | 
            +
                        ['uniqueCount', unique_count]
         | 
| 69 69 | 
             
                      ]
         | 
| 70 70 |  | 
| 71 71 | 
             
                    @writer.tag_elements('sst', attributes) { yield }
         | 
| @@ -94,9 +94,9 @@ module Writexlsx | |
| 94 94 |  | 
| 95 95 | 
             
                    # Convert control character to the _xHHHH_ escape.
         | 
| 96 96 | 
             
                    string = string.gsub(
         | 
| 97 | 
            -
             | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 97 | 
            +
                      /([\x00-\x08\x0B-\x1F])/,
         | 
| 98 | 
            +
                      sprintf("_x%04X_", $1.ord)
         | 
| 99 | 
            +
                    ) if string =~ /([\x00-\x08\x0B-\x1F])/
         | 
| 100 100 |  | 
| 101 101 | 
             
                    # Convert character to \xC2\xxx or \xC3\xxx
         | 
| 102 102 | 
             
                    if string.bytesize == 1 && 0x80 <= string.ord && string.ord <= 0xFF
         | 
| @@ -56,11 +56,11 @@ module Writexlsx | |
| 56 56 | 
             
                  # based on the default or user defined values in the Workbook palette.
         | 
| 57 57 | 
             
                  #
         | 
| 58 58 | 
             
                  def palette_color(index)
         | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 59 | 
            +
                    if index.to_s =~ /^#([0-9A-F]{6})$/i
         | 
| 60 | 
            +
                      "FF#{$1.upcase}"
         | 
| 61 | 
            +
                    else
         | 
| 62 | 
            +
                      "FF#{super(index)}"
         | 
| 63 | 
            +
                    end
         | 
| 64 64 | 
             
                  end
         | 
| 65 65 |  | 
| 66 66 | 
             
                  #
         | 
| @@ -526,9 +526,9 @@ module Writexlsx | |
| 526 526 | 
             
                  #
         | 
| 527 527 | 
             
                  def write_cell_style(name, xf_id, builtin_id)
         | 
| 528 528 | 
             
                    attributes = [
         | 
| 529 | 
            -
             | 
| 530 | 
            -
             | 
| 531 | 
            -
             | 
| 529 | 
            +
                      ['name',      name],
         | 
| 530 | 
            +
                      ['xfId',      xf_id],
         | 
| 531 | 
            +
                      ['builtinId', builtin_id]
         | 
| 532 532 | 
             
                    ]
         | 
| 533 533 |  | 
| 534 534 | 
             
                    @writer.empty_tag('cellStyle', attributes)
         | 
| @@ -570,9 +570,9 @@ module Writexlsx | |
| 570 570 | 
             
                  #
         | 
| 571 571 | 
             
                  def write_table_styles
         | 
| 572 572 | 
             
                    attributes = [
         | 
| 573 | 
            -
             | 
| 574 | 
            -
             | 
| 575 | 
            -
             | 
| 573 | 
            +
                      ['count',             0],
         | 
| 574 | 
            +
                      ['defaultTableStyle', 'TableStyleMedium9'],
         | 
| 575 | 
            +
                      ['defaultPivotStyle', 'PivotStyleLight16']
         | 
| 576 576 | 
             
                    ]
         | 
| 577 577 |  | 
| 578 578 | 
             
                    @writer.empty_tag('tableStyles', attributes)
         |