write_xlsx 1.12.1 → 1.12.3
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/.rubocop.yml +12 -0
 - data/Changes +6 -0
 - data/LICENSE.txt +1 -1
 - data/examples/autofilter.rb +1 -2
 - data/examples/colors.rb +4 -4
 - data/examples/formats.rb +14 -14
 - data/lib/write_xlsx/chart/area.rb +1 -1
 - data/lib/write_xlsx/chart/axis.rb +4 -4
 - data/lib/write_xlsx/chart/bar.rb +1 -1
 - data/lib/write_xlsx/chart/caption.rb +8 -4
 - data/lib/write_xlsx/chart/column.rb +1 -1
 - data/lib/write_xlsx/chart/doughnut.rb +2 -2
 - data/lib/write_xlsx/chart/line.rb +1 -1
 - data/lib/write_xlsx/chart/pie.rb +2 -2
 - data/lib/write_xlsx/chart/radar.rb +1 -1
 - data/lib/write_xlsx/chart/scatter.rb +1 -1
 - data/lib/write_xlsx/chart/series.rb +10 -20
 - data/lib/write_xlsx/chart/stock.rb +1 -1
 - data/lib/write_xlsx/chart.rb +14 -21
 - data/lib/write_xlsx/chartsheet.rb +3 -3
 - data/lib/write_xlsx/drawing.rb +108 -114
 - data/lib/write_xlsx/format.rb +20 -24
 - data/lib/write_xlsx/image.rb +89 -0
 - data/lib/write_xlsx/image_property.rb +163 -0
 - data/lib/write_xlsx/inserted_chart.rb +42 -0
 - data/lib/write_xlsx/package/app.rb +1 -0
 - data/lib/write_xlsx/package/button.rb +58 -5
 - data/lib/write_xlsx/package/conditional_format.rb +4 -4
 - data/lib/write_xlsx/package/packager.rb +22 -27
 - data/lib/write_xlsx/package/rich_value.rb +1 -1
 - data/lib/write_xlsx/package/styles.rb +1 -1
 - data/lib/write_xlsx/package/vml.rb +10 -19
 - data/lib/write_xlsx/shape.rb +3 -2
 - data/lib/write_xlsx/sparkline.rb +1 -1
 - data/lib/write_xlsx/utility.rb +8 -203
 - data/lib/write_xlsx/version.rb +1 -1
 - data/lib/write_xlsx/workbook.rb +87 -175
 - data/lib/write_xlsx/worksheet/data_validation.rb +1 -1
 - data/lib/write_xlsx/worksheet/hyperlink.rb +2 -2
 - data/lib/write_xlsx/worksheet.rb +478 -484
 - data/lib/write_xlsx/zip_file_utils.rb +2 -2
 - data/write_xlsx.gemspec +3 -3
 - metadata +15 -9
 
| 
         @@ -0,0 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Writexlsx
         
     | 
| 
      
 5 
     | 
    
         
            +
              class InsertedChart
         
     | 
| 
      
 6 
     | 
    
         
            +
                include Writexlsx::Utility
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                attr_reader :row, :col, :chart, :x_offset, :y_offset
         
     | 
| 
      
 9 
     | 
    
         
            +
                attr_reader :x_scale, :y_scale
         
     | 
| 
      
 10 
     | 
    
         
            +
                attr_reader :anchor, :description, :decorative
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def initialize(
         
     | 
| 
      
 13 
     | 
    
         
            +
                      row, col, chart, x_offset, y_offset, x_scale, y_scale,
         
     | 
| 
      
 14 
     | 
    
         
            +
                      anchor, description, decorative
         
     | 
| 
      
 15 
     | 
    
         
            +
                    )
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @row         = row
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @col         = col
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @chart       = chart
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @x_offset    = x_offset
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @y_offset    = y_offset
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @x_scale     = x_scale || 0
         
     | 
| 
      
 22 
     | 
    
         
            +
                  @y_scale     = y_scale || 0
         
     | 
| 
      
 23 
     | 
    
         
            +
                  @anchor      = anchor
         
     | 
| 
      
 24 
     | 
    
         
            +
                  @description = description
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @decorative  = decorative
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def name
         
     | 
| 
      
 29 
     | 
    
         
            +
                  chart.name
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                def scaled_width
         
     | 
| 
      
 33 
     | 
    
         
            +
                  width = chart.width if ptrue?(chart.width)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  (0.5 + (width * x_scale)).to_i
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def scaled_height
         
     | 
| 
      
 38 
     | 
    
         
            +
                  height = chart.height if ptrue?(chart.height)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  (0.5 + (height * y_scale)).to_i
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -8,13 +8,66 @@ module Writexlsx 
     | 
|
| 
       8 
8 
     | 
    
         
             
                class Button
         
     | 
| 
       9 
9 
     | 
    
         
             
                  include Writexlsx::Utility
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
                   
     | 
| 
      
 11 
     | 
    
         
            +
                  def initialize(worksheet, row, col, params, default_row_pixels, button_number)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @worksheet = worksheet
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @default_row_pixels = default_row_pixels
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    # Set the button caption.
         
     | 
| 
      
 16 
     | 
    
         
            +
                    caption = params[:caption] || "Button #{button_number}"
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    @font = { _caption: caption }
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    # Set the macro name.
         
     | 
| 
      
 21 
     | 
    
         
            +
                    @macro = if params[:macro]
         
     | 
| 
      
 22 
     | 
    
         
            +
                               "[0]!#{params[:macro]}"
         
     | 
| 
      
 23 
     | 
    
         
            +
                             else
         
     | 
| 
      
 24 
     | 
    
         
            +
                               "[0]!Button#{button_number}_Click"
         
     | 
| 
      
 25 
     | 
    
         
            +
                             end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                    # Set the alt text for the button.
         
     | 
| 
      
 28 
     | 
    
         
            +
                    @description = params[:description]
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                    # Ensure that a width and height have been set.
         
     | 
| 
      
 31 
     | 
    
         
            +
                    default_height = @default_row_pixels
         
     | 
| 
      
 32 
     | 
    
         
            +
                    width  = params[:width]  || DEFAULT_COL_PIXELS
         
     | 
| 
      
 33 
     | 
    
         
            +
                    height = params[:height] || default_row_pixels
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                    # Scale the size of the button box if required.
         
     | 
| 
      
 36 
     | 
    
         
            +
                    width  *= params[:x_scale] if params[:x_scale]
         
     | 
| 
      
 37 
     | 
    
         
            +
                    height *= params[:y_scale] if params[:y_scale]
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                    # Round the dimensions to the nearest pixel.
         
     | 
| 
      
 40 
     | 
    
         
            +
                    width  = (0.5 + width).to_i
         
     | 
| 
      
 41 
     | 
    
         
            +
                    height = (0.5 + height).to_i
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                    # Set the x/y offsets.
         
     | 
| 
      
 44 
     | 
    
         
            +
                    x_offset = params[:x_offset] || 0
         
     | 
| 
      
 45 
     | 
    
         
            +
                    y_offset = params[:y_offset] || 0
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                    start_row = row
         
     | 
| 
      
 48 
     | 
    
         
            +
                    start_col = col
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                    # Calculate the positions of button object.
         
     | 
| 
      
 51 
     | 
    
         
            +
                    vertices = @worksheet.position_object_pixels(
         
     | 
| 
      
 52 
     | 
    
         
            +
                      start_col,
         
     | 
| 
      
 53 
     | 
    
         
            +
                      start_row,
         
     | 
| 
      
 54 
     | 
    
         
            +
                      x_offset,
         
     | 
| 
      
 55 
     | 
    
         
            +
                      y_offset,
         
     | 
| 
      
 56 
     | 
    
         
            +
                      width,
         
     | 
| 
      
 57 
     | 
    
         
            +
                      height
         
     | 
| 
      
 58 
     | 
    
         
            +
                    )
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                    # Add the width and height for VML.
         
     | 
