write_xlsx 1.11.2 → 1.12.1
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 +3 -0
- data/Changes +30 -0
- data/README.md +1 -1
- data/lib/write_xlsx/format.rb +5 -5
- data/lib/write_xlsx/package/content_types.rb +22 -0
- data/lib/write_xlsx/package/metadata.rb +139 -22
- data/lib/write_xlsx/package/packager.rb +120 -3
- data/lib/write_xlsx/package/relationships.rb +25 -0
- data/lib/write_xlsx/package/rich_value.rb +70 -0
- data/lib/write_xlsx/package/rich_value_rel.rb +70 -0
- data/lib/write_xlsx/package/rich_value_structure.rb +83 -0
- data/lib/write_xlsx/package/rich_value_types.rb +103 -0
- data/lib/write_xlsx/utility.rb +172 -0
- data/lib/write_xlsx/version.rb +1 -1
- data/lib/write_xlsx/workbook.rb +46 -166
- data/lib/write_xlsx/worksheet/cell_data.rb +19 -0
- data/lib/write_xlsx/worksheet/hyperlink.rb +2 -1
- data/lib/write_xlsx/worksheet.rb +93 -22
- metadata +7 -3
data/lib/write_xlsx/workbook.rb
CHANGED
@@ -35,6 +35,9 @@ module Writexlsx
|
|
35
35
|
attr_reader :max_url_length # :nodoc:
|
36
36
|
attr_reader :strings_to_urls # :nodoc:
|
37
37
|
attr_reader :read_only # :nodoc:
|
38
|
+
attr_reader :embedded_image_indexes # :nodec:
|
39
|
+
attr_reader :embedded_images # :nodoc:
|
40
|
+
attr_reader :embedded_descriptions # :nodoc:
|
38
41
|
|
39
42
|
def initialize(file, *option_params)
|
40
43
|
options, default_formats = process_workbook_options(*option_params)
|
@@ -80,6 +83,9 @@ module Writexlsx
|
|
80
83
|
@has_comments = false
|
81
84
|
@read_only = 0
|
82
85
|
@has_metadata = false
|
86
|
+
@has_embedded_images = false
|
87
|
+
@has_embedded_descriptions = false
|
88
|
+
|
83
89
|
if options[:max_url_length]
|
84
90
|
@max_url_length = options[:max_url_length]
|
85
91
|
|
@@ -88,6 +94,10 @@ module Writexlsx
|
|
88
94
|
# Structures for the shared strings data.
|
89
95
|
@shared_strings = Package::SharedStrings.new
|
90
96
|
|
97
|
+
# Structures for embedded images.
|
98
|
+
@embedded_image_indexes = {}
|
99
|
+
@embedded_images = []
|
100
|
+
|
91
101
|
# Formula calculation default settings.
|
92
102
|
@calc_id = 124519
|
93
103
|
@calc_mode = 'auto'
|
@@ -530,6 +540,10 @@ module Writexlsx
|
|
530
540
|
!!@date_1904
|
531
541
|
end
|
532
542
|
|
543
|
+
def has_dynamic_functions?
|
544
|
+
@has_dynamic_functions
|
545
|
+
end
|
546
|
+
|
533
547
|
#
|
534
548
|
# Add a string to the shared string table, if it isn't already there, and
|
535
549
|
# return the string index.
|
@@ -597,6 +611,14 @@ module Writexlsx
|
|
597
611
|
@has_metadata
|
598
612
|
end
|
599
613
|
|
614
|
+
def has_embedded_images?
|
615
|
+
@has_embedded_images
|
616
|
+
end
|
617
|
+
|
618
|
+
def has_embedded_descriptions?
|
619
|
+
@has_embedded_descriptions
|
620
|
+
end
|
621
|
+
|
600
622
|
private
|
601
623
|
|
602
624
|
def filename
|
@@ -1226,10 +1248,11 @@ module Writexlsx
|
|
1226
1248
|
#
|
1227
1249
|
def prepare_metadata
|
1228
1250
|
@worksheets.each do |sheet|
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1251
|
+
next unless sheet.has_dynamic_functions? || sheet.has_embedded_images?
|
1252
|
+
|
1253
|
+
@has_metadata = true
|
1254
|
+
@has_dynamic_functions ||= sheet.has_dynamic_functions?
|
1255
|
+
@has_embedded_images ||= sheet.has_embedded_images?
|
1233
1256
|
end
|
1234
1257
|
end
|
1235
1258
|
|
@@ -1380,12 +1403,22 @@ module Writexlsx
|
|
1380
1403
|
#
|
1381
1404
|
def prepare_drawings # :nodoc:
|
1382
1405
|
chart_ref_id = 0
|
1383
|
-
image_ref_id = 0
|
1384
1406
|
drawing_id = 0
|
1385
1407
|
ref_id = 0
|
1386
1408
|
image_ids = {}
|
1387
1409
|
header_image_ids = {}
|
1388
1410
|
background_ids = {}
|
1411
|
+
|
1412
|
+
# Store the image types for any embedded images.
|
1413
|
+
@embedded_images.each do |image_data|
|
1414
|
+
store_image_types(image_data[1])
|
1415
|
+
|
1416
|
+
@has_embedded_descriptions = true if ptrue?(image_data[2])
|
1417
|
+
end
|
1418
|
+
|
1419
|
+
# The image IDs start from after the embedded images.
|
1420
|
+
image_ref_id = @embedded_images.size
|
1421
|
+
|
1389
1422
|
@worksheets.each do |sheet|
|
1390
1423
|
chart_count = sheet.charts.size
|
1391
1424
|
image_count = sheet.images.size
|
@@ -1508,173 +1541,20 @@ module Writexlsx
|
|
1508
1541
|
end
|
1509
1542
|
|
1510
1543
|
#
|
1511
|
-
#
|
1512
|
-
#
|
1513
|
-
# any duplicates.
|
1544
|
+
# Store the image types (PNG/JPEG/etc) used in the workbook to use in these
|
1545
|
+
# Content_Types file.
|
1514
1546
|
#
|
1515
|
-
def
|
1516
|
-
|
1517
|
-
|
1518
|
-
y_dpi = 96
|
1519
|
-
|
1520
|
-
# Open the image file and import the data.
|
1521
|
-
data = File.binread(filename)
|
1522
|
-
md5 = Digest::MD5.hexdigest(data)
|
1523
|
-
if data.unpack1('x A3') == 'PNG'
|
1524
|
-
# Test for PNGs.
|
1525
|
-
type, width, height, x_dpi, y_dpi = process_png(data)
|
1547
|
+
def store_image_types(type)
|
1548
|
+
case type
|
1549
|
+
when 'png'
|
1526
1550
|
@image_types[:png] = 1
|
1527
|
-
|
1528
|
-
# Test for JPEG files.
|
1529
|
-
type, width, height, x_dpi, y_dpi = process_jpg(data, filename)
|
1551
|
+
when 'jpeg'
|
1530
1552
|
@image_types[:jpeg] = 1
|
1531
|
-
|
1532
|
-
# Test for GIFs.
|
1533
|
-
type, width, height, x_dpi, y_dpi = process_gif(data, filename)
|
1553
|
+
when 'gif'
|
1534
1554
|
@image_types[:gif] = 1
|
1535
|
-
|
1536
|
-
# Test for BMPs.
|
1537
|
-
type, width, height = process_bmp(data, filename)
|
1555
|
+
when 'bmp'
|
1538
1556
|
@image_types[:bmp] = 1
|
1539
|
-
else
|
1540
|
-
# TODO. Add Image::Size to support other types.
|
1541
|
-
raise "Unsupported image format for file: #{filename}\n"
|
1542
1557
|
end
|
1543
|
-
|
1544
|
-
# Set a default dpi for images with 0 dpi.
|
1545
|
-
x_dpi = 96 if x_dpi == 0
|
1546
|
-
y_dpi = 96 if y_dpi == 0
|
1547
|
-
|
1548
|
-
[type, width, height, File.basename(filename), x_dpi, y_dpi, md5]
|
1549
|
-
end
|
1550
|
-
|
1551
|
-
#
|
1552
|
-
# Extract width and height information from a PNG file.
|
1553
|
-
#
|
1554
|
-
def process_png(data)
|
1555
|
-
type = 'png'
|
1556
|
-
width = 0
|
1557
|
-
height = 0
|
1558
|
-
x_dpi = 96
|
1559
|
-
y_dpi = 96
|
1560
|
-
|
1561
|
-
offset = 8
|
1562
|
-
data_length = data.size
|
1563
|
-
|
1564
|
-
# Search through the image data to read the height and width in th the
|
1565
|
-
# IHDR element. Also read the DPI in the pHYs element.
|
1566
|
-
while offset < data_length
|
1567
|
-
|
1568
|
-
length = data[offset + 0, 4].unpack1("N")
|
1569
|
-
png_type = data[offset + 4, 4].unpack1("A4")
|
1570
|
-
|
1571
|
-
case png_type
|
1572
|
-
when "IHDR"
|
1573
|
-
width = data[offset + 8, 4].unpack1("N")
|
1574
|
-
height = data[offset + 12, 4].unpack1("N")
|
1575
|
-
when "pHYs"
|
1576
|
-
x_ppu = data[offset + 8, 4].unpack1("N")
|
1577
|
-
y_ppu = data[offset + 12, 4].unpack1("N")
|
1578
|
-
units = data[offset + 16, 1].unpack1("C")
|
1579
|
-
|
1580
|
-
if units == 1
|
1581
|
-
x_dpi = x_ppu * 0.0254
|
1582
|
-
y_dpi = y_ppu * 0.0254
|
1583
|
-
end
|
1584
|
-
end
|
1585
|
-
|
1586
|
-
offset = offset + length + 12
|
1587
|
-
|
1588
|
-
break if png_type == "IEND"
|
1589
|
-
end
|
1590
|
-
raise "#{filename}: no size data found in png image.\n" unless height
|
1591
|
-
|
1592
|
-
[type, width, height, x_dpi, y_dpi]
|
1593
|
-
end
|
1594
|
-
|
1595
|
-
def process_jpg(data, filename)
|
1596
|
-
type = 'jpeg'
|
1597
|
-
x_dpi = 96
|
1598
|
-
y_dpi = 96
|
1599
|
-
|
1600
|
-
offset = 2
|
1601
|
-
data_length = data.bytesize
|
1602
|
-
|
1603
|
-
# Search through the image data to read the JPEG markers.
|
1604
|
-
while offset < data_length
|
1605
|
-
marker = data[offset + 0, 2].unpack1("n")
|
1606
|
-
length = data[offset + 2, 2].unpack1("n")
|
1607
|
-
|
1608
|
-
# Read the height and width in the 0xFFCn elements
|
1609
|
-
# (Except C4, C8 and CC which aren't SOF markers).
|
1610
|
-
if (marker & 0xFFF0) == 0xFFC0 &&
|
1611
|
-
marker != 0xFFC4 && marker != 0xFFCC
|
1612
|
-
height = data[offset + 5, 2].unpack1("n")
|
1613
|
-
width = data[offset + 7, 2].unpack1("n")
|
1614
|
-
end
|
1615
|
-
|
1616
|
-
# Read the DPI in the 0xFFE0 element.
|
1617
|
-
if marker == 0xFFE0
|
1618
|
-
units = data[offset + 11, 1].unpack1("C")
|
1619
|
-
x_density = data[offset + 12, 2].unpack1("n")
|
1620
|
-
y_density = data[offset + 14, 2].unpack1("n")
|
1621
|
-
|
1622
|
-
if units == 1
|
1623
|
-
x_dpi = x_density
|
1624
|
-
y_dpi = y_density
|
1625
|
-
elsif units == 2
|
1626
|
-
x_dpi = x_density * 2.54
|
1627
|
-
y_dpi = y_density * 2.54
|
1628
|
-
end
|
1629
|
-
end
|
1630
|
-
|
1631
|
-
offset += length + 2
|
1632
|
-
break if marker == 0xFFDA
|
1633
|
-
end
|
1634
|
-
|
1635
|
-
raise "#{filename}: no size data found in jpeg image.\n" unless height
|
1636
|
-
|
1637
|
-
[type, width, height, x_dpi, y_dpi]
|
1638
|
-
end
|
1639
|
-
|
1640
|
-
#
|
1641
|
-
# Extract width and height information from a GIF file.
|
1642
|
-
#
|
1643
|
-
def process_gif(data, filename)
|
1644
|
-
type = 'gif'
|
1645
|
-
x_dpi = 96
|
1646
|
-
y_dpi = 96
|
1647
|
-
|
1648
|
-
width = data[6, 2].unpack1("v")
|
1649
|
-
height = data[8, 2].unpack1("v")
|
1650
|
-
|
1651
|
-
raise "#{filename}: no size data found in gif image.\n" if height.nil?
|
1652
|
-
|
1653
|
-
[type, width, height, x_dpi, y_dpi]
|
1654
|
-
end
|
1655
|
-
|
1656
|
-
# Extract width and height information from a BMP file.
|
1657
|
-
def process_bmp(data, filename) # :nodoc:
|
1658
|
-
type = 'bmp'
|
1659
|
-
|
1660
|
-
# Check that the file is big enough to be a bitmap.
|
1661
|
-
raise "#{filename} doesn't contain enough data." if data.bytesize <= 0x36
|
1662
|
-
|
1663
|
-
# Read the bitmap width and height. Verify the sizes.
|
1664
|
-
width, height = data.unpack("x18 V2")
|
1665
|
-
raise "#{filename}: largest image width #{width} supported is 65k." if width > 0xFFFF
|
1666
|
-
raise "#{filename}: largest image height supported is 65k." if height > 0xFFFF
|
1667
|
-
|
1668
|
-
# Read the bitmap planes and bpp data. Verify them.
|
1669
|
-
planes, bitcount = data.unpack("x26 v2")
|
1670
|
-
raise "#{filename} isn't a 24bit true color bitmap." unless bitcount == 24
|
1671
|
-
raise "#{filename}: only 1 plane supported in bitmap image." unless planes == 1
|
1672
|
-
|
1673
|
-
# Read the bitmap compression. Verify compression.
|
1674
|
-
compression = data.unpack1("x30 V")
|
1675
|
-
raise "#{filename}: compression not supported in bitmap image." unless compression == 0
|
1676
|
-
|
1677
|
-
[type, width, height]
|
1678
1558
|
end
|
1679
1559
|
end
|
1680
1560
|
end
|
@@ -206,5 +206,24 @@ module Writexlsx
|
|
206
206
|
worksheet.writer.empty_tag('c', cell_attributes(worksheet, row, row_name, col))
|
207
207
|
end
|
208
208
|
end
|
209
|
+
|
210
|
+
class EmbedImageCellData < CellData # :nodoc:
|
211
|
+
def initialize(image_index, xf)
|
212
|
+
@image_index = image_index
|
213
|
+
@xf = xf
|
214
|
+
end
|
215
|
+
|
216
|
+
def write_cell(worksheet, row, row_name, col)
|
217
|
+
attributes = cell_attributes(worksheet, row, row_name, col)
|
218
|
+
|
219
|
+
# Write a error value (mainly for embedded images).
|
220
|
+
attributes << %w[t e]
|
221
|
+
attributes << ['vm', @image_index]
|
222
|
+
|
223
|
+
worksheet.writer.tag_elements('c', attributes) do
|
224
|
+
worksheet.write_cell_value('#VALUE!')
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
209
228
|
end
|
210
229
|
end
|
data/lib/write_xlsx/worksheet.rb
CHANGED
@@ -113,7 +113,8 @@ module Writexlsx
|
|
113
113
|
@drawing_rels_id = 0
|
114
114
|
@vml_drawing_rels = {}
|
115
115
|
@vml_drawing_rels_id = 0
|
116
|
-
@
|
116
|
+
@has_dynamic_functions = false
|
117
|
+
@has_embedded_images = false
|
117
118
|
|
118
119
|
@use_future_functions = false
|
119
120
|
|
@@ -160,6 +161,8 @@ module Writexlsx
|
|
160
161
|
@page_setup.margin_footer = 0.5
|
161
162
|
@page_setup.header_footer_aligns = false
|
162
163
|
end
|
164
|
+
|
165
|
+
@embedded_image_indexes = @workbook.embedded_image_indexes
|
163
166
|
end
|
164
167
|
|
165
168
|
def set_xml_writer(filename) # :nodoc:
|
@@ -1446,6 +1449,7 @@ module Writexlsx
|
|
1446
1449
|
formula = expand_formula(formula, 'HYPGEOM.DIST\(')
|
1447
1450
|
formula = expand_formula(formula, 'IFNA\(')
|
1448
1451
|
formula = expand_formula(formula, 'IFS\(')
|
1452
|
+
formula = expand_formula(formula, 'IMAGE\(')
|
1449
1453
|
formula = expand_formula(formula, 'IMCOSH\(')
|
1450
1454
|
formula = expand_formula(formula, 'IMCOT\(')
|
1451
1455
|
formula = expand_formula(formula, 'IMCSCH\(')
|
@@ -1536,7 +1540,7 @@ module Writexlsx
|
|
1536
1540
|
raise WriteXLSXInsufficientArgumentError if [_row, _col, _formula].include?(nil)
|
1537
1541
|
|
1538
1542
|
# Check for dynamic array functions.
|
1539
|
-
regex = /\
|
1543
|
+
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\(/
|
1540
1544
|
if _formula =~ regex
|
1541
1545
|
return write_dynamic_array_formula(
|
1542
1546
|
_row, _col, _row, _col, _formula, _format, _value
|
@@ -1549,7 +1553,7 @@ module Writexlsx
|
|
1549
1553
|
else
|
1550
1554
|
check_dimensions(_row, _col)
|
1551
1555
|
store_row_col_max_min_values(_row, _col)
|
1552
|
-
_formula = _formula
|
1556
|
+
_formula = prepare_formula(_formula)
|
1553
1557
|
|
1554
1558
|
store_data_to_table(FormulaCellData.new(_formula, _format, _value), _row, _col)
|
1555
1559
|
end
|
@@ -1634,7 +1638,7 @@ module Writexlsx
|
|
1634
1638
|
#
|
1635
1639
|
def write_dynamic_array_formula(row1, col1, row2 = nil, col2 = nil, formula = nil, format = nil, value = nil)
|
1636
1640
|
write_array_formula_base('d', row1, col1, row2, col2, formula, format, value)
|
1637
|
-
@
|
1641
|
+
@has_dynamic_functions = true
|
1638
1642
|
end
|
1639
1643
|
|
1640
1644
|
#
|
@@ -1782,21 +1786,23 @@ module Writexlsx
|
|
1782
1786
|
# The label is written using the {#write()}[#method-i-write] method. Therefore it is
|
1783
1787
|
# possible to write strings, numbers or formulas as labels.
|
1784
1788
|
#
|
1785
|
-
def write_url(row, col, url = nil, format = nil, str = nil, tip = nil)
|
1789
|
+
def write_url(row, col, url = nil, format = nil, str = nil, tip = nil, ignore_write_string = false)
|
1786
1790
|
# Check for a cell reference in A1 notation and substitute row and column
|
1787
1791
|
if (row_col_array = row_col_notation(row))
|
1788
|
-
_row, _col
|
1789
|
-
_url
|
1790
|
-
_format
|
1791
|
-
_str
|
1792
|
-
_tip
|
1792
|
+
_row, _col = row_col_array
|
1793
|
+
_url = col
|
1794
|
+
_format = url
|
1795
|
+
_str = format
|
1796
|
+
_tip = str
|
1797
|
+
_ignore_write_string = tip
|
1793
1798
|
else
|
1794
|
-
_row
|
1795
|
-
_col
|
1796
|
-
_url
|
1797
|
-
_format
|
1798
|
-
_str
|
1799
|
-
_tip
|
1799
|
+
_row = row
|
1800
|
+
_col = col
|
1801
|
+
_url = url
|
1802
|
+
_format = format
|
1803
|
+
_str = str
|
1804
|
+
_tip = tip
|
1805
|
+
_ignore_write_string = ignore_write_string
|
1800
1806
|
end
|
1801
1807
|
_format, _str = _str, _format if _str.respond_to?(:xf_index) || !_format.respond_to?(:xf_index)
|
1802
1808
|
raise WriteXLSXInsufficientArgumentError if [_row, _col, _url].include?(nil)
|
@@ -1814,7 +1820,7 @@ module Writexlsx
|
|
1814
1820
|
_format ||= @default_url_format
|
1815
1821
|
|
1816
1822
|
# Write the hyperlink string.
|
1817
|
-
write_string(_row, _col, hyperlink.str, _format)
|
1823
|
+
write_string(_row, _col, hyperlink.str, _format) unless _ignore_write_string
|
1818
1824
|
end
|
1819
1825
|
|
1820
1826
|
#
|
@@ -1959,6 +1965,65 @@ module Writexlsx
|
|
1959
1965
|
]
|
1960
1966
|
end
|
1961
1967
|
|
1968
|
+
#
|
1969
|
+
# Embed an image into the worksheet.
|
1970
|
+
#
|
1971
|
+
def embed_image(row, col, filename, options = nil)
|
1972
|
+
# Check for a cell reference in A1 notation and substitute row and column.
|
1973
|
+
if (row_col_array = row_col_notation(row))
|
1974
|
+
_row, _col = row_col_array
|
1975
|
+
image = col
|
1976
|
+
_options = filename
|
1977
|
+
else
|
1978
|
+
_row = row
|
1979
|
+
_col = col
|
1980
|
+
image = filename
|
1981
|
+
_options = options
|
1982
|
+
end
|
1983
|
+
xf, url, tip, description, decorative = []
|
1984
|
+
|
1985
|
+
raise WriteXLSXInsufficientArgumentError if [_row, _col, image].include?(nil)
|
1986
|
+
raise "Couldn't locate #{image}" unless File.exist?(image)
|
1987
|
+
|
1988
|
+
# Check that row and col are valid and store max and min values
|
1989
|
+
check_dimensions(_row, _col)
|
1990
|
+
store_row_col_max_min_values(_row, _col)
|
1991
|
+
|
1992
|
+
if options
|
1993
|
+
xf = options[:cell_format]
|
1994
|
+
url = options[:url]
|
1995
|
+
tip = options[:tip]
|
1996
|
+
description = options[:description]
|
1997
|
+
decorative = options[:decorative]
|
1998
|
+
end
|
1999
|
+
|
2000
|
+
# Write the url without writing a string.
|
2001
|
+
if url
|
2002
|
+
xf ||= @default_url_format
|
2003
|
+
|
2004
|
+
write_url(row, col, url, xf, nil, tip, true)
|
2005
|
+
end
|
2006
|
+
|
2007
|
+
# Get the image properties, mainly for the type and checksum.
|
2008
|
+
image_properties = get_image_properties(image)
|
2009
|
+
type = image_properties[0]
|
2010
|
+
md5 = image_properties[6]
|
2011
|
+
|
2012
|
+
# Check for duplicate images.
|
2013
|
+
image_index = @embedded_image_indexes[md5]
|
2014
|
+
|
2015
|
+
unless ptrue?(image_index)
|
2016
|
+
@workbook.embedded_images << [image, type, description, decorative]
|
2017
|
+
|
2018
|
+
image_index = @workbook.embedded_images.size
|
2019
|
+
@embedded_image_indexes[md5] = image_index
|
2020
|
+
end
|
2021
|
+
|
2022
|
+
# Write the cell placeholder.
|
2023
|
+
store_data_to_table(EmbedImageCellData.new(image_index, xf), _row, _col)
|
2024
|
+
@has_embedded_images = true
|
2025
|
+
end
|
2026
|
+
|
1962
2027
|
#
|
1963
2028
|
# :call-seq:
|
1964
2029
|
# repeat_formula(row, column, formula [ , format ])
|
@@ -2799,8 +2864,12 @@ module Writexlsx
|
|
2799
2864
|
end
|
2800
2865
|
end
|
2801
2866
|
|
2802
|
-
def
|
2803
|
-
@
|
2867
|
+
def has_dynamic_functions?
|
2868
|
+
@has_dynamic_functions
|
2869
|
+
end
|
2870
|
+
|
2871
|
+
def has_embedded_images?
|
2872
|
+
@has_embedded_images
|
2804
2873
|
end
|
2805
2874
|
|
2806
2875
|
private
|
@@ -3278,6 +3347,7 @@ EOS
|
|
3278
3347
|
end
|
3279
3348
|
|
3280
3349
|
@drawing_links << ['/image', "../media/image#{image_id}.#{image_type}"] unless @drawing_rels[md5]
|
3350
|
+
|
3281
3351
|
drawing.rel_index = drawing_rel_index(md5)
|
3282
3352
|
end
|
3283
3353
|
public :prepare_image
|
@@ -4256,9 +4326,10 @@ EOS
|
|
4256
4326
|
|
4257
4327
|
# If the cell isn't a string then we have to add the url as
|
4258
4328
|
# the string to display
|
4259
|
-
if ptrue?(@cell_data_table)
|
4260
|
-
ptrue?(@cell_data_table[row_num])
|
4261
|
-
ptrue?(@cell_data_table[row_num][col_num]) &&
|
4329
|
+
if ptrue?(@cell_data_table) &&
|
4330
|
+
ptrue?(@cell_data_table[row_num]) &&
|
4331
|
+
ptrue?(@cell_data_table[row_num][col_num]) &&
|
4332
|
+
@cell_data_table[row_num][col_num].display_url_string?
|
4262
4333
|
link.display_on
|
4263
4334
|
end
|
4264
4335
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: write_xlsx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.12.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hideo NAKAMURA
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nkf
|
@@ -266,6 +266,10 @@ files:
|
|
266
266
|
- lib/write_xlsx/package/metadata.rb
|
267
267
|
- lib/write_xlsx/package/packager.rb
|
268
268
|
- lib/write_xlsx/package/relationships.rb
|
269
|
+
- lib/write_xlsx/package/rich_value.rb
|
270
|
+
- lib/write_xlsx/package/rich_value_rel.rb
|
271
|
+
- lib/write_xlsx/package/rich_value_structure.rb
|
272
|
+
- lib/write_xlsx/package/rich_value_types.rb
|
269
273
|
- lib/write_xlsx/package/shared_strings.rb
|
270
274
|
- lib/write_xlsx/package/styles.rb
|
271
275
|
- lib/write_xlsx/package/table.rb
|
@@ -304,7 +308,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
304
308
|
- !ruby/object:Gem::Version
|
305
309
|
version: '0'
|
306
310
|
requirements: []
|
307
|
-
rubygems_version: 3.
|
311
|
+
rubygems_version: 3.4.19
|
308
312
|
signing_key:
|
309
313
|
specification_version: 4
|
310
314
|
summary: write_xlsx is a gem to create a new file in the Excel 2007+ XLSX format.
|