lib/write_xlsx/worksheet.rb in write_xlsx-1.11.2 vs lib/write_xlsx/worksheet.rb in write_xlsx-1.12.0
- old
+ new
@@ -111,11 +111,12 @@
@shape_hash = {}
@drawing_rels = {}
@drawing_rels_id = 0
@vml_drawing_rels = {}
@vml_drawing_rels_id = 0
- @has_dynamic_arrays = false
+ @has_dynamic_functions = false
+ @has_embedded_images = false
@use_future_functions = false
@header_images = []
@footer_images = []
@@ -158,10 +159,12 @@
self.margins_top_bottom = 1
@page_setup.margin_header = 0.5
@page_setup.margin_footer = 0.5
@page_setup.header_footer_aligns = false
end
+
+ @embedded_image_indexes = @workbook.embedded_image_indexes
end
def set_xml_writer(filename) # :nodoc:
@writer.set_xml_writer(filename)
end
@@ -1444,10 +1447,11 @@
formula = expand_formula(formula, 'GAMMA\(')
formula = expand_formula(formula, 'GAUSS\(')
formula = expand_formula(formula, 'HYPGEOM.DIST\(')
formula = expand_formula(formula, 'IFNA\(')
formula = expand_formula(formula, 'IFS\(')
+ formula = expand_formula(formula, 'IMAGE\(')
formula = expand_formula(formula, 'IMCOSH\(')
formula = expand_formula(formula, 'IMCOT\(')
formula = expand_formula(formula, 'IMCSCH\(')
formula = expand_formula(formula, 'IMCSC\(')
formula = expand_formula(formula, 'IMSECH\(')
@@ -1534,11 +1538,11 @@
_value = value
end
raise WriteXLSXInsufficientArgumentError if [_row, _col, _formula].include?(nil)
# Check for dynamic array functions.
- regex = /\bLET\(|\bSORT\(|\bLAMBDA\(|\bSINGLE\(|\bSORTBY\(|\bUNIQUE\(|\bXMATCH\(|\bFILTER\(|\bXLOOKUP\(|\bSEQUENCE\(|\bRANDARRAY\(|\bANCHORARRAY\(/
+ regex = /\bANCHORARRAY\(|\bBYCOL\(|\bBYROW\(|\bCHOOSECOLS\(|\bCHOOSEROWS\(|\bDROP\(|\bEXPAND\(|\bFILTER\(|\bHSTACK\(|\bLAMBDA\(|\bMAKEARRAY\(|\bMAP\(|\bRANDARRAY\(|\bREDUCE\(|\bSCAN\(|\bSEQUENCE\(|\bSINGLE\(|\bSORT\(|\bSORTBY\(|\bSWITCH\(|\bTAKE\(|\bTEXTSPLIT\(|\bTOCOL\(|\bTOROW\(|\bUNIQUE\(|\bVSTACK\(|\bWRAPCOLS\(|\bWRAPROWS\(|\bXLOOKUP\(/
if _formula =~ regex
return write_dynamic_array_formula(
_row, _col, _row, _col, _formula, _format, _value
)
end
@@ -1547,11 +1551,11 @@
if _formula =~ /^\{=.*\}$/
write_array_formula(_row, _col, _row, _col, _formula, _format, _value)
else
check_dimensions(_row, _col)
store_row_col_max_min_values(_row, _col)
- _formula = _formula.sub(/^=/, '')
+ _formula = prepare_formula(_formula)
store_data_to_table(FormulaCellData.new(_formula, _format, _value), _row, _col)
end
end
@@ -1632,11 +1636,11 @@
#
# Write a dynamic formula to the specified row and column (zero indexed).
#
def write_dynamic_array_formula(row1, col1, row2 = nil, col2 = nil, formula = nil, format = nil, value = nil)
write_array_formula_base('d', row1, col1, row2, col2, formula, format, value)
- @has_dynamic_arrays = true
+ @has_dynamic_functions = true
end
#
# write_boolean(row, col, val, format)
#
@@ -1780,25 +1784,27 @@
# the invisible link. The visible label is the same as the link unless
# an alternative label is specified. The label parameter is optional.
# The label is written using the {#write()}[#method-i-write] method. Therefore it is
# possible to write strings, numbers or formulas as labels.
#
- def write_url(row, col, url = nil, format = nil, str = nil, tip = nil)
+ def write_url(row, col, url = nil, format = nil, str = nil, tip = nil, ignore_write_string = false)
# Check for a cell reference in A1 notation and substitute row and column
if (row_col_array = row_col_notation(row))
- _row, _col = row_col_array
- _url = col
- _format = url
- _str = format
- _tip = str
+ _row, _col = row_col_array
+ _url = col
+ _format = url
+ _str = format
+ _tip = str
+ _ignore_write_string = tip
else
- _row = row
- _col = col
- _url = url
- _format = format
- _str = str
- _tip = tip
+ _row = row
+ _col = col
+ _url = url
+ _format = format
+ _str = str
+ _tip = tip
+ _ignore_write_string = ignore_write_string
end
_format, _str = _str, _format if _str.respond_to?(:xf_index) || !_format.respond_to?(:xf_index)
raise WriteXLSXInsufficientArgumentError if [_row, _col, _url].include?(nil)
# Check that row and col are valid and store max and min values
@@ -1812,11 +1818,11 @@
# Add the default URL format.
_format ||= @default_url_format
# Write the hyperlink string.
- write_string(_row, _col, hyperlink.str, _format)
+ write_string(_row, _col, hyperlink.str, _format) unless _ignore_write_string
end
#
# :call-seq:
# write_date_time (row, col, date_string [ , format ])
@@ -1958,10 +1964,69 @@
x_scale, y_scale, url, tip, anchor, description, decorative
]
end
#
+ # Embed an image into the worksheet.
+ #
+ def embed_image(row, col, filename, options = nil)
+ # Check for a cell reference in A1 notation and substitute row and column.
+ if (row_col_array = row_col_notation(row))
+ _row, _col = row_col_array
+ image = col
+ _options = filename
+ else
+ _row = row
+ _col = col
+ image = filename
+ _options = options
+ end
+ xf, url, tip, description, decorative = []
+
+ raise WriteXLSXInsufficientArgumentError if [_row, _col, image].include?(nil)
+ raise "Couldn't locate #{image}" unless File.exist?(image)
+
+ # Check that row and col are valid and store max and min values
+ check_dimensions(_row, _col)
+ store_row_col_max_min_values(_row, _col)
+
+ if options
+ xf = options[:cell_format]
+ url = options[:url]
+ tip = options[:tip]
+ description = options[:description]
+ decorative = options[:decorative]
+ end
+
+ # Write the url without writing a string.
+ if url
+ xf ||= @default_url_format
+
+ write_url(row, col, url, xf, nil, tip, true)
+ end
+
+ # Get the image properties, mainly for the type and checksum.
+ image_properties = get_image_properties(image)
+ type = image_properties[0]
+ md5 = image_properties[6]
+
+ # Check for duplicate images.
+ image_index = @embedded_image_indexes[md5]
+
+ unless ptrue?(image_index)
+ @workbook.embedded_images << [image, type, description, decorative]
+
+ image_index = @workbook.embedded_images.size
+ @embedded_image_indexes[md5] = image_index
+ end
+
+ # Write the cell placeholder.
+ store_data_to_table(EmbedImageCellData.new(image_index, xf), _row, _col)
+ @has_embedded_images = true
+ end
+
+ #
# :call-seq:
# repeat_formula(row, column, formula [ , format ])
#
# Deprecated. This is a writeexcel gem's method that is no longer
# required by WriteXLSX.
@@ -2797,14 +2862,18 @@
sparkline.write_sparkline_group(@writer)
end
end
end
- def has_dynamic_arrays?
- @has_dynamic_arrays
+ def has_dynamic_functions?
+ @has_dynamic_functions
end
+ def has_embedded_images?
+ @has_embedded_images
+ end
+
private
#
# Compare adjacent column information structures.
#
@@ -3276,10 +3345,11 @@
@drawing_links << [rel_type, target, target_mode] if target && !@drawing_rels[url]
drawing.url_rel_index = drawing_rel_index(url)
end
@drawing_links << ['/image', "../media/image#{image_id}.#{image_type}"] unless @drawing_rels[md5]
+
drawing.rel_index = drawing_rel_index(md5)
end
public :prepare_image
def prepare_header_image(image_id, width, height, name, image_type, position, x_dpi, y_dpi, md5)
@@ -4254,12 +4324,13 @@
# Get the link data for this cell.
link = @hyperlinks[row_num][col_num]
# If the cell isn't a string then we have to add the url as
# the string to display
- if ptrue?(@cell_data_table) &&
- ptrue?(@cell_data_table[row_num]) &&
- ptrue?(@cell_data_table[row_num][col_num]) && @cell_data_table[row_num][col_num].display_url_string?
+ if ptrue?(@cell_data_table) &&
+ ptrue?(@cell_data_table[row_num]) &&
+ ptrue?(@cell_data_table[row_num][col_num]) &&
+ @cell_data_table[row_num][col_num].display_url_string?
link.display_on
end
if link.respond_to?(:external_hyper_link)
# External link with rel file relationship.