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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/Changes +5 -0
  4. data/LICENSE.txt +1 -1
  5. data/examples/autofilter.rb +38 -9
  6. data/examples/dynamic_arrays.rb +247 -0
  7. data/examples/lambda.rb +43 -0
  8. data/examples/watermark.png +0 -0
  9. data/examples/watermark.rb +26 -0
  10. data/lib/write_xlsx/chart.rb +1 -0
  11. data/lib/write_xlsx/chartsheet.rb +1 -0
  12. data/lib/write_xlsx/col_name.rb +1 -0
  13. data/lib/write_xlsx/colors.rb +1 -0
  14. data/lib/write_xlsx/compatibility.rb +1 -0
  15. data/lib/write_xlsx/drawing.rb +20 -10
  16. data/lib/write_xlsx/format.rb +5 -0
  17. data/lib/write_xlsx/formats.rb +1 -0
  18. data/lib/write_xlsx/gradient.rb +2 -0
  19. data/lib/write_xlsx/package/app.rb +1 -0
  20. data/lib/write_xlsx/package/button.rb +6 -2
  21. data/lib/write_xlsx/package/comments.rb +3 -1
  22. data/lib/write_xlsx/package/conditional_format.rb +1 -0
  23. data/lib/write_xlsx/package/content_types.rb +1 -0
  24. data/lib/write_xlsx/package/core.rb +1 -0
  25. data/lib/write_xlsx/package/custom.rb +1 -0
  26. data/lib/write_xlsx/package/metadata.rb +1 -0
  27. data/lib/write_xlsx/package/packager.rb +1 -0
  28. data/lib/write_xlsx/package/relationships.rb +1 -0
  29. data/lib/write_xlsx/package/shared_strings.rb +1 -1
  30. data/lib/write_xlsx/package/styles.rb +1 -0
  31. data/lib/write_xlsx/package/table.rb +1 -0
  32. data/lib/write_xlsx/package/theme.rb +1 -0
  33. data/lib/write_xlsx/package/vml.rb +1 -0
  34. data/lib/write_xlsx/package/xml_writer_simple.rb +21 -2
  35. data/lib/write_xlsx/shape.rb +1 -0
  36. data/lib/write_xlsx/sheets.rb +1 -0
  37. data/lib/write_xlsx/sparkline.rb +1 -0
  38. data/lib/write_xlsx/utility.rb +2 -3
  39. data/lib/write_xlsx/version.rb +3 -1
  40. data/lib/write_xlsx/worksheet/cell_data.rb +52 -62
  41. data/lib/write_xlsx/worksheet/data_validation.rb +1 -0
  42. data/lib/write_xlsx/worksheet/hyperlink.rb +3 -2
  43. data/lib/write_xlsx/worksheet/page_setup.rb +1 -0
  44. data/lib/write_xlsx/worksheet.rb +260 -47
  45. data/lib/write_xlsx/zip_file_utils.rb +1 -0
  46. data/lib/write_xlsx.rb +1 -0
  47. data/write_xlsx.gemspec +1 -0
  48. metadata +8 -4
@@ -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 = true
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
- if token.respond_to?(:to_ary)
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(self, row, col, num, xf))
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(self, row, col, index, xf))
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(self, row, col, index, xf))
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(self, row, col, xf))
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(self, row, col, formula, format, value))
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
- row1, col1, row2, col2, formula, xf, value = row_col_notation(args)
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
- # Remove array formula braces and the leading =.
1122
- formula = formula.sub(/^\{(.*)\}$/, '\1').sub(/^=/, '')
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(self, row1, col1, formula, xf, range, value)
1328
+ FormulaArrayCellData.new(formula, xf, range, value)
1127
1329
  elsif type == 'd'
1128
- DynamicFormulaArrayCellData.new(self, row1, col1, formula, xf, range, value)
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(self, row, col, val, xf))
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(self, row, col, date_time, xf))
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 = params[:x_offset]
1347
- y_offset = params[:y_offset]
1348
- x_scale = params[:x_scale]
1349
- y_scale = params[:y_scale]
1350
- anchor = params[:object_position]
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 << [row, col, chart, x_offset, y_offset, x_scale, y_scale, anchor]
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, col, chart, x_offset, y_offset, x_scale, y_scale, anchor = @charts[index]
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, name, nil, anchor, drawing_rel_index, 0, nil, 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, name, nil, anchor, 0, 0, tip, decorative)
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 = description if 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.name, shape, shape.anchor, drawing_rel_index, 0, nil, 0
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
@@ -1,4 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
+ # frozen_string_literal: true
2
3
 
3
4
  #
4
5
  # from http://d.hatena.ne.jp/alunko/20071021
data/lib/write_xlsx.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'write_xlsx/workbook'
4
5
 
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.09.5
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-18 00:00:00.000000000 Z
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: '0'
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.3.7
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.