write_xlsx 1.02.0 → 1.08.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/Changes +72 -0
- data/README.md +1 -1
- data/examples/chart_data_labels.rb +320 -0
- data/examples/chart_line.rb +85 -10
- data/examples/tables.rb +77 -42
- data/lib/write_xlsx/chart/line.rb +15 -1
- data/lib/write_xlsx/chart/series.rb +100 -0
- data/lib/write_xlsx/chart.rb +155 -33
- data/lib/write_xlsx/drawing.rb +80 -17
- data/lib/write_xlsx/format.rb +5 -5
- data/lib/write_xlsx/package/app.rb +3 -3
- data/lib/write_xlsx/package/comments.rb +4 -4
- data/lib/write_xlsx/package/conditional_format.rb +2 -8
- data/lib/write_xlsx/package/packager.rb +1 -0
- data/lib/write_xlsx/package/relationships.rb +2 -2
- data/lib/write_xlsx/package/styles.rb +42 -11
- data/lib/write_xlsx/package/table.rb +16 -7
- data/lib/write_xlsx/package/vml.rb +20 -19
- data/lib/write_xlsx/sheets.rb +12 -20
- data/lib/write_xlsx/utility.rb +9 -3
- data/lib/write_xlsx/version.rb +1 -1
- data/lib/write_xlsx/workbook.rb +76 -35
- data/lib/write_xlsx/worksheet/data_validation.rb +1 -6
- data/lib/write_xlsx/worksheet.rb +197 -57
- data/test/drawing/{test_write_ext.rb → test_write_xdr_ext.rb} +2 -2
- data/test/perl_output/chart_data_labels.xlsx +0 -0
- data/test/perl_output/chart_line.xlsx +0 -0
- data/test/perl_output/comments2.xlsx +0 -0
- data/test/perl_output/tables.xlsx +0 -0
- data/test/regression/images/red2.png +0 -0
- data/test/regression/test_array_formula04.rb +31 -0
- data/test/regression/test_chart_crossing01.rb +1 -1
- data/test/regression/test_chart_crossing05.rb +46 -0
- data/test/regression/test_chart_crossing06.rb +46 -0
- data/test/regression/test_chart_data_labels26.rb +44 -0
- data/test/regression/test_chart_data_labels27.rb +44 -0
- data/test/regression/test_chart_data_labels28.rb +52 -0
- data/test/regression/test_chart_data_labels29.rb +43 -0
- data/test/regression/test_chart_data_labels30.rb +46 -0
- data/test/regression/test_chart_data_labels31.rb +49 -0
- data/test/regression/test_chart_data_labels32.rb +54 -0
- data/test/regression/test_chart_data_labels33.rb +52 -0
- data/test/regression/test_chart_data_labels34.rb +54 -0
- data/test/regression/test_chart_data_labels35.rb +46 -0
- data/test/regression/test_chart_data_labels36.rb +54 -0
- data/test/regression/test_chart_data_labels37.rb +51 -0
- data/test/regression/test_chart_data_labels38.rb +54 -0
- data/test/regression/test_chart_data_labels39.rb +53 -0
- data/test/regression/test_chart_data_labels40.rb +53 -0
- data/test/regression/test_chart_data_labels41.rb +54 -0
- data/test/regression/test_chart_data_labels42.rb +58 -0
- data/test/regression/test_chart_data_labels43.rb +58 -0
- data/test/regression/test_chart_data_labels44.rb +56 -0
- data/test/regression/test_chart_data_labels45.rb +57 -0
- data/test/regression/test_chart_data_labels46.rb +61 -0
- data/test/regression/test_chart_data_labels47.rb +61 -0
- data/test/regression/test_chart_data_labels48.rb +55 -0
- data/test/regression/test_chart_data_labels49.rb +55 -0
- data/test/regression/test_chart_data_labels50.rb +57 -0
- data/test/regression/test_chart_line05.rb +43 -0
- data/test/regression/test_chart_line06.rb +43 -0
- data/test/regression/test_comment15.rb +28 -0
- data/test/regression/test_comment16.rb +34 -0
- data/test/regression/test_format16.rb +24 -0
- data/test/regression/test_format17.rb +24 -0
- data/test/regression/test_header04.rb +30 -0
- data/test/regression/test_header_image15.rb +36 -0
- data/test/regression/test_header_image16.rb +42 -0
- data/test/regression/test_header_image17.rb +46 -0
- data/test/regression/test_header_image18.rb +48 -0
- data/test/regression/test_header_image19.rb +36 -0
- data/test/regression/test_hyperlink48.rb +31 -0
- data/test/regression/test_hyperlink49.rb +29 -0
- data/test/regression/test_hyperlink50.rb +27 -0
- data/test/regression/test_hyperlink51.rb +27 -0
- data/test/regression/test_ignore_error01.rb +23 -0
- data/test/regression/test_ignore_error02.rb +24 -0
- data/test/regression/test_ignore_error03.rb +26 -0
- data/test/regression/test_ignore_error04.rb +26 -0
- data/test/regression/test_ignore_error05.rb +32 -0
- data/test/regression/test_ignore_error06.rb +32 -0
- data/test/regression/test_image45.rb +2 -1
- data/test/regression/test_image46.rb +1 -1
- data/test/regression/test_image48.rb +32 -0
- data/test/regression/test_image49.rb +38 -0
- data/test/regression/test_image50.rb +24 -0
- data/test/regression/test_image51.rb +30 -0
- data/test/regression/test_image52.rb +26 -0
- data/test/regression/test_image53.rb +26 -0
- data/test/regression/test_image54.rb +26 -0
- data/test/regression/test_image55.rb +27 -0
- data/test/regression/test_object_position12.rb +25 -0
- data/test/regression/test_object_position13.rb +25 -0
- data/test/regression/test_object_position14.rb +25 -0
- data/test/regression/test_object_position15.rb +29 -0
- data/test/regression/test_object_position16.rb +29 -0
- data/test/regression/test_object_position17.rb +29 -0
- data/test/regression/test_object_position18.rb +29 -0
- data/test/regression/test_object_position19.rb +29 -0
- data/test/regression/test_object_position20.rb +29 -0
- data/test/regression/test_protect04.rb +32 -0
- data/test/regression/test_protect05.rb +35 -0
- data/test/regression/test_protect06.rb +35 -0
- data/test/regression/test_protect07.rb +23 -0
- data/test/regression/test_table24.rb +27 -0
- data/test/regression/test_table25.rb +27 -0
- data/test/regression/test_table26.rb +38 -0
- data/test/regression/xlsx_files/array_formula04.xlsx +0 -0
- data/test/regression/xlsx_files/chart_crossing05.xlsx +0 -0
- data/test/regression/xlsx_files/chart_crossing06.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels26.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels27.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels28.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels29.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels30.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels31.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels32.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels33.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels34.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels35.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels36.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels37.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels38.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels39.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels40.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels41.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels42.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels43.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels44.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels45.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels46.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels47.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels48.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels49.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels50.xlsx +0 -0
- data/test/regression/xlsx_files/chart_line05.xlsx +0 -0
- data/test/regression/xlsx_files/chart_line06.xlsx +0 -0
- data/test/regression/xlsx_files/comment15.xlsx +0 -0
- data/test/regression/xlsx_files/comment16.xlsx +0 -0
- data/test/regression/xlsx_files/format16.xlsx +0 -0
- data/test/regression/xlsx_files/format17.xlsx +0 -0
- data/test/regression/xlsx_files/header04.xlsx +0 -0
- data/test/regression/xlsx_files/header_image15.xlsx +0 -0
- data/test/regression/xlsx_files/header_image16.xlsx +0 -0
- data/test/regression/xlsx_files/header_image17.xlsx +0 -0
- data/test/regression/xlsx_files/header_image18.xlsx +0 -0
- data/test/regression/xlsx_files/header_image19.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink46.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink50.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink51.xlsx +0 -0
- data/test/regression/xlsx_files/ignore_error01.xlsx +0 -0
- data/test/regression/xlsx_files/ignore_error02.xlsx +0 -0
- data/test/regression/xlsx_files/ignore_error03.xlsx +0 -0
- data/test/regression/xlsx_files/ignore_error04.xlsx +0 -0
- data/test/regression/xlsx_files/ignore_error05.xlsx +0 -0
- data/test/regression/xlsx_files/ignore_error06.xlsx +0 -0
- data/test/regression/xlsx_files/image45.xlsx +0 -0
- data/test/regression/xlsx_files/image46.xlsx +0 -0
- data/test/regression/xlsx_files/image48.xlsx +0 -0
- data/test/regression/xlsx_files/image49.xlsx +0 -0
- data/test/regression/xlsx_files/image50.xlsx +0 -0
- data/test/regression/xlsx_files/image51.xlsx +0 -0
- data/test/regression/xlsx_files/image52.xlsx +0 -0
- data/test/regression/xlsx_files/image53.xlsx +0 -0
- data/test/regression/xlsx_files/image54.xlsx +0 -0
- data/test/regression/xlsx_files/image55.xlsx +0 -0
- data/test/regression/xlsx_files/object_position12.xlsx +0 -0
- data/test/regression/xlsx_files/object_position13.xlsx +0 -0
- data/test/regression/xlsx_files/object_position14.xlsx +0 -0
- data/test/regression/xlsx_files/object_position15.xlsx +0 -0
- data/test/regression/xlsx_files/object_position16.xlsx +0 -0
- data/test/regression/xlsx_files/object_position17.xlsx +0 -0
- data/test/regression/xlsx_files/object_position18.xlsx +0 -0
- data/test/regression/xlsx_files/object_position19.xlsx +0 -0
- data/test/regression/xlsx_files/object_position20.xlsx +0 -0
- data/test/regression/xlsx_files/protect04.xlsx +0 -0
- data/test/regression/xlsx_files/protect05.xlsx +0 -0
- data/test/regression/xlsx_files/protect06.xlsx +0 -0
- data/test/regression/xlsx_files/protect07.xlsx +0 -0
- data/test/regression/xlsx_files/table24.xlsx +0 -0
- data/test/regression/xlsx_files/table25.xlsx +0 -0
- data/test/regression/xlsx_files/table26.xlsx +0 -0
- data/test/test_example_match.rb +433 -10
- data/test/utility/test_range.rb +20 -0
- data/test/workbook/test_check_sheetname.rb +0 -10
- data/write_xlsx.gemspec +1 -0
- metadata +323 -8
data/lib/write_xlsx/workbook.rb
CHANGED
@@ -52,6 +52,7 @@ module Writexlsx
|
|
52
52
|
attr_reader :max_url_length # :nodoc:
|
53
53
|
attr_reader :strings_to_urls # :nodoc:
|
54
54
|
attr_reader :default_url_format # :nodoc:
|
55
|
+
attr_reader :read_only # :nodoc:
|
55
56
|
|
56
57
|
#
|
57
58
|
# A new Excel workbook is created using the +new+ constructor
|
@@ -132,6 +133,8 @@ module Writexlsx
|
|
132
133
|
@strings_to_urls = (options[:strings_to_urls].nil? || options[:strings_to_urls]) ? true : false
|
133
134
|
|
134
135
|
@max_url_length = 2079
|
136
|
+
@has_comments = false
|
137
|
+
@read_only = 0
|
135
138
|
if options[:max_url_length]
|
136
139
|
@max_url_length = options[:max_url_length]
|
137
140
|
|
@@ -291,6 +294,9 @@ module Writexlsx
|
|
291
294
|
# Write the XLSX file version.
|
292
295
|
write_file_version
|
293
296
|
|
297
|
+
# Write the fileSharing element.
|
298
|
+
write_file_sharing
|
299
|
+
|
294
300
|
# Write the workbook properties.
|
295
301
|
write_workbook_pr
|
296
302
|
|
@@ -953,6 +959,13 @@ module Writexlsx
|
|
953
959
|
end
|
954
960
|
end
|
955
961
|
|
962
|
+
#
|
963
|
+
# Set the Excel "Read-only recommended" save option.
|
964
|
+
#
|
965
|
+
def read_only_recommended
|
966
|
+
@read_only = 2
|
967
|
+
end
|
968
|
+
|
956
969
|
#
|
957
970
|
# set_calc_mode()
|
958
971
|
#
|
@@ -1115,7 +1128,8 @@ module Writexlsx
|
|
1115
1128
|
@border_count,
|
1116
1129
|
@fill_count,
|
1117
1130
|
@custom_colors,
|
1118
|
-
@dxf_formats
|
1131
|
+
@dxf_formats,
|
1132
|
+
@has_comments
|
1119
1133
|
]
|
1120
1134
|
end
|
1121
1135
|
|
@@ -1309,6 +1323,17 @@ module Writexlsx
|
|
1309
1323
|
@writer.empty_tag('fileVersion', attributes)
|
1310
1324
|
end
|
1311
1325
|
|
1326
|
+
#
|
1327
|
+
# Write the <fileSharing> element.
|
1328
|
+
#
|
1329
|
+
def write_file_sharing
|
1330
|
+
return if !ptrue?(@read_only)
|
1331
|
+
|
1332
|
+
attributes = []
|
1333
|
+
attributes << ['readOnlyRecommended', 1]
|
1334
|
+
@writer.empty_tag('fileSharing', attributes)
|
1335
|
+
end
|
1336
|
+
|
1312
1337
|
def write_workbook_pr #:nodoc:
|
1313
1338
|
attributes = []
|
1314
1339
|
attributes << ['codeName', @vba_codename] if ptrue?(@vba_codename)
|
@@ -1711,11 +1736,14 @@ module Writexlsx
|
|
1711
1736
|
if sheet.has_comments?
|
1712
1737
|
comment_files += 1
|
1713
1738
|
comment_id += 1
|
1739
|
+
@has_comments = true
|
1714
1740
|
end
|
1715
1741
|
vml_drawing_id += 1
|
1716
1742
|
|
1717
|
-
sheet.prepare_vml_objects(
|
1718
|
-
|
1743
|
+
sheet.prepare_vml_objects(
|
1744
|
+
vml_data_id, vml_shape_id,
|
1745
|
+
vml_drawing_id, comment_id
|
1746
|
+
)
|
1719
1747
|
|
1720
1748
|
# Each VML file should start with a shape id incremented by 1024.
|
1721
1749
|
vml_data_id += 1 * ( 1 + sheet.num_comments_block )
|
@@ -1738,8 +1766,6 @@ module Writexlsx
|
|
1738
1766
|
end
|
1739
1767
|
end
|
1740
1768
|
|
1741
|
-
add_font_format_for_cell_comments if num_comment_files > 0
|
1742
|
-
|
1743
1769
|
# Set the workbook vba_codename if one of the sheets has a button and
|
1744
1770
|
# the workbook has a vbaProject binary.
|
1745
1771
|
if has_button && @vba_project && !@vba_codename
|
@@ -1759,19 +1785,6 @@ module Writexlsx
|
|
1759
1785
|
end
|
1760
1786
|
end
|
1761
1787
|
|
1762
|
-
def add_font_format_for_cell_comments
|
1763
|
-
format = Format.new(
|
1764
|
-
@formats,
|
1765
|
-
:font => 'Tahoma',
|
1766
|
-
:size => 8,
|
1767
|
-
:color_indexed => 81,
|
1768
|
-
:font_only => 1
|
1769
|
-
)
|
1770
|
-
|
1771
|
-
format.get_xf_index
|
1772
|
-
@formats.formats << format
|
1773
|
-
end
|
1774
|
-
|
1775
1788
|
#
|
1776
1789
|
# Add "cached" data to charts to provide the numCache and strCache data for
|
1777
1790
|
# series and title/axis ranges.
|
@@ -1922,9 +1935,12 @@ module Writexlsx
|
|
1922
1935
|
# Iterate through the worksheets and set up any chart or image drawings.
|
1923
1936
|
#
|
1924
1937
|
def prepare_drawings #:nodoc:
|
1925
|
-
chart_ref_id
|
1926
|
-
image_ref_id
|
1927
|
-
drawing_id
|
1938
|
+
chart_ref_id = 0
|
1939
|
+
image_ref_id = 0
|
1940
|
+
drawing_id = 0
|
1941
|
+
ref_id = 0
|
1942
|
+
image_ids = {}
|
1943
|
+
header_image_ids = {}
|
1928
1944
|
@worksheets.each do |sheet|
|
1929
1945
|
chart_count = sheet.charts.size
|
1930
1946
|
image_count = sheet.images.size
|
@@ -1944,9 +1960,19 @@ module Writexlsx
|
|
1944
1960
|
|
1945
1961
|
# Prepare the worksheet images.
|
1946
1962
|
sheet.images.each_with_index do |image, index|
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1963
|
+
filename = image[2]
|
1964
|
+
type, width, height, name, x_dpi, y_dpi, md5 = get_image_properties(image[2])
|
1965
|
+
if image_ids[md5]
|
1966
|
+
ref_id = image_ids[md5]
|
1967
|
+
else
|
1968
|
+
image_ref_id += 1
|
1969
|
+
image_ids[md5] = ref_id = image_ref_id
|
1970
|
+
@images << [filename, type]
|
1971
|
+
end
|
1972
|
+
sheet.prepare_image(
|
1973
|
+
index, ref_id, drawing_id, width, height,
|
1974
|
+
name, type, x_dpi, y_dpi, md5
|
1975
|
+
)
|
1950
1976
|
end
|
1951
1977
|
|
1952
1978
|
# Prepare the worksheet charts.
|
@@ -1965,13 +1991,21 @@ module Writexlsx
|
|
1965
1991
|
filename = sheet.header_images[index][0]
|
1966
1992
|
position = sheet.header_images[index][1]
|
1967
1993
|
|
1968
|
-
type, width, height, name, x_dpi, y_dpi =
|
1994
|
+
type, width, height, name, x_dpi, y_dpi, md5 =
|
1969
1995
|
get_image_properties(filename)
|
1970
1996
|
|
1971
|
-
|
1997
|
+
if header_image_ids[md5]
|
1998
|
+
ref_id = header_image_ids[md5]
|
1999
|
+
else
|
2000
|
+
image_ref_id += 1
|
2001
|
+
header_image_ids[md5] = ref_id = image_ref_id
|
2002
|
+
@images << [filename, type]
|
2003
|
+
end
|
1972
2004
|
|
1973
|
-
sheet.prepare_header_image(
|
1974
|
-
|
2005
|
+
sheet.prepare_header_image(
|
2006
|
+
ref_id, width, height, name, type,
|
2007
|
+
position, x_dpi, y_dpi, md5
|
2008
|
+
)
|
1975
2009
|
end
|
1976
2010
|
|
1977
2011
|
# Prepare the footer images.
|
@@ -1979,13 +2013,21 @@ module Writexlsx
|
|
1979
2013
|
filename = sheet.footer_images[index][0]
|
1980
2014
|
position = sheet.footer_images[index][1]
|
1981
2015
|
|
1982
|
-
type, width, height, name, x_dpi, y_dpi =
|
2016
|
+
type, width, height, name, x_dpi, y_dpi, md5 =
|
1983
2017
|
get_image_properties(filename)
|
1984
2018
|
|
1985
|
-
|
2019
|
+
if header_image_ids[md5]
|
2020
|
+
ref_id = header_image_ids[md5]
|
2021
|
+
else
|
2022
|
+
image_ref_id += 1
|
2023
|
+
header_image_ids[md5] = ref_id = image_ref_id
|
2024
|
+
@images << [filename, type]
|
2025
|
+
end
|
1986
2026
|
|
1987
|
-
sheet.prepare_header_image(
|
1988
|
-
|
2027
|
+
sheet.prepare_header_image(
|
2028
|
+
ref_id, width, height, name, type,
|
2029
|
+
position, x_dpi, y_dpi, md5
|
2030
|
+
)
|
1989
2031
|
end
|
1990
2032
|
|
1991
2033
|
if has_drawings
|
@@ -2014,6 +2056,7 @@ module Writexlsx
|
|
2014
2056
|
|
2015
2057
|
# Open the image file and import the data.
|
2016
2058
|
data = File.binread(filename)
|
2059
|
+
md5 = Digest::MD5.hexdigest(data)
|
2017
2060
|
if data.unpack('x A3')[0] == 'PNG'
|
2018
2061
|
# Test for PNGs.
|
2019
2062
|
type, width, height, x_dpi, y_dpi = process_png(data)
|
@@ -2031,13 +2074,11 @@ module Writexlsx
|
|
2031
2074
|
raise "Unsupported image format for file: #{filename}\n"
|
2032
2075
|
end
|
2033
2076
|
|
2034
|
-
@images << [filename, type]
|
2035
|
-
|
2036
2077
|
# Set a default dpi for images with 0 dpi.
|
2037
2078
|
x_dpi = 96 if x_dpi == 0
|
2038
2079
|
y_dpi = 96 if y_dpi == 0
|
2039
2080
|
|
2040
|
-
[type, width, height, File.basename(filename), x_dpi, y_dpi]
|
2081
|
+
[type, width, height, File.basename(filename), x_dpi, y_dpi, md5]
|
2041
2082
|
end
|
2042
2083
|
|
2043
2084
|
#
|
@@ -138,12 +138,7 @@ module Writexlsx
|
|
138
138
|
row_first, row_last = row_last, row_first if row_first > row_last
|
139
139
|
col_first, col_last = col_last, col_first if col_first > col_last
|
140
140
|
|
141
|
-
|
142
|
-
if row_first == row_last && col_first == col_last
|
143
|
-
sqref += xl_rowcol_to_cell(row_first, col_first)
|
144
|
-
else
|
145
|
-
sqref += xl_range(row_first, row_last, col_first, col_last)
|
146
|
-
end
|
141
|
+
sqref += xl_range(row_first, row_last, col_first, col_last)
|
147
142
|
end
|
148
143
|
|
149
144
|
if @validate != 'none'
|