| 
      
 61 
     | 
    
         
            +
                    vertices << [width, height]
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                    @vertices = vertices
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
       12 
65 
     | 
    
         | 
| 
       13 
66 
     | 
    
         
             
                  def v_shape_attributes(id, z_index)
         
     | 
| 
       14 
67 
     | 
    
         
             
                    attributes = v_shape_attributes_base(id)
         
     | 
| 
       15 
     | 
    
         
            -
                    attributes << ['alt', description] if description
         
     | 
| 
      
 68 
     | 
    
         
            +
                    attributes << ['alt', @description] if @description
         
     | 
| 
       16 
69 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
                    attributes << ['style', (v_shape_style_base(z_index, vertices) + style_addition).join]
         
     | 
| 
      
 70 
     | 
    
         
            +
                    attributes << ['style', (v_shape_style_base(z_index, @vertices) + style_addition).join]
         
     | 
| 
       18 
71 
     | 
    
         
             
                    attributes << ['o:button',    't']
         
     | 
| 
       19 
72 
     | 
    
         
             
                    attributes << ['fillcolor',   color]
         
     | 
| 
       20 
73 
     | 
    
         
             
                    attributes << ['strokecolor', 'windowText [64]']
         
     | 
| 
         @@ -81,7 +134,7 @@ module Writexlsx 
     | 
|
| 
       81 
134 
     | 
    
         | 
| 
       82 
135 
     | 
    
         
             
                    @writer.tag_elements('v:textbox', attributes) do
         
     | 
| 
       83 
136 
     | 
    
         
             
                      # Write the div element.
         
     | 
| 
       84 
     | 
    
         
            -
                      write_div('center', font)
         
     | 
| 
      
 137 
     | 
    
         
            +
                      write_div('center', @font)
         
     | 
| 
       85 
138 
     | 
    
         
             
                    end
         
     | 
| 
       86 
139 
     | 
    
         
             
                  end
         
     | 
| 
       87 
140 
     | 
    
         | 
| 
         @@ -118,7 +171,7 @@ module Writexlsx 
     | 
|
| 
       118 
171 
     | 
    
         
             
                  # Write the <x:FmlaMacro> element.
         
     | 
| 
       119 
172 
     | 
    
         
             
                  #
         
     | 
| 
       120 
173 
     | 
    
         
             
                  def write_fmla_macro
         
     | 
| 
       121 
     | 
    
         
            -
                    @writer.data_element('x:FmlaMacro', macro)
         
     | 
| 
      
 174 
     | 
    
         
            +
                    @writer.data_element('x:FmlaMacro', @macro)
         
     | 
| 
       122 
175 
     | 
    
         
             
                  end
         
     | 
| 
       123 
176 
     | 
    
         | 
| 
       124 
177 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -409,7 +409,7 @@ module Writexlsx 
     | 
|
| 
       409 
409 
     | 
    
         | 
| 
       410 
410 
     | 
    
         
             
                  def row_col_param_for_conditional_formatting(*args)
         
     | 
| 
       411 
411 
     | 
    
         
             
                    # Check for a cell reference in A1 notation and substitute row and column
         
     | 
| 
       412 
     | 
    
         
            -
                    user_range = if args[0].to_s =~  
     | 
| 
      
 412 
     | 
    
         
            +
                    user_range = if args[0].to_s =~ /^\D/ && (args[0] =~ /,/)
         
     | 
| 
       413 
413 
     | 
    
         
             
                                   # Check for a user defined multiple range like B3:K6,B8:K11.
         
     | 
| 
       414 
414 
     | 
    
         
             
                                   args[0].sub(/^=/, '').gsub(/\s*,\s*/, ' ').gsub("$", '')
         
     | 
| 
       415 
415 
     | 
    
         
             
                                 end
         
     | 
| 
         @@ -516,7 +516,7 @@ module Writexlsx 
     | 
|
| 
       516 
516 
     | 
    
         
             
                    end
         
     | 
| 
       517 
517 
     | 
    
         | 
| 
       518 
518 
     | 
    
         
             
                    # 'Between' and 'Not between' criteria require 2 values.
         
     | 
| 
       519 
     | 
    
         
            -
                    if  
     | 
| 
      
 519 
     | 
    
         
            +
                    if %w[between notBetween].include?(param[:criteria])
         
     | 
| 
       520 
520 
     | 
    
         
             
                      raise WriteXLSXOptionParameterError, "Invalid criteria : #{param[:criteria]}" unless param.has_key?(:minimum) || param.has_key?(:maximum)
         
     | 
| 
       521 
521 
     | 
    
         
             
                    else
         
     | 
| 
       522 
522 
     | 
    
         
             
                      param[:minimum] = nil
         
     | 
| 
         @@ -524,7 +524,7 @@ module Writexlsx 
     | 
|
| 
       524 
524 
     | 
    
         
             
                    end
         
     | 
| 
       525 
525 
     | 
    
         | 
| 
       526 
526 
     | 
    
         
             
                    # Convert date/times value if required.
         
     | 
| 
       527 
     | 
    
         
            -
                    raise WriteXLSXOptionParameterError if  
     | 
| 
      
 527 
     | 
    
         
            +
                    raise WriteXLSXOptionParameterError if %w[date time].include?(param[:type]) && !(convert_date_time_value(param, :value) || convert_date_time_value(param, :maximum))
         
     | 
| 
       528 
528 
     | 
    
         
             
                  end
         
     | 
| 
       529 
529 
     | 
    
         | 
| 
       530 
530 
     | 
    
         
             
                  def convert_date_time_if_required(val)
         
     | 
| 
         @@ -697,7 +697,7 @@ module Writexlsx 
     | 
|
| 
       697 
697 
     | 
    
         
             
                      max_data = user_props.size
         
     | 
| 
       698 
698 
     | 
    
         
             
                      max_data = total_icons - 1 if max_data >= total_icons
         
     | 
| 
       699 
699 
     | 
    
         | 
| 
       700 
     | 
    
         
            -
                      (0..max_data - 1).each do |i|
         
     | 
| 
      
 700 
     | 
    
         
            +
                      (0..(max_data - 1)).each do |i|
         
     | 
| 
       701 
701 
     | 
    
         
             
                        # Set the user defined 'value' property.
         
     | 
| 
       702 
702 
     | 
    
         
             
                        props[i][:value] = user_props[i][:value].to_s.sub(/^=/, '') if user_props[i][:value]
         
     | 
| 
       703 
703 
     | 
    
         | 
| 
         @@ -203,11 +203,9 @@ module Writexlsx 
     | 
|
| 
       203 
203 
     | 
    
         
             
                  # Write the rdrichvalue(*).xml file.
         
     | 
| 
       204 
204 
     | 
    
         
             
                  #
         
     | 
| 
       205 
205 
     | 
    
         
             
                  def write_rich_value_files
         
     | 
| 
       206 
     | 
    
         
            -
                    dir = @package_dir
         
     | 
| 
       207 
     | 
    
         
            -
             
     | 
| 
       208 
206 
     | 
    
         
             
                    return unless @workbook.has_embedded_images?
         
     | 
| 
       209 
207 
     | 
    
         | 
