write_xlsx 1.09.5 → 1.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/Changes +5 -0
- data/LICENSE.txt +1 -1
- data/examples/autofilter.rb +38 -9
- data/examples/dynamic_arrays.rb +247 -0
- data/examples/lambda.rb +43 -0
- data/examples/watermark.png +0 -0
- data/examples/watermark.rb +26 -0
- data/lib/write_xlsx/chart.rb +1 -0
- data/lib/write_xlsx/chartsheet.rb +1 -0
- data/lib/write_xlsx/col_name.rb +1 -0
- data/lib/write_xlsx/colors.rb +1 -0
- data/lib/write_xlsx/compatibility.rb +1 -0
- data/lib/write_xlsx/drawing.rb +20 -10
- data/lib/write_xlsx/format.rb +5 -0
- data/lib/write_xlsx/formats.rb +1 -0
- data/lib/write_xlsx/gradient.rb +2 -0
- data/lib/write_xlsx/package/app.rb +1 -0
- data/lib/write_xlsx/package/button.rb +6 -2
- data/lib/write_xlsx/package/comments.rb +3 -1
- data/lib/write_xlsx/package/conditional_format.rb +1 -0
- data/lib/write_xlsx/package/content_types.rb +1 -0
- data/lib/write_xlsx/package/core.rb +1 -0
- data/lib/write_xlsx/package/custom.rb +1 -0
- data/lib/write_xlsx/package/metadata.rb +1 -0
- data/lib/write_xlsx/package/packager.rb +1 -0
- data/lib/write_xlsx/package/relationships.rb +1 -0
- data/lib/write_xlsx/package/shared_strings.rb +1 -1
- data/lib/write_xlsx/package/styles.rb +1 -0
- data/lib/write_xlsx/package/table.rb +1 -0
- data/lib/write_xlsx/package/theme.rb +1 -0
- data/lib/write_xlsx/package/vml.rb +1 -0
- data/lib/write_xlsx/package/xml_writer_simple.rb +21 -2
- data/lib/write_xlsx/shape.rb +1 -0
- data/lib/write_xlsx/sheets.rb +1 -0
- data/lib/write_xlsx/sparkline.rb +1 -0
- data/lib/write_xlsx/utility.rb +2 -3
- data/lib/write_xlsx/version.rb +3 -1
- data/lib/write_xlsx/worksheet/cell_data.rb +52 -62
- data/lib/write_xlsx/worksheet/data_validation.rb +1 -0
- data/lib/write_xlsx/worksheet/hyperlink.rb +3 -2
- data/lib/write_xlsx/worksheet/page_setup.rb +1 -0
- data/lib/write_xlsx/worksheet.rb +260 -47
- data/lib/write_xlsx/zip_file_utils.rb +1 -0
- data/lib/write_xlsx.rb +1 -0
- data/write_xlsx.gemspec +1 -0
- metadata +8 -4
data/lib/write_xlsx/worksheet.rb
CHANGED
@@ -44,7 +44,7 @@ module Writexlsx
|
|
44
44
|
@index = index
|
45
45
|
@name = name
|
46
46
|
@colinfo = {}
|
47
|
-
@cell_data_table =
|
47
|
+
@cell_data_table = []
|
48
48
|
@excel_version = 2007
|
49
49
|
@palette = workbook.palette
|
50
50
|
@default_url_format = workbook.default_url_format
|
@@ -61,6 +61,7 @@ module Writexlsx
|
|
61
61
|
@selections = []
|
62
62
|
@panes = []
|
63
63
|
@hide_row_col_headers = 0
|
64
|
+
@top_left_cell = ''
|
64
65
|
|
65
66
|
@tab_color = 0
|
66
67
|
|
@@ -103,6 +104,9 @@ module Writexlsx
|
|
103
104
|
@vml_drawing_rels = {}
|
104
105
|
@vml_drawing_rels_id = 0
|
105
106
|
@has_dynamic_arrays = false
|
107
|
+
|
108
|
+
@use_future_functions = false
|
109
|
+
|
106
110
|
@header_images = []
|
107
111
|
@footer_images = []
|
108
112
|
@background_image = ''
|
@@ -256,8 +260,8 @@ module Writexlsx
|
|
256
260
|
if range.nil?
|
257
261
|
raise "The range must be defined in unprotect_range())\n"
|
258
262
|
else
|
259
|
-
range.gsub
|
260
|
-
range.sub
|
263
|
+
range = range.gsub(/\$/, "")
|
264
|
+
range = range.sub(/^=/, "")
|
261
265
|
@num_protected_ranges += 1
|
262
266
|
end
|
263
267
|
|
@@ -410,6 +414,18 @@ module Writexlsx
|
|
410
414
|
@selections = [[nil, active_cell, sqref]]
|
411
415
|
end
|
412
416
|
|
417
|
+
###############################################################################
|
418
|
+
#
|
419
|
+
# set_top_left_cell()
|
420
|
+
#
|
421
|
+
# Set the first visible cell at the top left of the worksheet.
|
422
|
+
#
|
423
|
+
def set_top_left_cell(*args)
|
424
|
+
row, col = row_col_notation(args)
|
425
|
+
|
426
|
+
@top_left_cell = xl_rowcol_to_cell(row, col)
|
427
|
+
end
|
428
|
+
|
413
429
|
#
|
414
430
|
# :call-seq:
|
415
431
|
# freeze_panes(row, col [ , top_row, left_col ] )
|
@@ -813,7 +829,8 @@ module Writexlsx
|
|
813
829
|
# Set the option to print the worksheet in black and white.
|
814
830
|
#
|
815
831
|
def print_black_and_white
|
816
|
-
@page_setup.black_white
|
832
|
+
@page_setup.black_white = true
|
833
|
+
@page_setup.page_setup_changed = true
|
817
834
|
end
|
818
835
|
|
819
836
|
#
|
@@ -878,8 +895,11 @@ module Writexlsx
|
|
878
895
|
token = row_col_args[2] || ''
|
879
896
|
token = token.to_s if token.instance_of?(Time)
|
880
897
|
|
898
|
+
fmt = row_col_args[3]
|
899
|
+
if fmt.respond_to?(:force_text_format?) && fmt.force_text_format?
|
900
|
+
write_string(*args) # Force text format
|
881
901
|
# Match an array ref.
|
882
|
-
|
902
|
+
elsif token.respond_to?(:to_ary)
|
883
903
|
write_row(*args)
|
884
904
|
elsif token.respond_to?(:coerce) # Numeric
|
885
905
|
write_number(*args)
|
@@ -918,7 +938,7 @@ module Writexlsx
|
|
918
938
|
|
919
939
|
#
|
920
940
|
# :call-seq:
|
921
|
-
# write_row(row, col, array [ , format ]
|
941
|
+
# write_row(row, col, array [ , format ])
|
922
942
|
#
|
923
943
|
# Write a row of data starting from (row, col). Call write_col() if any of
|
924
944
|
# the elements of the array are in turn array. This allows the writing
|
@@ -942,7 +962,7 @@ module Writexlsx
|
|
942
962
|
|
943
963
|
#
|
944
964
|
# :call-seq:
|
945
|
-
# write_col(row, col, array [ , format ]
|
965
|
+
# write_col(row, col, array [ , format ])
|
946
966
|
#
|
947
967
|
# Write a column of data starting from (row, col). Call write_row() if any of
|
948
968
|
# the elements of the array are in turn array. This allows the writing
|
@@ -981,7 +1001,7 @@ module Writexlsx
|
|
981
1001
|
|
982
1002
|
#
|
983
1003
|
# :call-seq:
|
984
|
-
# write_number(row, column, number [ , format ]
|
1004
|
+
# write_number(row, column, number [ , format ])
|
985
1005
|
#
|
986
1006
|
# Write an integer or a float to the cell specified by row and column:
|
987
1007
|
#
|
@@ -994,12 +1014,12 @@ module Writexlsx
|
|
994
1014
|
check_dimensions(row, col)
|
995
1015
|
store_row_col_max_min_values(row, col)
|
996
1016
|
|
997
|
-
store_data_to_table(NumberCellData.new(
|
1017
|
+
store_data_to_table(NumberCellData.new(num, xf), row, col)
|
998
1018
|
end
|
999
1019
|
|
1000
1020
|
#
|
1001
1021
|
# :call-seq:
|
1002
|
-
# write_string(row, column, string [, format ]
|
1022
|
+
# write_string(row, column, string [, format ])
|
1003
1023
|
#
|
1004
1024
|
# Write a string to the specified row and column (zero indexed).
|
1005
1025
|
# +format+ is optional.
|
@@ -1016,12 +1036,12 @@ module Writexlsx
|
|
1016
1036
|
|
1017
1037
|
index = shared_string_index(str.length > STR_MAX ? str[0, STR_MAX] : str)
|
1018
1038
|
|
1019
|
-
store_data_to_table(StringCellData.new(
|
1039
|
+
store_data_to_table(StringCellData.new(index, xf), row, col)
|
1020
1040
|
end
|
1021
1041
|
|
1022
1042
|
#
|
1023
1043
|
# :call-seq:
|
1024
|
-
# write_rich_string(row, column, (string | format, string)+, [,cell_format]
|
1044
|
+
# write_rich_string(row, column, (string | format, string)+, [,cell_format])
|
1025
1045
|
#
|
1026
1046
|
# The write_rich_string() method is used to write strings with multiple formats.
|
1027
1047
|
# The method receives string fragments prefixed by format objects. The final
|
@@ -1044,7 +1064,7 @@ module Writexlsx
|
|
1044
1064
|
|
1045
1065
|
index = shared_string_index(xml_str_of_rich_string(fragments))
|
1046
1066
|
|
1047
|
-
store_data_to_table(StringCellData.new(
|
1067
|
+
store_data_to_table(StringCellData.new(index, xf), row, col)
|
1048
1068
|
end
|
1049
1069
|
|
1050
1070
|
#
|
@@ -1067,12 +1087,177 @@ module Writexlsx
|
|
1067
1087
|
check_dimensions(row, col)
|
1068
1088
|
store_row_col_max_min_values(row, col)
|
1069
1089
|
|
1070
|
-
store_data_to_table(BlankCellData.new(
|
1090
|
+
store_data_to_table(BlankCellData.new(xf), row, col)
|
1071
1091
|
end
|
1072
1092
|
|
1093
|
+
def expand_formula(formula, function, addition = '')
|
1094
|
+
if formula =~ /\b(#{function})/
|
1095
|
+
formula.gsub(
|
1096
|
+
::Regexp.last_match(1),
|
1097
|
+
"_xlfn#{addition}.#{::Regexp.last_match(1)}"
|
1098
|
+
)
|
1099
|
+
else
|
1100
|
+
formula
|
1101
|
+
end
|
1102
|
+
end
|
1103
|
+
private :expand_formula
|
1104
|
+
|
1105
|
+
#
|
1106
|
+
# Utility method to strip equal sign and array braces from a formula
|
1107
|
+
# and also expand out future and dynamic array formulas.
|
1108
|
+
#
|
1109
|
+
def prepare_formula(given_formula)
|
1110
|
+
# Ignore empty/null formulas.
|
1111
|
+
return given_formula unless ptrue?(given_formula)
|
1112
|
+
|
1113
|
+
# Remove array formula braces and the leading =.
|
1114
|
+
formula = given_formula.sub(/^\{(.*)\}$/, '\1').sub(/^=/, '')
|
1115
|
+
|
1116
|
+
# # Don't expand formulas that the user has already expanded.
|
1117
|
+
return formula if formula =~ /_xlfn\./
|
1118
|
+
|
1119
|
+
# Expand dynamic array formulas.
|
1120
|
+
formula = expand_formula(formula, 'LET\(')
|
1121
|
+
formula = expand_formula(formula, 'LAMBDA\(')
|
1122
|
+
formula = expand_formula(formula, 'SINGLE\(')
|
1123
|
+
formula = expand_formula(formula, 'SORTBY\(')
|
1124
|
+
formula = expand_formula(formula, 'UNIQUE\(')
|
1125
|
+
formula = expand_formula(formula, 'XMATCH\(')
|
1126
|
+
formula = expand_formula(formula, 'XLOOKUP\(')
|
1127
|
+
formula = expand_formula(formula, 'SEQUENCE\(')
|
1128
|
+
formula = expand_formula(formula, 'RANDARRAY\(')
|
1129
|
+
formula = expand_formula(formula, 'SORT\(', '._xlws')
|
1130
|
+
formula = expand_formula(formula, 'ANCHORARRAY\(')
|
1131
|
+
formula = expand_formula(formula, 'FILTER\(', '._xlws')
|
1132
|
+
|
1133
|
+
return formula unless @use_future_functions
|
1134
|
+
|
1135
|
+
# Future functions.
|
1136
|
+
formula = expand_formula(formula, 'ACOTH\(')
|
1137
|
+
formula = expand_formula(formula, 'ACOT\(')
|
1138
|
+
formula = expand_formula(formula, 'AGGREGATE\(')
|
1139
|
+
formula = expand_formula(formula, 'ARABIC\(')
|
1140
|
+
formula = expand_formula(formula, 'BASE\(')
|
1141
|
+
formula = expand_formula(formula, 'BETA.DIST\(')
|
1142
|
+
formula = expand_formula(formula, 'BETA.INV\(')
|
1143
|
+
formula = expand_formula(formula, 'BINOM.DIST.RANGE\(')
|
1144
|
+
formula = expand_formula(formula, 'BINOM.DIST\(')
|
1145
|
+
formula = expand_formula(formula, 'BINOM.INV\(')
|
1146
|
+
formula = expand_formula(formula, 'BITAND\(')
|
1147
|
+
formula = expand_formula(formula, 'BITLSHIFT\(')
|
1148
|
+
formula = expand_formula(formula, 'BITOR\(')
|
1149
|
+
formula = expand_formula(formula, 'BITRSHIFT\(')
|
1150
|
+
formula = expand_formula(formula, 'BITXOR\(')
|
1151
|
+
formula = expand_formula(formula, 'CEILING.MATH\(')
|
1152
|
+
formula = expand_formula(formula, 'CEILING.PRECISE\(')
|
1153
|
+
formula = expand_formula(formula, 'CHISQ.DIST.RT\(')
|
1154
|
+
formula = expand_formula(formula, 'CHISQ.DIST\(')
|
1155
|
+
formula = expand_formula(formula, 'CHISQ.INV.RT\(')
|
1156
|
+
formula = expand_formula(formula, 'CHISQ.INV\(')
|
1157
|
+
formula = expand_formula(formula, 'CHISQ.TEST\(')
|
1158
|
+
formula = expand_formula(formula, 'COMBINA\(')
|
1159
|
+
formula = expand_formula(formula, 'CONCAT\(')
|
1160
|
+
formula = expand_formula(formula, 'CONFIDENCE.NORM\(')
|
1161
|
+
formula = expand_formula(formula, 'CONFIDENCE.T\(')
|
1162
|
+
formula = expand_formula(formula, 'COTH\(')
|
1163
|
+
formula = expand_formula(formula, 'COT\(')
|
1164
|
+
formula = expand_formula(formula, 'COVARIANCE.P\(')
|
1165
|
+
formula = expand_formula(formula, 'COVARIANCE.S\(')
|
1166
|
+
formula = expand_formula(formula, 'CSCH\(')
|
1167
|
+
formula = expand_formula(formula, 'CSC\(')
|
1168
|
+
formula = expand_formula(formula, 'DAYS\(')
|
1169
|
+
formula = expand_formula(formula, 'DECIMAL\(')
|
1170
|
+
formula = expand_formula(formula, 'ERF.PRECISE\(')
|
1171
|
+
formula = expand_formula(formula, 'ERFC.PRECISE\(')
|
1172
|
+
formula = expand_formula(formula, 'EXPON.DIST\(')
|
1173
|
+
formula = expand_formula(formula, 'F.DIST.RT\(')
|
1174
|
+
formula = expand_formula(formula, 'F.DIST\(')
|
1175
|
+
formula = expand_formula(formula, 'F.INV.RT\(')
|
1176
|
+
formula = expand_formula(formula, 'F.INV\(')
|
1177
|
+
formula = expand_formula(formula, 'F.TEST\(')
|
1178
|
+
formula = expand_formula(formula, 'FILTERXML\(')
|
1179
|
+
formula = expand_formula(formula, 'FLOOR.MATH\(')
|
1180
|
+
formula = expand_formula(formula, 'FLOOR.PRECISE\(')
|
1181
|
+
formula = expand_formula(formula, 'FORECAST.ETS.CONFINT\(')
|
1182
|
+
formula = expand_formula(formula, 'FORECAST.ETS.SEASONALITY\(')
|
1183
|
+
formula = expand_formula(formula, 'FORECAST.ETS.STAT\(')
|
1184
|
+
formula = expand_formula(formula, 'FORECAST.ETS\(')
|
1185
|
+
formula = expand_formula(formula, 'FORECAST.LINEAR\(')
|
1186
|
+
formula = expand_formula(formula, 'FORMULATEXT\(')
|
1187
|
+
formula = expand_formula(formula, 'GAMMA.DIST\(')
|
1188
|
+
formula = expand_formula(formula, 'GAMMA.INV\(')
|
1189
|
+
formula = expand_formula(formula, 'GAMMALN.PRECISE\(')
|
1190
|
+
formula = expand_formula(formula, 'GAMMA\(')
|
1191
|
+
formula = expand_formula(formula, 'GAUSS\(')
|
1192
|
+
formula = expand_formula(formula, 'HYPGEOM.DIST\(')
|
1193
|
+
formula = expand_formula(formula, 'IFNA\(')
|
1194
|
+
formula = expand_formula(formula, 'IFS\(')
|
1195
|
+
formula = expand_formula(formula, 'IMCOSH\(')
|
1196
|
+
formula = expand_formula(formula, 'IMCOT\(')
|
1197
|
+
formula = expand_formula(formula, 'IMCSCH\(')
|
1198
|
+
formula = expand_formula(formula, 'IMCSC\(')
|
1199
|
+
formula = expand_formula(formula, 'IMSECH\(')
|
1200
|
+
formula = expand_formula(formula, 'IMSEC\(')
|
1201
|
+
formula = expand_formula(formula, 'IMSINH\(')
|
1202
|
+
formula = expand_formula(formula, 'IMTAN\(')
|
1203
|
+
formula = expand_formula(formula, 'ISFORMULA\(')
|
1204
|
+
formula = expand_formula(formula, 'ISOWEEKNUM\(')
|
1205
|
+
formula = expand_formula(formula, 'LOGNORM.DIST\(')
|
1206
|
+
formula = expand_formula(formula, 'LOGNORM.INV\(')
|
1207
|
+
formula = expand_formula(formula, 'MAXIFS\(')
|
1208
|
+
formula = expand_formula(formula, 'MINIFS\(')
|
1209
|
+
formula = expand_formula(formula, 'MODE.MULT\(')
|
1210
|
+
formula = expand_formula(formula, 'MODE.SNGL\(')
|
1211
|
+
formula = expand_formula(formula, 'MUNIT\(')
|
1212
|
+
formula = expand_formula(formula, 'NEGBINOM.DIST\(')
|
1213
|
+
formula = expand_formula(formula, 'NORM.DIST\(')
|
1214
|
+
formula = expand_formula(formula, 'NORM.INV\(')
|
1215
|
+
formula = expand_formula(formula, 'NORM.S.DIST\(')
|
1216
|
+
formula = expand_formula(formula, 'NORM.S.INV\(')
|
1217
|
+
formula = expand_formula(formula, 'NUMBERVALUE\(')
|
1218
|
+
formula = expand_formula(formula, 'PDURATION\(')
|
1219
|
+
formula = expand_formula(formula, 'PERCENTILE.EXC\(')
|
1220
|
+
formula = expand_formula(formula, 'PERCENTILE.INC\(')
|
1221
|
+
formula = expand_formula(formula, 'PERCENTRANK.EXC\(')
|
1222
|
+
formula = expand_formula(formula, 'PERCENTRANK.INC\(')
|
1223
|
+
formula = expand_formula(formula, 'PERMUTATIONA\(')
|
1224
|
+
formula = expand_formula(formula, 'PHI\(')
|
1225
|
+
formula = expand_formula(formula, 'POISSON.DIST\(')
|
1226
|
+
formula = expand_formula(formula, 'QUARTILE.EXC\(')
|
1227
|
+
formula = expand_formula(formula, 'QUARTILE.INC\(')
|
1228
|
+
formula = expand_formula(formula, 'QUERYSTRING\(')
|
1229
|
+
formula = expand_formula(formula, 'RANK.AVG\(')
|
1230
|
+
formula = expand_formula(formula, 'RANK.EQ\(')
|
1231
|
+
formula = expand_formula(formula, 'RRI\(')
|
1232
|
+
formula = expand_formula(formula, 'SECH\(')
|
1233
|
+
formula = expand_formula(formula, 'SEC\(')
|
1234
|
+
formula = expand_formula(formula, 'SHEETS\(')
|
1235
|
+
formula = expand_formula(formula, 'SHEET\(')
|
1236
|
+
formula = expand_formula(formula, 'SKEW.P\(')
|
1237
|
+
formula = expand_formula(formula, 'STDEV.P\(')
|
1238
|
+
formula = expand_formula(formula, 'STDEV.S\(')
|
1239
|
+
formula = expand_formula(formula, 'SWITCH\(')
|
1240
|
+
formula = expand_formula(formula, 'T.DIST.2T\(')
|
1241
|
+
formula = expand_formula(formula, 'T.DIST.RT\(')
|
1242
|
+
formula = expand_formula(formula, 'T.DIST\(')
|
1243
|
+
formula = expand_formula(formula, 'T.INV.2T\(')
|
1244
|
+
formula = expand_formula(formula, 'T.INV\(')
|
1245
|
+
formula = expand_formula(formula, 'T.TEST\(')
|
1246
|
+
formula = expand_formula(formula, 'TEXTJOIN\(')
|
1247
|
+
formula = expand_formula(formula, 'UNICHAR\(')
|
1248
|
+
formula = expand_formula(formula, 'UNICODE\(')
|
1249
|
+
formula = expand_formula(formula, 'VAR.P\(')
|
1250
|
+
formula = expand_formula(formula, 'VAR.S\(')
|
1251
|
+
formula = expand_formula(formula, 'WEBSERVICE\(')
|
1252
|
+
formula = expand_formula(formula, 'WEIBULL.DIST\(')
|
1253
|
+
formula = expand_formula(formula, 'XOR\(')
|
1254
|
+
expand_formula(formula, 'Z.TEST\(')
|
1255
|
+
end
|
1256
|
+
private :prepare_formula
|
1257
|
+
|
1073
1258
|
#
|
1074
1259
|
# :call-seq:
|
1075
|
-
# write_formula(row, column, formula [ , format [ , value ] ]
|
1260
|
+
# write_formula(row, column, formula [ , format [ , value ] ])
|
1076
1261
|
#
|
1077
1262
|
# Write a formula or function to the cell specified by +row+ and +column+:
|
1078
1263
|
#
|
@@ -1081,6 +1266,15 @@ module Writexlsx
|
|
1081
1266
|
row, col, formula, format, value = row_col_notation(args)
|
1082
1267
|
raise WriteXLSXInsufficientArgumentError if [row, col, formula].include?(nil)
|
1083
1268
|
|
1269
|
+
# Check for dynamic array functions.
|
1270
|
+
regex = /\bLET\(|\bSORT\(|\bLAMBDA\(|\bSINGLE\(|\bSORTBY\(|\bUNIQUE\(|\bXMATCH\(|\bFILTER\(|\bXLOOKUP\(|\bSEQUENCE\(|\bRANDARRAY\(|\bANCHORARRAY\(/
|
1271
|
+
if formula =~ regex
|
1272
|
+
return write_dynamic_array_formula(
|
1273
|
+
row, col, row, col, formula, format, value
|
1274
|
+
)
|
1275
|
+
end
|
1276
|
+
|
1277
|
+
# Hand off array formulas.
|
1084
1278
|
if formula =~ /^\{=.*\}$/
|
1085
1279
|
write_array_formula(row, col, row, col, formula, format, value)
|
1086
1280
|
else
|
@@ -1088,7 +1282,7 @@ module Writexlsx
|
|
1088
1282
|
store_row_col_max_min_values(row, col)
|
1089
1283
|
formula = formula.sub(/^=/, '')
|
1090
1284
|
|
1091
|
-
store_data_to_table(FormulaCellData.new(
|
1285
|
+
store_data_to_table(FormulaCellData.new(formula, format, value), row, col)
|
1092
1286
|
end
|
1093
1287
|
end
|
1094
1288
|
|
@@ -1098,7 +1292,15 @@ module Writexlsx
|
|
1098
1292
|
#
|
1099
1293
|
def write_array_formula_base(type, *args)
|
1100
1294
|
# Check for a cell reference in A1 notation and substitute row and column
|
1101
|
-
|
1295
|
+
# Convert single cell to range
|
1296
|
+
if args.first.to_s =~ /^([A-Za-z]+[0-9]+)$/
|
1297
|
+
range = "#{::Regexp.last_match(1)}:#{::Regexp.last_match(1)}"
|
1298
|
+
params = [range] + args[1..]
|
1299
|
+
else
|
1300
|
+
params = args
|
1301
|
+
end
|
1302
|
+
|
1303
|
+
row1, col1, row2, col2, formula, xf, value = row_col_notation(params)
|
1102
1304
|
raise WriteXLSXInsufficientArgumentError if [row1, col1, row2, col2, formula].include?(nil)
|
1103
1305
|
|
1104
1306
|
# Swap last row/col with first row/col as necessary
|
@@ -1118,17 +1320,18 @@ module Writexlsx
|
|
1118
1320
|
"#{xl_rowcol_to_cell(row1, col1)}:#{xl_rowcol_to_cell(row2, col2)}"
|
1119
1321
|
end
|
1120
1322
|
|
1121
|
-
#
|
1122
|
-
formula = formula
|
1323
|
+
# Modify the formula string, as needed.
|
1324
|
+
formula = prepare_formula(formula)
|
1123
1325
|
|
1124
1326
|
store_data_to_table(
|
1125
1327
|
if type == 'a'
|
1126
|
-
FormulaArrayCellData.new(
|
1328
|
+
FormulaArrayCellData.new(formula, xf, range, value)
|
1127
1329
|
elsif type == 'd'
|
1128
|
-
DynamicFormulaArrayCellData.new(
|
1330
|
+
DynamicFormulaArrayCellData.new(formula, xf, range, value)
|
1129
1331
|
else
|
1130
1332
|
raise "invalid type in write_array_formula_base()."
|
1131
|
-
end
|
1333
|
+
end,
|
1334
|
+
row1, col1
|
1132
1335
|
)
|
1133
1336
|
|
1134
1337
|
# Pad out the rest of the area with formatted zeroes.
|
@@ -1176,7 +1379,7 @@ module Writexlsx
|
|
1176
1379
|
check_dimensions(row, col)
|
1177
1380
|
store_row_col_max_min_values(row, col)
|
1178
1381
|
|
1179
|
-
store_data_to_table(BooleanCellData.new(
|
1382
|
+
store_data_to_table(BooleanCellData.new(val, xf), row, col)
|
1180
1383
|
end
|
1181
1384
|
|
1182
1385
|
#
|
@@ -1271,7 +1474,7 @@ module Writexlsx
|
|
1271
1474
|
|
1272
1475
|
#
|
1273
1476
|
# :call-seq:
|
1274
|
-
# write_url(row, column, url [ , format, label, tip ]
|
1477
|
+
# write_url(row, column, url [ , format, label, tip ])
|
1275
1478
|
#
|
1276
1479
|
# Write a hyperlink to a URL in the cell specified by +row+ and +column+.
|
1277
1480
|
# The hyperlink is comprised of two elements: the visible label and
|
@@ -1304,7 +1507,7 @@ module Writexlsx
|
|
1304
1507
|
|
1305
1508
|
#
|
1306
1509
|
# :call-seq:
|
1307
|
-
# write_date_time (row, col, date_string [ , format ]
|
1510
|
+
# write_date_time (row, col, date_string [ , format ])
|
1308
1511
|
#
|
1309
1512
|
# Write a datetime string in ISO8601 "yyyy-mm-ddThh:mm:ss.ss" format as a
|
1310
1513
|
# number representing an Excel date. format is optional.
|
@@ -1321,7 +1524,7 @@ module Writexlsx
|
|
1321
1524
|
date_time = convert_date_time(str)
|
1322
1525
|
|
1323
1526
|
if date_time
|
1324
|
-
store_data_to_table(NumberCellData.new(
|
1527
|
+
store_data_to_table(NumberCellData.new(date_time, xf), row, col)
|
1325
1528
|
else
|
1326
1529
|
# If the date isn't valid then write it as a string.
|
1327
1530
|
write_string(*args)
|
@@ -1330,7 +1533,7 @@ module Writexlsx
|
|
1330
1533
|
|
1331
1534
|
#
|
1332
1535
|
# :call-seq:
|
1333
|
-
# insert_chart(row, column, chart [ , x, y, x_scale, y_scale ]
|
1536
|
+
# insert_chart(row, column, chart [ , x, y, x_scale, y_scale ])
|
1334
1537
|
#
|
1335
1538
|
# This method can be used to insert a Chart object into a worksheet.
|
1336
1539
|
# The Chart must be created by the add_chart() Workbook method and
|
@@ -1343,12 +1546,13 @@ module Writexlsx
|
|
1343
1546
|
|
1344
1547
|
if options.first.instance_of?(Hash)
|
1345
1548
|
params = options.first
|
1346
|
-
x_offset
|
1347
|
-
y_offset
|
1348
|
-
x_scale
|
1349
|
-
y_scale
|
1350
|
-
anchor
|
1351
|
-
|
1549
|
+
x_offset = params[:x_offset]
|
1550
|
+
y_offset = params[:y_offset]
|
1551
|
+
x_scale = params[:x_scale]
|
1552
|
+
y_scale = params[:y_scale]
|
1553
|
+
anchor = params[:object_position]
|
1554
|
+
description = params[:description]
|
1555
|
+
decorative = params[:decorative]
|
1352
1556
|
else
|
1353
1557
|
x_offset, y_offset, x_scale, y_scale, anchor = options
|
1354
1558
|
end
|
@@ -1374,7 +1578,10 @@ module Writexlsx
|
|
1374
1578
|
x_offset = chart.x_offset if ptrue?(chart.x_offset)
|
1375
1579
|
y_offset = chart.y_offset if ptrue?(chart.y_offset)
|
1376
1580
|
|
1377
|
-
@charts << [
|
1581
|
+
@charts << [
|
1582
|
+
row, col, chart, x_offset, y_offset,
|
1583
|
+
x_scale, y_scale, anchor, description, decorative
|
1584
|
+
]
|
1378
1585
|
end
|
1379
1586
|
|
1380
1587
|
#
|
@@ -1415,7 +1622,7 @@ module Writexlsx
|
|
1415
1622
|
|
1416
1623
|
#
|
1417
1624
|
# :call-seq:
|
1418
|
-
# repeat_formula(row, column, formula [ , format ]
|
1625
|
+
# repeat_formula(row, column, formula [ , format ])
|
1419
1626
|
#
|
1420
1627
|
# Deprecated. This is a writeexcel gem's method that is no longer
|
1421
1628
|
# required by WriteXLSX.
|
@@ -1450,7 +1657,7 @@ module Writexlsx
|
|
1450
1657
|
|
1451
1658
|
#
|
1452
1659
|
# :call-seq:
|
1453
|
-
# set_row(row [ , height, format, hidden, level, collapsed ]
|
1660
|
+
# set_row(row [ , height, format, hidden, level, collapsed ])
|
1454
1661
|
#
|
1455
1662
|
# This method can be used to change the default properties of a row.
|
1456
1663
|
# All parameters apart from +row+ are optional.
|
@@ -1866,7 +2073,9 @@ module Writexlsx
|
|
1866
2073
|
def prepare_chart(index, chart_id, drawing_id) # :nodoc:
|
1867
2074
|
drawing_type = 1
|
1868
2075
|
|
1869
|
-
row,
|
2076
|
+
row, col, chart, x_offset, y_offset,
|
2077
|
+
x_scale, y_scale, anchor, description, decorative = @charts[index]
|
2078
|
+
|
1870
2079
|
chart.id = chart_id - 1
|
1871
2080
|
x_scale ||= 0
|
1872
2081
|
y_scale ||= 0
|
@@ -1884,7 +2093,7 @@ module Writexlsx
|
|
1884
2093
|
name = chart.name
|
1885
2094
|
|
1886
2095
|
# Create a Drawing object to use with worksheet unless one already exists.
|
1887
|
-
drawing = Drawing.new(drawing_type, dimensions, 0, 0,
|
2096
|
+
drawing = Drawing.new(drawing_type, dimensions, 0, 0, nil, anchor, drawing_rel_index, 0, nil, name, description, decorative)
|
1888
2097
|
if drawings?
|
1889
2098
|
@drawings.add_drawing_object(drawing)
|
1890
2099
|
else
|
@@ -2603,7 +2812,7 @@ module Writexlsx
|
|
2603
2812
|
height = (0.5 + (height * 9_525)).to_i
|
2604
2813
|
|
2605
2814
|
# Create a Drawing object to use with worksheet unless one already exists.
|
2606
|
-
drawing = Drawing.new(drawing_type, dimensions, width, height,
|
2815
|
+
drawing = Drawing.new(drawing_type, dimensions, width, height, nil, anchor, 0, 0, tip, name, description, decorative)
|
2607
2816
|
if drawings?
|
2608
2817
|
drawings = @drawings
|
2609
2818
|
else
|
@@ -2616,7 +2825,7 @@ module Writexlsx
|
|
2616
2825
|
end
|
2617
2826
|
drawings.add_drawing_object(drawing)
|
2618
2827
|
|
2619
|
-
drawing.description =
|
2828
|
+
drawing.description = name unless description
|
2620
2829
|
|
2621
2830
|
if url
|
2622
2831
|
rel_type = '/hyperlink'
|
@@ -2689,7 +2898,7 @@ EOS
|
|
2689
2898
|
|
2690
2899
|
#
|
2691
2900
|
# :call-seq:
|
2692
|
-
# insert_shape(row, col, shape [ , x, y, x_scale, y_scale ]
|
2901
|
+
# insert_shape(row, col, shape [ , x, y, x_scale, y_scale ])
|
2693
2902
|
#
|
2694
2903
|
# Insert a shape into the worksheet.
|
2695
2904
|
#
|
@@ -2760,7 +2969,7 @@ EOS
|
|
2760
2969
|
drawing_type = 3
|
2761
2970
|
drawing = Drawing.new(
|
2762
2971
|
drawing_type, shape.dimensions, shape.width_emu, shape.height_emu,
|
2763
|
-
shape
|
2972
|
+
shape, shape.anchor, drawing_rel_index, 0, shape.name, nil, 0
|
2764
2973
|
)
|
2765
2974
|
drawings.add_drawing_object(drawing)
|
2766
2975
|
end
|
@@ -2787,6 +2996,9 @@ EOS
|
|
2787
2996
|
"[0]!Button#{button_number}_Click"
|
2788
2997
|
end
|
2789
2998
|
|
2999
|
+
# Set the alt text for the button.
|
3000
|
+
button.description = params[:description]
|
3001
|
+
|
2790
3002
|
# Ensure that a width and height have been set.
|
2791
3003
|
default_width = @default_col_pixels
|
2792
3004
|
default_height = @default_row_pixels
|
@@ -2964,6 +3176,9 @@ EOS
|
|
2964
3176
|
# TODO. Add pageBreakPreview mode when requested.
|
2965
3177
|
attributes << %w[view pageLayout] if page_view?
|
2966
3178
|
|
3179
|
+
# Set the first visible cell.
|
3180
|
+
attributes << ['topLeftCell', @top_left_cell] if ptrue?(@top_left_cell)
|
3181
|
+
|
2967
3182
|
# Set the zoom level.
|
2968
3183
|
if @zoom != 100
|
2969
3184
|
attributes << ['zoomScale', @zoom] unless page_view?
|
@@ -3119,7 +3334,7 @@ EOS
|
|
3119
3334
|
|
3120
3335
|
def write_cell_column_dimension(row_num) # :nodoc:
|
3121
3336
|
(@dim_colmin..@dim_colmax).each do |col_num|
|
3122
|
-
@cell_data_table[row_num][col_num].write_cell if @cell_data_table[row_num][col_num]
|
3337
|
+
@cell_data_table[row_num][col_num].write_cell(self, row_num, col_num) if @cell_data_table[row_num][col_num]
|
3123
3338
|
end
|
3124
3339
|
end
|
3125
3340
|
|
@@ -3984,13 +4199,11 @@ EOS
|
|
3984
4199
|
end
|
3985
4200
|
end
|
3986
4201
|
|
3987
|
-
def store_data_to_table(cell_data) # :nodoc:
|
3988
|
-
row = cell_data.row
|
3989
|
-
col = cell_data.col
|
4202
|
+
def store_data_to_table(cell_data, row, col) # :nodoc:
|
3990
4203
|
if @cell_data_table[row]
|
3991
4204
|
@cell_data_table[row][col] = cell_data
|
3992
4205
|
else
|
3993
|
-
@cell_data_table[row] =
|
4206
|
+
@cell_data_table[row] = []
|
3994
4207
|
@cell_data_table[row][col] = cell_data
|
3995
4208
|
end
|
3996
4209
|
end
|
data/lib/write_xlsx.rb
CHANGED
data/write_xlsx.gemspec
CHANGED
@@ -11,6 +11,7 @@ Gem::Specification.new do |gem|
|
|
11
11
|
gem.summary = 'write_xlsx is a gem to create a new file in the Excel 2007+ XLSX format.'
|
12
12
|
gem.homepage = 'https://github.com/cxn03651/write_xlsx#readme'
|
13
13
|
gem.license = 'MIT'
|
14
|
+
gem.required_ruby_version = '>= 2.5.0'
|
14
15
|
|
15
16
|
gem.files = Dir.chdir(File.expand_path(__dir__)) do
|
16
17
|
`git ls-files -z`.split("\x0").reject do |f|
|
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.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hideo NAKAMURA
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-01-
|
11
|
+
date: 2023-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|
@@ -158,6 +158,7 @@ files:
|
|
158
158
|
- examples/defined_name.rb
|
159
159
|
- examples/demo.rb
|
160
160
|
- examples/diag_border.rb
|
161
|
+
- examples/dynamic_arrays.rb
|
161
162
|
- examples/formats.rb
|
162
163
|
- examples/headers.rb
|
163
164
|
- examples/hide_row_col.rb
|
@@ -166,6 +167,7 @@ files:
|
|
166
167
|
- examples/ignore_errors.rb
|
167
168
|
- examples/indent.rb
|
168
169
|
- examples/keep_leading_zeros.rb
|
170
|
+
- examples/lambda.rb
|
169
171
|
- examples/macros.rb
|
170
172
|
- examples/merge1.rb
|
171
173
|
- examples/merge2.rb
|
@@ -200,6 +202,8 @@ files:
|
|
200
202
|
- examples/tables.rb
|
201
203
|
- examples/update_range_format_with_params.rb
|
202
204
|
- examples/vbaProject.bin
|
205
|
+
- examples/watermark.png
|
206
|
+
- examples/watermark.rb
|
203
207
|
- lib/write_xlsx.rb
|
204
208
|
- lib/write_xlsx/chart.rb
|
205
209
|
- lib/write_xlsx/chart/area.rb
|
@@ -264,14 +268,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
264
268
|
requirements:
|
265
269
|
- - ">="
|
266
270
|
- !ruby/object:Gem::Version
|
267
|
-
version:
|
271
|
+
version: 2.5.0
|
268
272
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
269
273
|
requirements:
|
270
274
|
- - ">="
|
271
275
|
- !ruby/object:Gem::Version
|
272
276
|
version: '0'
|
273
277
|
requirements: []
|
274
|
-
rubygems_version: 3.
|
278
|
+
rubygems_version: 3.4.1
|
275
279
|
signing_key:
|
276
280
|
specification_version: 4
|
277
281
|
summary: write_xlsx is a gem to create a new file in the Excel 2007+ XLSX format.
|