| 
       210 
     | 
    
         
            -
                    FileUtils.mkdir_p("#{ 
     | 
| 
      
 208 
     | 
    
         
            +
                    FileUtils.mkdir_p("#{@package_dir}/xl/richData")
         
     | 
| 
       211 
209 
     | 
    
         | 
| 
       212 
210 
     | 
    
         
             
                    write_rich_value_file
         
     | 
| 
       213 
211 
     | 
    
         
             
                    write_rich_value_structure_file
         
     | 
| 
         @@ -219,12 +217,11 @@ module Writexlsx 
     | 
|
| 
       219 
217 
     | 
    
         
             
                  # Write the rdrichvalue.xml file.
         
     | 
| 
       220 
218 
     | 
    
         
             
                  #
         
     | 
| 
       221 
219 
     | 
    
         
             
                  def write_rich_value_file
         
     | 
| 
       222 
     | 
    
         
            -
                    dir        = @package_dir
         
     | 
| 
       223 
220 
     | 
    
         
             
                    rich_value = Package::RichValue.new
         
     | 
| 
       224 
221 
     | 
    
         | 
| 
       225 
222 
     | 
    
         
             
                    rich_value.embedded_images = @workbook.embedded_images
         
     | 
| 
       226 
223 
     | 
    
         | 
| 
       227 
     | 
    
         
            -
                    rich_value.set_xml_writer("#{ 
     | 
| 
      
 224 
     | 
    
         
            +
                    rich_value.set_xml_writer("#{@package_dir}/xl/richData/rdrichvalue.xml")
         
     | 
| 
       228 
225 
     | 
    
         
             
                    rich_value.assemble_xml_file
         
     | 
| 
       229 
226 
     | 
    
         
             
                  end
         
     | 
| 
       230 
227 
     | 
    
         | 
| 
         @@ -232,12 +229,11 @@ module Writexlsx 
     | 
|
| 
       232 
229 
     | 
    
         
             
                  # Write the rdrichvaluestructure.xml file.
         
     | 
| 
       233 
230 
     | 
    
         
             
                  #
         
     | 
| 
       234 
231 
     | 
    
         
             
                  def write_rich_value_structure_file
         
     | 
| 
       235 
     | 
    
         
            -
                    dir        = @package_dir
         
     | 
| 
       236 
232 
     | 
    
         
             
                    rich_value = Package::RichValueStructure.new
         
     | 
| 
       237 
233 
     | 
    
         | 
| 
       238 
234 
     | 
    
         
             
                    rich_value.has_embedded_descriptions = @workbook.has_embedded_descriptions?
         
     | 
| 
       239 
235 
     | 
    
         | 
| 
       240 
     | 
    
         
            -
                    rich_value.set_xml_writer("#{ 
     | 
| 
      
 236 
     | 
    
         
            +
                    rich_value.set_xml_writer("#{@package_dir}/xl/richData/rdrichvaluestructure.xml")
         
     | 
| 
       241 
237 
     | 
    
         
             
                    rich_value.assemble_xml_file
         
     | 
| 
       242 
238 
     | 
    
         
             
                  end
         
     | 
| 
       243 
239 
     | 
    
         | 
| 
         @@ -246,9 +242,8 @@ module Writexlsx 
     | 
|
| 
       246 
242 
     | 
    
         
             
                  #
         
     | 
| 
       247 
243 
     | 
    
         
             
                  def write_rich_value_types_file
         
     | 
| 
       248 
244 
     | 
    
         
             
                    rich_value = Package::RichValueTypes.new
         
     | 
| 
       249 
     | 
    
         
            -
                    dir        = @package_dir
         
     | 
| 
       250 
245 
     | 
    
         | 
| 
       251 
     | 
    
         
            -
                    rich_value.set_xml_writer("#{ 
     | 
| 
      
 246 
     | 
    
         
            +
                    rich_value.set_xml_writer("#{@package_dir}/xl/richData/rdRichValueTypes.xml")
         
     | 
| 
       252 
247 
     | 
    
         
             
                    rich_value.assemble_xml_file
         
     | 
| 
       253 
248 
     | 
    
         
             
                  end
         
     | 
| 
       254 
249 
     | 
    
         | 
| 
         @@ -256,12 +251,11 @@ module Writexlsx 
     | 
|
| 
       256 
251 
     | 
    
         
             
                  # Write the rdrichvalue.xml file.
         
     | 
| 
       257 
252 
     | 
    
         
             
                  #
         
     | 
| 
       258 
253 
     | 
    
         
             
                  def write_rich_value_rel
         
     | 
| 
       259 
     | 
    
         
            -
                    dir        = @package_dir
         
     | 
| 
       260 
254 
     | 
    
         
             
                    rich_value = Package::RichValueRel.new
         
     | 
| 
       261 
255 
     | 
    
         | 
| 
       262 
256 
     | 
    
         
             
                    rich_value.value_count = @workbook.embedded_images.size
         
     | 
| 
       263 
257 
     | 
    
         | 
| 
       264 
     | 
    
         
            -
                    rich_value.set_xml_writer("#{ 
     | 
| 
      
 258 
     | 
    
         
            +
                    rich_value.set_xml_writer("#{@package_dir}/xl/richData/richValueRel.xml")
         
     | 
| 
       265 
259 
     | 
    
         
             
                    rich_value.assemble_xml_file
         
     | 
| 
       266 
260 
     | 
    
         
             
                  end
         
     | 
| 
       267 
261 
     | 
    
         | 
| 
         @@ -456,22 +450,21 @@ module Writexlsx 
     | 
|
| 
       456 
450 
     | 
    
         
             
                  def write_rich_value_rels_files
         
     | 
| 
       457 
451 
     | 
    
         
             
                    return if @workbook.embedded_images.empty?
         
     | 
| 
       458 
452 
     | 
    
         | 
| 
       459 
     | 
    
         
            -
                    dir  = @package_dir
         
     | 
| 
       460 
     | 
    
         
            -
             
     | 
| 
       461 
453 
     | 
    
         
             
                    # Create the .rels dirs.
         
     | 
| 
       462 
     | 
    
         
            -
                     
     | 
| 
      
 454 
     | 
    
         
            +
                    rich_value_rels_dir = "#{@package_dir}/xl/richData/_rels"
         
     | 
| 
      
 455 
     | 
    
         
            +
                    FileUtils.mkdir_p(rich_value_rels_dir)
         
     | 
| 
       463 
456 
     | 
    
         | 
| 
       464 
457 
     | 
    
         
             
                    rels = Package::Relationships.new
         
     | 
| 
       465 
458 
     | 
    
         | 
| 
       466 
459 
     | 
    
         
             
                    @workbook.embedded_images.each_with_index do |image_data, index|
         
     | 
| 
       467 
     | 
    
         
            -
                      file_type  = image_data 
     | 
| 
      
 460 
     | 
    
         
            +
                      file_type  = image_data.type
         
     | 
| 
       468 
461 
     | 
    
         
             
                      image_file = "../media/image#{index + 1}.#{file_type}"
         
     | 
| 
       469 
462 
     | 
    
         | 
| 
       470 
463 
     | 
    
         
             
                      rels.add_worksheet_relationship('/image', image_file)
         
     | 
| 
       471 
464 
     | 
    
         
             
                    end
         
     | 
| 
       472 
465 
     | 
    
         | 
| 
       473 
466 
     | 
    
         
             
                    # Create the .rels file.
         
     | 
| 
       474 
     | 
    
         
            -
                    rels.set_xml_writer("#{ 
     | 
| 
      
 467 
     | 
    
         
            +
                    rels.set_xml_writer("#{rich_value_rels_dir}/richValueRel.xml.rels")
         
     | 
| 
       475 
468 
     | 
    
         
             
                    rels.assemble_xml_file
         
     | 
| 
       476 
469 
     | 
    
         
             
                  end
         
     | 
| 
       477 
470 
     | 
    
         | 
| 
         @@ -481,32 +474,34 @@ module Writexlsx 
     | 
|
| 
       481 
474 
     | 
    
         
             
                  def add_image_files
         
     | 
| 
       482 
475 
     | 
    
         
             
                    index = 1
         
     | 
| 
       483 
476 
     | 
    
         | 
| 
       484 
     | 
    
         
            -
                    dir = "#{@package_dir}/xl/media"
         
     | 
| 
       485 
     | 
    
         
            -
             
     | 
| 
       486 
477 
     | 
    
         
             
                    @workbook.embedded_images.each do |image|
         
     | 
| 
       487 
     | 
    
         
            -
                       
     | 
| 
       488 
     | 
    
         
            -
                      FileUtils.cp(image[0], "#{dir}/image#{index}.#{image[1]}")
         
     | 
| 
       489 
     | 
    
         
            -
                      index += 1
         
     | 
| 
      
 478 
     | 
    
         
            +
                      index = write_image_x_xml_files(image, index)
         
     | 
| 
       490 
479 
     | 
    
         
             
                    end
         
     | 
| 
       491 
480 
     | 
    
         | 
| 
       492 
481 
     | 
    
         
             
                    @workbook.images.each do |image|
         
     | 
| 
       493 
     | 
    
         
            -
                       
     | 
| 
       494 
     | 
    
         
            -
                      FileUtils.cp(image[0], "#{dir}/image#{index}.#{image[1]}")
         
     | 
| 
       495 
     | 
    
         
            -
                      index += 1
         
     | 
| 
      
 482 
     | 
    
         
            +
                      index = write_image_x_xml_files(image, index)
         
     | 
| 
       496 
483 
     | 
    
         
             
                    end
         
     | 
| 
       497 
484 
     | 
    
         
             
                  end
         
     | 
| 
       498 
485 
     | 
    
         | 
| 
      
 486 
     | 
    
         
            +
                  def write_image_x_xml_files(image, index)
         
     | 
| 
      
 487 
     | 
    
         
            +
                    FileUtils.mkdir_p("#{@package_dir}/xl/media")
         
     | 
| 
      
 488 
     | 
    
         
            +
                    FileUtils.cp(
         
     | 
| 
      
 489 
     | 
    
         
            +
                      image.filename,
         
     | 
| 
      
 490 
     | 
    
         
            +
                      "#{@package_dir}/xl/media/image#{index}.#{image.type}"
         
     | 
| 
      
 491 
     | 
    
         
            +
                    )
         
     | 
| 
      
 492 
     | 
    
         
            +
                    index + 1
         
     | 
| 
      
 493 
     | 
    
         
            +
                  end
         
     | 
| 
      
 494 
     | 
    
         
            +
             
     | 
| 
       499 
495 
     | 
    
         
             
                  #
         
     | 
| 
       500 
496 
     | 
    
         
             
                  # Write the vbaProject.bin file.
         
     | 
| 
       501 
497 
     | 
    
         
             
                  #
         
     | 
| 
       502 
498 
     | 
    
         
             
                  def add_vba_project
         
     | 
| 
       503 
     | 
    
         
            -
                    dir = @package_dir
         
     | 
| 
       504 
499 
     | 
    
         
             
                    vba_project = @workbook.vba_project
         
     | 
| 
       505 
500 
     | 
    
         | 
| 
       506 
501 
     | 
    
         
             
                    return unless vba_project
         
     | 
| 
       507 
502 
     | 
    
         | 
| 
       508 
     | 
    
         
            -
                    FileUtils.mkdir_p("#{ 
     | 
| 
       509 
     | 
    
         
            -
                    FileUtils.copy(vba_project, "#{ 
     | 
| 
      
 503 
     | 
    
         
            +
                    FileUtils.mkdir_p("#{@package_dir}/xl")
         
     | 
| 
      
 504 
     | 
    
         
            +
                    FileUtils.copy(vba_project, "#{@package_dir}/xl/vbaProject.bin")
         
     | 
| 
       510 
505 
     | 
    
         
             
                  end
         
     | 
| 
       511 
506 
     | 
    
         
             
                end
         
     | 
| 
       512 
507 
     | 
    
         
             
              end
         
     | 
| 
         @@ -265,21 +265,10 @@ module Writexlsx 
     | 
|
| 
       265 
265 
     | 
    
         
             
                  #
         
     | 
| 
       266 
266 
     | 
    
         
             
                  # Write the <v:shape> element.
         
     | 
| 
       267 
267 
     | 
    
         
             
                  #
         
     | 
| 
       268 
     | 
    
         
            -
                  def write_image_shape(id, index,  
     | 
| 
       269 
     | 
    
         
            -
                    type       = '#_x0000_t75'
         
     | 
| 
       270 
     | 
    
         
            -
             
     | 
| 
       271 
     | 
    
         
            -
                    # Get the image parameters
         
     | 
| 
       272 
     | 
    
         
            -
                    width    = image_data[0]
         
     | 
| 
       273 
     | 
    
         
            -
                    height   = image_data[1]
         
     | 
| 
       274 
     | 
    
         
            -
                    name     = image_data[2]
         
     | 
| 
       275 
     | 
    
         
            -
                    position = image_data[3]
         
     | 
| 
       276 
     | 
    
         
            -
                    x_dpi    = image_data[4]
         
     | 
| 
       277 
     | 
    
         
            -
                    y_dpi    = image_data[5]
         
     | 
| 
       278 
     | 
    
         
            -
                    ref_id   = image_data[6]
         
     | 
| 
       279 
     | 
    
         
            -
             
     | 
| 
      
 268 
     | 
    
         
            +
                  def write_image_shape(id, index, image_property)
         
     | 
| 
       280 
269 
     | 
    
         
             
                    # Scale the height/width by the resolution, relative to 72dpi.
         
     | 
| 
       281 
     | 
    
         
            -
                    width  = width  * 72.0 / x_dpi
         
     | 
| 
       282 
     | 
    
         
            -
                    height = height * 72.0 / y_dpi
         
     | 
| 
      
 270 
     | 
    
         
            +
                    width  = image_property.width  * 72.0 / image_property.x_dpi
         
     | 
| 
      
 271 
     | 
    
         
            +
                    height = image_property.height * 72.0 / image_property.y_dpi
         
     | 
| 
       283 
272 
     | 
    
         | 
| 
       284 
273 
     | 
    
         
             
                    # Excel uses a rounding based around 72 and 96 dpi.
         
     | 
| 
       285 
274 
     | 
    
         
             
                    width  = 72 / 96.0 * ((width  * 96 / 72.0) + 0.25).to_i
         
     | 
| 
         @@ -288,13 +277,15 @@ module Writexlsx 
     | 
|
| 
       288 
277 
     | 
    
         
             
                    width = width.to_i if (width - width.to_i).abs < 0.1
         
     | 
| 
       289 
278 
     | 
    
         
             
                    height = height.to_i if (height - height.to_i).abs < 0.1
         
     | 
| 
       290 
279 
     | 
    
         | 
| 
      
 280 
     | 
    
         
            +
                    type = '#_x0000_t75'
         
     | 
| 
      
 281 
     | 
    
         
            +
             
     | 
| 
       291 
282 
     | 
    
         
             
                    style = [
         
     | 
| 
       292 
283 
     | 
    
         
             
                      "position:absolute", "margin-left:0", "margin-top:0",
         
     | 
| 
       293 
284 
     | 
    
         
             
                      "width:#{width}pt", "height:#{height}pt",
         
     | 
| 
       294 
285 
     | 
    
         
             
                      "z-index:#{index}"
         
     | 
| 
       295 
286 
     | 
    
         
             
                    ].join(';')
         
     | 
| 
       296 
287 
     | 
    
         
             
                    attributes = [
         
     | 
| 
       297 
     | 
    
         
            -
                      ['id',     position],
         
     | 
| 
      
 288 
     | 
    
         
            +
                      ['id',     image_property.position],
         
     | 
| 
       298 
289 
     | 
    
         
             
                      ['o:spid', "_x0000_s#{id}"],
         
     | 
| 
       299 
290 
     | 
    
         
             
                      ['type',   type],
         
     | 
| 
       300 
291 
     | 
    
         
             
                      ['style',  style]
         
     | 
| 
         @@ -302,7 +293,7 @@ module Writexlsx 
     | 
|
| 
       302 
293 
     | 
    
         | 
| 
       303 
294 
     | 
    
         
             
                    @writer.tag_elements('v:shape', attributes) do
         
     | 
| 
       304 
295 
     | 
    
         
             
                      # Write the v:imagedata element.
         
     | 
| 
       305 
     | 
    
         
            -
                      write_imagedata( 
     | 
| 
      
 296 
     | 
    
         
            +
                      write_imagedata(image_property)
         
     | 
| 
       306 
297 
     | 
    
         | 
| 
       307 
298 
     | 
    
         
             
                      # Write the o:lock element.
         
     | 
| 
       308 
299 
     | 
    
         
             
                      write_rotation_lock
         
     | 
| 
         @@ -312,10 +303,10 @@ module Writexlsx 
     | 
|
| 
       312 
303 
     | 
    
         
             
                  #
         
     | 
| 
       313 
304 
     | 
    
         
             
                  # Write the <v:imagedata> element.
         
     | 
| 
       314 
305 
     | 
    
         
             
                  #
         
     | 
| 
       315 
     | 
    
         
            -
                  def write_imagedata( 
     | 
| 
      
 306 
     | 
    
         
            +
                  def write_imagedata(image_property)
         
     | 
| 
       316 
307 
     | 
    
         
             
                    attributes = [
         
     | 
| 
       317 
     | 
    
         
            -
                      ['o:relid', "rId#{ 
     | 
| 
       318 
     | 
    
         
            -
                      ['o:title',  
     | 
| 
      
 308 
     | 
    
         
            +
                      ['o:relid', "rId#{image_property.ref_id}"],
         
     | 
| 
      
 309 
     | 
    
         
            +
                      ['o:title', image_property.body]
         
     | 
| 
       319 
310 
     | 
    
         
             
                    ]
         
     | 
| 
       320 
311 
     | 
    
         | 
| 
       321 
312 
     | 
    
         
             
                    @writer.empty_tag('v:imagedata', attributes)
         
     | 
    
        data/lib/write_xlsx/shape.rb
    CHANGED
    
    | 
         @@ -150,8 +150,9 @@ module Writexlsx 
     | 
|
| 
       150 
150 
     | 
    
         
             
                # Calculate the vertices that define the position of a shape object within
         
     | 
| 
       151 
151 
     | 
    
         
             
                # the worksheet in EMUs.  Save the vertices with the object.
         
     | 
| 
       152 
152 
     | 
    
         
             
                #
         
     | 
| 
       153 
     | 
    
         
            -
                # The vertices are expressed as English Metric Units (EMUs). 
     | 
| 
       154 
     | 
    
         
            -
                # EMUs per point. Therefore, 12,700 * 3 /4 = 9,525 
     | 
| 
      
 153 
     | 
    
         
            +
                # The vertices are expressed as English Metric Units (EMUs).
         
     | 
| 
      
 154 
     | 
    
         
            +
                # There are 12,700 EMUs per point. Therefore, 12,700 * 3 /4 = 9,525
         
     | 
| 
      
 155 
     | 
    
         
            +
                # EMUs per pixel.
         
     | 
| 
       155 
156 
     | 
    
         
             
                #
         
     | 
| 
       156 
157 
     | 
    
         
             
                def calc_position_emus(worksheet)
         
     | 
| 
       157 
158 
     | 
    
         
             
                  c_start, r_start,
         
     | 
    
        data/lib/write_xlsx/sparkline.rb
    CHANGED
    
    | 
         @@ -246,7 +246,7 @@ module Writexlsx 
     | 
|
| 
       246 
246 
     | 
    
         
             
                def write_sparklines  # :nodoc:
         
     | 
| 
       247 
247 
     | 
    
         
             
                  # Write the sparkline elements.
         
     | 
| 
       248 
248 
     | 
    
         
             
                  @writer.tag_elements('x14:sparklines') do
         
     | 
| 
       249 
     | 
    
         
            -
                    (0..count - 1).each do |i|
         
     | 
| 
      
 249 
     | 
    
         
            +
                    (0..(count - 1)).each do |i|
         
     | 
| 
       250 
250 
     | 
    
         
             
                      range    = @ranges[i]
         
     | 
| 
       251 
251 
     | 
    
         
             
                      location = @locations[i]
         
     | 
| 
       252 
252 
     | 
    
         | 
    
        data/lib/write_xlsx/utility.rb
    CHANGED
    
    | 
         @@ -27,6 +27,9 @@ module Writexlsx 
     | 
|
| 
       27 
27 
     | 
    
         
             
                  't'  =>  5, 'u' =>  8, 'v' =>  7, 'w' => 11, 'x' =>  7, 'y' =>  7,
         
     | 
| 
       28 
28 
     | 
    
         
             
                  'z'  =>  6, '{' =>  5, '|' =>  7, '}' =>  5, '~' =>  7
         
     | 
| 
       29 
29 
     | 
    
         
             
                }.freeze
         
     | 
| 
      
 30 
     | 
    
         
            +
                MAX_DIGIT_WIDTH    = 7    # For Calabri 11.  # :nodoc:
         
     | 
| 
      
 31 
     | 
    
         
            +
                PADDING            = 5                       # :nodoc:
         
     | 
| 
      
 32 
     | 
    
         
            +
                DEFAULT_COL_PIXELS = 64
         
     | 
| 
       30 
33 
     | 
    
         | 
| 
       31 
34 
     | 
    
         
             
                #
         
     | 
| 
       32 
35 
     | 
    
         
             
                # xl_rowcol_to_cell($row, col, row_absolute, col_absolute)
         
     | 
| 
         @@ -169,7 +172,7 @@ module Writexlsx 
     | 
|
| 
       169 
172 
     | 
    
         
             
                    if time =~ /^(\d\d):(\d\d)(:(\d\d(\.\d+)?))?/
         
     | 
| 
       170 
173 
     | 
    
         
             
                      hour   = ::Regexp.last_match(1).to_i
         
     | 
| 
       171 
174 
     | 
    
         
             
                      min    = ::Regexp.last_match(2).to_i
         
     | 
| 
       172 
     | 
    
         
            -
                      sec    = ::Regexp.last_match(4).to_f 
     | 
| 
      
 175 
     | 
    
         
            +
                      sec    = ::Regexp.last_match(4).to_f
         
     | 
| 
       173 
176 
     | 
    
         
             
                    else
         
     | 
| 
       174 
177 
     | 
    
         
             
                      return nil # Not a valid time format.
         
     | 
| 
       175 
178 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -226,7 +229,7 @@ module Writexlsx 
     | 
|
| 
       226 
229 
     | 
    
         | 
| 
       227 
230 
     | 
    
         
             
                  # Accumulate the number of days since the epoch.
         
     | 
| 
       228 
231 
     | 
    
         
             
                  days = day                               # Add days for current month
         
     | 
| 
       229 
     | 
    
         
            -
                  (0..month - 2).each do |m|
         
     | 
| 
      
 232 
     | 
    
         
            +
                  (0..(month - 2)).each do |m|
         
     | 
| 
       230 
233 
     | 
    
         
             
                    days += mdays[m]                      # Add days for past months
         
     | 
| 
       231 
234 
     | 
    
         
             
                  end
         
     | 
| 
       232 
235 
     | 
    
         
             
                  days += range * 365                      # Add days for past years
         
     | 
| 
         @@ -552,7 +555,7 @@ module Writexlsx 
     | 
|
| 
       552 
555 
     | 
    
         
             
                # Write the <x:Anchor> element.
         
     | 
| 
       553 
556 
     | 
    
         
             
                #
         
     | 
| 
       554 
557 
     | 
    
         
             
                def write_anchor
         
     | 
| 
       555 
     | 
    
         
            -
                  col_start, row_start, x1, y1, col_end, row_end, x2, y2 = vertices
         
     | 
| 
      
 558 
     | 
    
         
            +
                  col_start, row_start, x1, y1, col_end, row_end, x2, y2 = @vertices
         
     | 
| 
       556 
559 
     | 
    
         
             
                  data = [col_start, x1, row_start, y1, col_end, x2, row_end, y2].join(', ')
         
     | 
| 
       557 
560 
     | 
    
         | 
| 
       558 
561 
     | 
    
         
             
                  @writer.data_element('x:Anchor', data)
         
     | 
| 
         @@ -749,7 +752,7 @@ module Writexlsx 
     | 
|
| 
       749 
752 
     | 
    
         
             
                  hash[key.to_sym]
         
     | 
| 
       750 
753 
     | 
    
         
             
                end
         
     | 
| 
       751 
754 
     | 
    
         | 
| 
       752 
     | 
    
         
            -
                def  
     | 
| 
      
 755 
     | 
    
         
            +
                def palette_color_from_index(index)
         
     | 
| 
       753 
756 
     | 
    
         
             
                  # Adjust the colour index.
         
     | 
| 
       754 
757 
     | 
    
         
             
                  idx = index - 8
         
     | 
| 
       755 
758 
     | 
    
         | 
| 
         @@ -757,32 +760,6 @@ module Writexlsx 
     | 
|
| 
       757 
760 
     | 
    
         
             
                  sprintf("%02X%02X%02X", r, g, b)
         
     | 
| 
       758 
761 
     | 
    
         
             
                end
         
     | 
| 
       759 
762 
     | 
    
         | 
| 
       760 
     | 
    
         
            -
                #
         
     | 
| 
       761 
     | 
    
         
            -
                # Workbook の生成時のオプションハッシュを解析する
         
     | 
| 
       762 
     | 
    
         
            -
                #
         
     | 
| 
       763 
     | 
    
         
            -
                def process_workbook_options(*params)
         
     | 
| 
       764 
     | 
    
         
            -
                  case params.size
         
     | 
| 
       765 
     | 
    
         
            -
                  when 0
         
     | 
| 
       766 
     | 
    
         
            -
                    [{}, {}]
         
     | 
| 
       767 
     | 
    
         
            -
                  when 1 # one hash
         
     | 
| 
       768 
     | 
    
         
            -
                    options_keys = %i[tempdir date_1904 optimization excel2003_style strings_to_urls]
         
     | 
| 
       769 
     | 
    
         
            -
             
     | 
| 
       770 
     | 
    
         
            -
                    hash = params.first
         
     | 
| 
       771 
     | 
    
         
            -
                    options = hash.reject { |k, _v| !options_keys.include?(k) }
         
     | 
| 
       772 
     | 
    
         
            -
             
     | 
| 
       773 
     | 
    
         
            -
                    default_format_properties =
         
     | 
| 
       774 
     | 
    
         
            -
                      hash[:default_format_properties] ||
         
     | 
| 
       775 
     | 
    
         
            -
                      hash.reject { |k, _v| options_keys.include?(k) }
         
     | 
| 
       776 
     | 
    
         
            -
             
     | 
| 
       777 
     | 
    
         
            -
                    [options, default_format_properties.dup]
         
     | 
| 
       778 
     | 
    
         
            -
                  when 2 # array which includes options and default_format_properties
         
     | 
| 
       779 
     | 
    
         
            -
                    options, default_format_properties = params
         
     | 
| 
       780 
     | 
    
         
            -
                    default_format_properties ||= {}
         
     | 
| 
       781 
     | 
    
         
            -
             
     | 
| 
       782 
     | 
    
         
            -
                    [options.dup, default_format_properties.dup]
         
     | 
| 
       783 
     | 
    
         
            -
                  end
         
     | 
| 
       784 
     | 
    
         
            -
                end
         
     | 
| 
       785 
     | 
    
         
            -
             
     | 
| 
       786 
763 
     | 
    
         
             
                #
         
     | 
| 
       787 
764 
     | 
    
         
             
                # Convert user defined font values into private hash values.
         
     | 
| 
       788 
765 
     | 
    
         
             
                #
         
     | 
| 
         @@ -960,7 +937,7 @@ module Writexlsx 
     | 
|
| 
       960 
937 
     | 
    
         
             
                    index = Format.color(color_code)
         
     | 
| 
       961 
938 
     | 
    
         
             
                    raise "Unknown color '#{color_code}' used in chart formatting." unless index
         
     | 
| 
       962 
939 
     | 
    
         | 
| 
       963 
     | 
    
         
            -
                     
     | 
| 
      
 940 
     | 
    
         
            +
                    palette_color_from_index(index)
         
     | 
| 
       964 
941 
     | 
    
         
             
                  end
         
     | 
| 
       965 
942 
     | 
    
         
             
                end
         
     | 
| 
       966 
943 
     | 
    
         | 
| 
         @@ -988,178 +965,6 @@ module Writexlsx 
     | 
|
| 
       988 
965 
     | 
    
         
             
                def write_a_end_para_rpr # :nodoc:
         
     | 
| 
       989 
966 
     | 
    
         
             
                  @writer.empty_tag('a:endParaRPr', [%w[lang en-US]])
         
     | 
| 
       990 
967 
     | 
    
         
             
                end
         
     | 
| 
       991 
     | 
    
         
            -
             
     | 
| 
       992 
     | 
    
         
            -
                #
         
     | 
| 
       993 
     | 
    
         
            -
                # Extract information from the image file such as dimension, type, filename,
         
     | 
| 
       994 
     | 
    
         
            -
                # and extension. Also keep track of previously seen images to optimise out
         
     | 
| 
       995 
     | 
    
         
            -
                # any duplicates.
         
     | 
| 
       996 
     | 
    
         
            -
                #
         
     | 
| 
       997 
     | 
    
         
            -
                def get_image_properties(filename)
         
     | 
| 
       998 
     | 
    
         
            -
                  # Note the image_id, and previous_images mechanism isn't currently used.
         
     | 
| 
       999 
     | 
    
         
            -
                  x_dpi = 96
         
     | 
| 
       1000 
     | 
    
         
            -
                  y_dpi = 96
         
     | 
| 
       1001 
     | 
    
         
            -
             
     | 
| 
       1002 
     | 
    
         
            -
                  workbook = @workbook || self
         
     | 
| 
       1003 
     | 
    
         
            -
             
     | 
| 
       1004 
     | 
    
         
            -
                  # Open the image file and import the data.
         
     | 
| 
       1005 
     | 
    
         
            -
                  data = File.binread(filename)
         
     | 
| 
       1006 
     | 
    
         
            -
                  md5  = Digest::MD5.hexdigest(data)
         
     | 
| 
       1007 
     | 
    
         
            -
                  if data.unpack1('x A3') == 'PNG'
         
     | 
| 
       1008 
     | 
    
         
            -
                    # Test for PNGs.
         
     | 
| 
       1009 
     | 
    
         
            -
                    type, width, height, x_dpi, y_dpi = process_png(data)
         
     | 
| 
       1010 
     | 
    
         
            -
                    workbook.image_types[:png] = 1
         
     | 
| 
       1011 
     | 
    
         
            -
                  elsif data.unpack1('n') == 0xFFD8
         
     | 
| 
       1012 
     | 
    
         
            -
                    # Test for JPEG files.
         
     | 
| 
       1013 
     | 
    
         
            -
                    type, width, height, x_dpi, y_dpi = process_jpg(data, filename)
         
     | 
| 
       1014 
     | 
    
         
            -
                    workbook.image_types[:jpeg] = 1
         
     | 
| 
       1015 
     | 
    
         
            -
                  elsif data.unpack1('A4') == 'GIF8'
         
     | 
| 
       1016 
     | 
    
         
            -
                    # Test for GIFs.
         
     | 
| 
       1017 
     | 
    
         
            -
                    type, width, height, x_dpi, y_dpi = process_gif(data, filename)
         
     | 
| 
       1018 
     | 
    
         
            -
                    workbook.image_types[:gif] = 1
         
     | 
| 
       1019 
     | 
    
         
            -
                  elsif data.unpack1('A2') == 'BM'
         
     | 
| 
       1020 
     | 
    
         
            -
                    # Test for BMPs.
         
     | 
| 
       1021 
     | 
    
         
            -
                    type, width, height = process_bmp(data, filename)
         
     | 
| 
       1022 
     | 
    
         
            -
                    workbook.image_types[:bmp] = 1
         
     | 
| 
       1023 
     | 
    
         
            -
                  else
         
     | 
| 
       1024 
     | 
    
         
            -
                    # TODO. Add Image::Size to support other types.
         
     | 
| 
       1025 
     | 
    
         
            -
                    raise "Unsupported image format for file: #{filename}\n"
         
     | 
| 
       1026 
     | 
    
         
            -
                  end
         
     | 
| 
       1027 
     | 
    
         
            -
             
     | 
| 
       1028 
     | 
    
         
            -
                  # Set a default dpi for images with 0 dpi.
         
     | 
| 
       1029 
     | 
    
         
            -
                  x_dpi = 96 if x_dpi == 0
         
     | 
| 
       1030 
     | 
    
         
            -
                  y_dpi = 96 if y_dpi == 0
         
     | 
| 
       1031 
     | 
    
         
            -
             
     | 
| 
       1032 
     | 
    
         
            -
                  [type, width, height, File.basename(filename), x_dpi, y_dpi, md5]
         
     | 
| 
       1033 
     | 
    
         
            -
                end
         
     | 
| 
       1034 
     | 
    
         
            -
             
     | 
| 
       1035 
     | 
    
         
            -
                #
         
     | 
| 
       1036 
     | 
    
         
            -
                # Extract width and height information from a PNG file.
         
     | 
| 
       1037 
     | 
    
         
            -
                #
         
     | 
| 
       1038 
     | 
    
         
            -
                def process_png(data)
         
     | 
| 
       1039 
     | 
    
         
            -
                  type   = 'png'
         
     | 
| 
       1040 
     | 
    
         
            -
                  width  = 0
         
     | 
| 
       1041 
     | 
    
         
            -
                  height = 0
         
     | 
| 
       1042 
     | 
    
         
            -
                  x_dpi  = 96
         
     | 
| 
       1043 
     | 
    
         
            -
                  y_dpi  = 96
         
     | 
| 
       1044 
     | 
    
         
            -
             
     | 
| 
       1045 
     | 
    
         
            -
                  offset = 8
         
     | 
| 
       1046 
     | 
    
         
            -
                  data_length = data.size
         
     | 
| 
       1047 
     | 
    
         
            -
             
     | 
| 
       1048 
     | 
    
         
            -
                  # Search through the image data to read the height and width in th the
         
     | 
| 
       1049 
     | 
    
         
            -
                  # IHDR element. Also read the DPI in the pHYs element.
         
     | 
| 
       1050 
     | 
    
         
            -
                  while offset < data_length
         
     | 
| 
       1051 
     | 
    
         
            -
             
     | 
| 
       1052 
     | 
    
         
            -
                    length = data[offset + 0, 4].unpack1("N")
         
     | 
| 
       1053 
     | 
    
         
            -
                    png_type   = data[offset + 4, 4].unpack1("A4")
         
     | 
| 
       1054 
     | 
    
         
            -
             
     | 
| 
       1055 
     | 
    
         
            -
                    case png_type
         
     | 
| 
       1056 
     | 
    
         
            -
                    when "IHDR"
         
     | 
| 
       1057 
     | 
    
         
            -
                      width  = data[offset + 8, 4].unpack1("N")
         
     | 
| 
       1058 
     | 
    
         
            -
                      height = data[offset + 12, 4].unpack1("N")
         
     | 
| 
       1059 
     | 
    
         
            -
                    when "pHYs"
         
     | 
| 
       1060 
     | 
    
         
            -
                      x_ppu = data[offset +  8, 4].unpack1("N")
         
     | 
| 
       1061 
     | 
    
         
            -
                      y_ppu = data[offset + 12, 4].unpack1("N")
         
     | 
| 
       1062 
     | 
    
         
            -
                      units = data[offset + 16, 1].unpack1("C")
         
     | 
| 
       1063 
     | 
    
         
            -
             
     | 
| 
       1064 
     | 
    
         
            -
                      if units == 1
         
     | 
| 
       1065 
     | 
    
         
            -
                        x_dpi = x_ppu * 0.0254
         
     | 
| 
       1066 
     | 
    
         
            -
                        y_dpi = y_ppu * 0.0254
         
     | 
| 
       1067 
     | 
    
         
            -
                      end
         
     | 
| 
       1068 
     | 
    
         
            -
                    end
         
     | 
| 
       1069 
     | 
    
         
            -
             
     | 
| 
       1070 
     | 
    
         
            -
                    offset = offset + length + 12
         
     | 
| 
       1071 
     | 
    
         
            -
             
     | 
| 
       1072 
     | 
    
         
            -
                    break if png_type == "IEND"
         
     | 
| 
       1073 
     | 
    
         
            -
                  end
         
     | 
| 
       1074 
     | 
    
         
            -
                  raise "#{filename}: no size data found in png image.\n" unless height
         
     | 
| 
       1075 
     | 
    
         
            -
             
     | 
| 
       1076 
     | 
    
         
            -
                  [type, width, height, x_dpi, y_dpi]
         
     | 
| 
       1077 
     | 
    
         
            -
                end
         
     | 
| 
       1078 
     | 
    
         
            -
             
     | 
| 
       1079 
     | 
    
         
            -
                def process_jpg(data, filename)
         
     | 
| 
       1080 
     | 
    
         
            -
                  type     = 'jpeg'
         
     | 
| 
       1081 
     | 
    
         
            -
                  x_dpi    = 96
         
     | 
| 
       1082 
     | 
    
         
            -
                  y_dpi    = 96
         
     | 
| 
       1083 
     | 
    
         
            -
             
     | 
| 
       1084 
     | 
    
         
            -
                  offset = 2
         
     | 
| 
       1085 
     | 
    
         
            -
                  data_length = data.bytesize
         
     | 
| 
       1086 
     | 
    
         
            -
             
     | 
| 
       1087 
     | 
    
         
            -
                  # Search through the image data to read the JPEG markers.
         
     | 
| 
       1088 
     | 
    
         
            -
                  while offset < data_length
         
     | 
| 
       1089 
     | 
    
         
            -
                    marker  = data[offset + 0, 2].unpack1("n")
         
     | 
| 
       1090 
     | 
    
         
            -
                    length  = data[offset + 2, 2].unpack1("n")
         
     | 
| 
       1091 
     | 
    
         
            -
             
     | 
| 
       1092 
     | 
    
         
            -
                    # Read the height and width in the 0xFFCn elements
         
     | 
| 
       1093 
     | 
    
         
            -
                    # (Except C4, C8 and CC which aren't SOF markers).
         
     | 
| 
       1094 
     | 
    
         
            -
                    if (marker & 0xFFF0) == 0xFFC0 &&
         
     | 
| 
       1095 
     | 
    
         
            -
                       marker != 0xFFC4 && marker != 0xFFCC
         
     | 
| 
       1096 
     | 
    
         
            -
                      height = data[offset + 5, 2].unpack1("n")
         
     | 
| 
       1097 
     | 
    
         
            -
                      width  = data[offset + 7, 2].unpack1("n")
         
     | 
| 
       1098 
     | 
    
         
            -
                    end
         
     | 
| 
       1099 
     | 
    
         
            -
             
     | 
| 
       1100 
     | 
    
         
            -
                    # Read the DPI in the 0xFFE0 element.
         
     | 
| 
       1101 
     | 
    
         
            -
                    if marker == 0xFFE0
         
     | 
| 
       1102 
     | 
    
         
            -
                      units     = data[offset + 11, 1].unpack1("C")
         
     | 
| 
       1103 
     | 
    
         
            -
                      x_density = data[offset + 12, 2].unpack1("n")
         
     | 
| 
       1104 
     | 
    
         
            -
                      y_density = data[offset + 14, 2].unpack1("n")
         
     | 
| 
       1105 
     | 
    
         
            -
             
     | 
| 
       1106 
     | 
    
         
            -
                      if units == 1
         
     | 
| 
       1107 
     | 
    
         
            -
                        x_dpi = x_density
         
     | 
| 
       1108 
     | 
    
         
            -
                        y_dpi = y_density
         
     | 
| 
       1109 
     | 
    
         
            -
                      elsif units == 2
         
     | 
| 
       1110 
     | 
    
         
            -
                        x_dpi = x_density * 2.54
         
     | 
| 
       1111 
     | 
    
         
            -
                        y_dpi = y_density * 2.54
         
     | 
| 
       1112 
     | 
    
         
            -
                      end
         
     | 
| 
       1113 
     | 
    
         
            -
                    end
         
     | 
| 
       1114 
     | 
    
         
            -
             
     | 
| 
       1115 
     | 
    
         
            -
                    offset += length + 2
         
     | 
| 
       1116 
     | 
    
         
            -
                    break if marker == 0xFFDA
         
     | 
| 
       1117 
     | 
    
         
            -
                  end
         
     | 
| 
       1118 
     | 
    
         
            -
             
     | 
| 
       1119 
     | 
    
         
            -
                  raise "#{filename}: no size data found in jpeg image.\n" unless height
         
     | 
| 
       1120 
     | 
    
         
            -
             
     | 
| 
       1121 
     | 
    
         
            -
                  [type, width, height, x_dpi, y_dpi]
         
     | 
| 
       1122 
     | 
    
         
            -
                end
         
     | 
| 
       1123 
     | 
    
         
            -
             
     | 
| 
       1124 
     | 
    
         
            -
                #
         
     | 
| 
       1125 
     | 
    
         
            -
                # Extract width and height information from a GIF file.
         
     | 
| 
       1126 
     | 
    
         
            -
                #
         
     | 
| 
       1127 
     | 
    
         
            -
                def process_gif(data, filename)
         
     | 
| 
       1128 
     | 
    
         
            -
                  type  = 'gif'
         
     | 
| 
       1129 
     | 
    
         
            -
                  x_dpi = 96
         
     | 
| 
       1130 
     | 
    
         
            -
                  y_dpi = 96
         
     | 
| 
       1131 
     | 
    
         
            -
             
     | 
| 
       1132 
     | 
    
         
            -
                  width  = data[6, 2].unpack1("v")
         
     | 
| 
       1133 
     | 
    
         
            -
                  height = data[8, 2].unpack1("v")
         
     | 
| 
       1134 
     | 
    
         
            -
             
     | 
| 
       1135 
     | 
    
         
            -
                  raise "#{filename}: no size data found in gif image.\n" if height.nil?
         
     | 
| 
       1136 
     | 
    
         
            -
             
     | 
| 
       1137 
     | 
    
         
            -
                  [type, width, height, x_dpi, y_dpi]
         
     | 
| 
       1138 
     | 
    
         
            -
                end
         
     | 
| 
       1139 
     | 
    
         
            -
             
     | 
| 
       1140 
     | 
    
         
            -
                # Extract width and height information from a BMP file.
         
     | 
| 
       1141 
     | 
    
         
            -
                def process_bmp(data, filename)       # :nodoc:
         
     | 
| 
       1142 
     | 
    
         
            -
                  type     = 'bmp'
         
     | 
| 
       1143 
     | 
    
         
            -
             
     | 
| 
       1144 
     | 
    
         
            -
                  # Check that the file is big enough to be a bitmap.
         
     | 
| 
       1145 
     | 
    
         
            -
                  raise "#{filename} doesn't contain enough data." if data.bytesize <= 0x36
         
     | 
| 
       1146 
     | 
    
         
            -
             
     | 
| 
       1147 
     | 
    
         
            -
                  # Read the bitmap width and height. Verify the sizes.
         
     | 
| 
       1148 
     | 
    
         
            -
                  width, height = data.unpack("x18 V2")
         
     | 
| 
       1149 
     | 
    
         
            -
                  raise "#{filename}: largest image width #{width} supported is 65k." if width > 0xFFFF
         
     | 
| 
       1150 
     | 
    
         
            -
                  raise "#{filename}: largest image height supported is 65k." if height > 0xFFFF
         
     | 
| 
       1151 
     | 
    
         
            -
             
     | 
| 
       1152 
     | 
    
         
            -
                  # Read the bitmap planes and bpp data. Verify them.
         
     | 
| 
       1153 
     | 
    
         
            -
                  planes, bitcount = data.unpack("x26 v2")
         
     | 
| 
       1154 
     | 
    
         
            -
                  raise "#{filename} isn't a 24bit true color bitmap." unless bitcount == 24
         
     | 
| 
       1155 
     | 
    
         
            -
                  raise "#{filename}: only 1 plane supported in bitmap image." unless planes == 1
         
     | 
| 
       1156 
     | 
    
         
            -
             
     | 
| 
       1157 
     | 
    
         
            -
                  # Read the bitmap compression. Verify compression.
         
     | 
| 
       1158 
     | 
    
         
            -
                  compression = data.unpack1("x30 V")
         
     | 
| 
       1159 
     | 
    
         
            -
                  raise "#{filename}: compression not supported in bitmap image." unless compression == 0
         
     | 
| 
       1160 
     | 
    
         
            -
             
     | 
| 
       1161 
     | 
    
         
            -
                  [type, width, height]
         
     | 
| 
       1162 
     | 
    
         
            -
                end
         
     | 
| 
       1163 
968 
     | 
    
         
             
              end
         
     | 
| 
       1164 
969 
     | 
    
         | 
| 
       1165 
970 
     | 
    
         
             
              module WriteDPtPoint
         
     | 
    
        data/lib/write_xlsx/version.rb
    CHANGED