roo 1.13.2 → 2.7.0

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.
Files changed (216) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +17 -0
  3. data/.github/ISSUE_TEMPLATE +10 -0
  4. data/.gitignore +11 -0
  5. data/.simplecov +4 -0
  6. data/.travis.yml +17 -0
  7. data/CHANGELOG.md +626 -0
  8. data/Gemfile +17 -12
  9. data/Gemfile_ruby2 +30 -0
  10. data/Guardfile +23 -0
  11. data/LICENSE +3 -1
  12. data/README.md +285 -0
  13. data/Rakefile +23 -23
  14. data/examples/roo_soap_client.rb +28 -31
  15. data/examples/roo_soap_server.rb +4 -6
  16. data/examples/write_me.rb +9 -10
  17. data/lib/roo/base.rb +298 -495
  18. data/lib/roo/constants.rb +5 -0
  19. data/lib/roo/csv.rb +127 -113
  20. data/lib/roo/errors.rb +11 -0
  21. data/lib/roo/excelx/cell/base.rb +94 -0
  22. data/lib/roo/excelx/cell/boolean.rb +27 -0
  23. data/lib/roo/excelx/cell/date.rb +28 -0
  24. data/lib/roo/excelx/cell/datetime.rb +111 -0
  25. data/lib/roo/excelx/cell/empty.rb +19 -0
  26. data/lib/roo/excelx/cell/number.rb +87 -0
  27. data/lib/roo/excelx/cell/string.rb +19 -0
  28. data/lib/roo/excelx/cell/time.rb +43 -0
  29. data/lib/roo/excelx/cell.rb +106 -0
  30. data/lib/roo/excelx/comments.rb +55 -0
  31. data/lib/roo/excelx/coordinate.rb +12 -0
  32. data/lib/roo/excelx/extractor.rb +21 -0
  33. data/lib/roo/excelx/format.rb +64 -0
  34. data/lib/roo/excelx/relationships.rb +25 -0
  35. data/lib/roo/excelx/shared.rb +32 -0
  36. data/lib/roo/excelx/shared_strings.rb +157 -0
  37. data/lib/roo/excelx/sheet.rb +112 -0
  38. data/lib/roo/excelx/sheet_doc.rb +211 -0
  39. data/lib/roo/excelx/styles.rb +64 -0
  40. data/lib/roo/excelx/workbook.rb +59 -0
  41. data/lib/roo/excelx.rb +376 -602
  42. data/lib/roo/font.rb +17 -0
  43. data/lib/roo/formatters/base.rb +15 -0
  44. data/lib/roo/formatters/csv.rb +84 -0
  45. data/lib/roo/formatters/matrix.rb +23 -0
  46. data/lib/roo/formatters/xml.rb +31 -0
  47. data/lib/roo/formatters/yaml.rb +40 -0
  48. data/lib/roo/libre_office.rb +4 -0
  49. data/lib/roo/link.rb +34 -0
  50. data/lib/roo/open_office.rb +626 -0
  51. data/lib/roo/spreadsheet.rb +22 -23
  52. data/lib/roo/tempdir.rb +21 -0
  53. data/lib/roo/utils.rb +78 -0
  54. data/lib/roo/version.rb +3 -0
  55. data/lib/roo.rb +23 -24
  56. data/roo.gemspec +21 -204
  57. data/spec/helpers.rb +5 -0
  58. data/spec/lib/roo/base_spec.rb +229 -3
  59. data/spec/lib/roo/csv_spec.rb +38 -11
  60. data/spec/lib/roo/excelx/format_spec.rb +7 -6
  61. data/spec/lib/roo/excelx_spec.rb +510 -11
  62. data/spec/lib/roo/libreoffice_spec.rb +16 -6
  63. data/spec/lib/roo/openoffice_spec.rb +30 -8
  64. data/spec/lib/roo/spreadsheet_spec.rb +60 -12
  65. data/spec/lib/roo/utils_spec.rb +106 -0
  66. data/spec/spec_helper.rb +7 -6
  67. data/test/all_ss.rb +12 -11
  68. data/test/excelx/cell/test_base.rb +63 -0
  69. data/test/excelx/cell/test_boolean.rb +36 -0
  70. data/test/excelx/cell/test_date.rb +38 -0
  71. data/test/excelx/cell/test_datetime.rb +45 -0
  72. data/test/excelx/cell/test_empty.rb +7 -0
  73. data/test/excelx/cell/test_number.rb +74 -0
  74. data/test/excelx/cell/test_string.rb +28 -0
  75. data/test/excelx/cell/test_time.rb +30 -0
  76. data/test/formatters/test_csv.rb +119 -0
  77. data/test/formatters/test_matrix.rb +76 -0
  78. data/test/formatters/test_xml.rb +74 -0
  79. data/test/formatters/test_yaml.rb +20 -0
  80. data/test/roo/test_csv.rb +52 -0
  81. data/test/roo/test_excelx.rb +186 -0
  82. data/test/roo/test_libre_office.rb +9 -0
  83. data/test/roo/test_open_office.rb +126 -0
  84. data/test/test_helper.rb +73 -53
  85. data/test/test_roo.rb +1211 -2292
  86. metadata +119 -298
  87. data/CHANGELOG +0 -417
  88. data/Gemfile.lock +0 -78
  89. data/README.markdown +0 -126
  90. data/VERSION +0 -1
  91. data/lib/roo/excel.rb +0 -355
  92. data/lib/roo/excel2003xml.rb +0 -300
  93. data/lib/roo/google.rb +0 -292
  94. data/lib/roo/openoffice.rb +0 -496
  95. data/lib/roo/roo_rails_helper.rb +0 -83
  96. data/lib/roo/worksheet.rb +0 -18
  97. data/scripts/txt2html +0 -67
  98. data/spec/lib/roo/excel2003xml_spec.rb +0 -15
  99. data/spec/lib/roo/excel_spec.rb +0 -17
  100. data/spec/lib/roo/google_spec.rb +0 -64
  101. data/test/files/1900_base.xls +0 -0
  102. data/test/files/1900_base.xlsx +0 -0
  103. data/test/files/1904_base.xls +0 -0
  104. data/test/files/1904_base.xlsx +0 -0
  105. data/test/files/Bibelbund.csv +0 -3741
  106. data/test/files/Bibelbund.ods +0 -0
  107. data/test/files/Bibelbund.xls +0 -0
  108. data/test/files/Bibelbund.xlsx +0 -0
  109. data/test/files/Bibelbund.xml +0 -62518
  110. data/test/files/Bibelbund1.ods +0 -0
  111. data/test/files/Pfand_from_windows_phone.xlsx +0 -0
  112. data/test/files/bad_excel_date.xls +0 -0
  113. data/test/files/bbu.ods +0 -0
  114. data/test/files/bbu.xls +0 -0
  115. data/test/files/bbu.xlsx +0 -0
  116. data/test/files/bbu.xml +0 -152
  117. data/test/files/bode-v1.ods.zip +0 -0
  118. data/test/files/bode-v1.xls.zip +0 -0
  119. data/test/files/boolean.csv +0 -2
  120. data/test/files/boolean.ods +0 -0
  121. data/test/files/boolean.xls +0 -0
  122. data/test/files/boolean.xlsx +0 -0
  123. data/test/files/boolean.xml +0 -112
  124. data/test/files/borders.ods +0 -0
  125. data/test/files/borders.xls +0 -0
  126. data/test/files/borders.xlsx +0 -0
  127. data/test/files/borders.xml +0 -144
  128. data/test/files/bug-numbered-sheet-names.xlsx +0 -0
  129. data/test/files/bug-row-column-fixnum-float.xls +0 -0
  130. data/test/files/bug-row-column-fixnum-float.xml +0 -127
  131. data/test/files/comments.ods +0 -0
  132. data/test/files/comments.xls +0 -0
  133. data/test/files/comments.xlsx +0 -0
  134. data/test/files/csvtypes.csv +0 -1
  135. data/test/files/datetime.ods +0 -0
  136. data/test/files/datetime.xls +0 -0
  137. data/test/files/datetime.xlsx +0 -0
  138. data/test/files/datetime.xml +0 -142
  139. data/test/files/datetime_floatconv.xls +0 -0
  140. data/test/files/datetime_floatconv.xml +0 -148
  141. data/test/files/dreimalvier.ods +0 -0
  142. data/test/files/emptysheets.ods +0 -0
  143. data/test/files/emptysheets.xls +0 -0
  144. data/test/files/emptysheets.xlsx +0 -0
  145. data/test/files/emptysheets.xml +0 -105
  146. data/test/files/excel2003.xml +0 -21140
  147. data/test/files/false_encoding.xls +0 -0
  148. data/test/files/false_encoding.xml +0 -132
  149. data/test/files/file_item_error.xlsx +0 -0
  150. data/test/files/formula.ods +0 -0
  151. data/test/files/formula.xls +0 -0
  152. data/test/files/formula.xlsx +0 -0
  153. data/test/files/formula.xml +0 -134
  154. data/test/files/formula_parse_error.xls +0 -0
  155. data/test/files/formula_parse_error.xml +0 -1833
  156. data/test/files/formula_string_error.xlsx +0 -0
  157. data/test/files/html-escape.ods +0 -0
  158. data/test/files/link.xls +0 -0
  159. data/test/files/link.xlsx +0 -0
  160. data/test/files/matrix.ods +0 -0
  161. data/test/files/matrix.xls +0 -0
  162. data/test/files/named_cells.ods +0 -0
  163. data/test/files/named_cells.xls +0 -0
  164. data/test/files/named_cells.xlsx +0 -0
  165. data/test/files/no_spreadsheet_file.txt +0 -1
  166. data/test/files/numbers1.csv +0 -18
  167. data/test/files/numbers1.ods +0 -0
  168. data/test/files/numbers1.xls +0 -0
  169. data/test/files/numbers1.xlsx +0 -0
  170. data/test/files/numbers1.xml +0 -312
  171. data/test/files/numeric-link.xlsx +0 -0
  172. data/test/files/only_one_sheet.ods +0 -0
  173. data/test/files/only_one_sheet.xls +0 -0
  174. data/test/files/only_one_sheet.xlsx +0 -0
  175. data/test/files/only_one_sheet.xml +0 -67
  176. data/test/files/paragraph.ods +0 -0
  177. data/test/files/paragraph.xls +0 -0
  178. data/test/files/paragraph.xlsx +0 -0
  179. data/test/files/paragraph.xml +0 -127
  180. data/test/files/prova.xls +0 -0
  181. data/test/files/ric.ods +0 -0
  182. data/test/files/simple_spreadsheet.ods +0 -0
  183. data/test/files/simple_spreadsheet.xls +0 -0
  184. data/test/files/simple_spreadsheet.xlsx +0 -0
  185. data/test/files/simple_spreadsheet.xml +0 -225
  186. data/test/files/simple_spreadsheet_from_italo.ods +0 -0
  187. data/test/files/simple_spreadsheet_from_italo.xls +0 -0
  188. data/test/files/simple_spreadsheet_from_italo.xml +0 -242
  189. data/test/files/so_datetime.csv +0 -7
  190. data/test/files/style.ods +0 -0
  191. data/test/files/style.xls +0 -0
  192. data/test/files/style.xlsx +0 -0
  193. data/test/files/style.xml +0 -154
  194. data/test/files/time-test.csv +0 -2
  195. data/test/files/time-test.ods +0 -0
  196. data/test/files/time-test.xls +0 -0
  197. data/test/files/time-test.xlsx +0 -0
  198. data/test/files/time-test.xml +0 -131
  199. data/test/files/type_excel.ods +0 -0
  200. data/test/files/type_excel.xlsx +0 -0
  201. data/test/files/type_excelx.ods +0 -0
  202. data/test/files/type_excelx.xls +0 -0
  203. data/test/files/type_openoffice.xls +0 -0
  204. data/test/files/type_openoffice.xlsx +0 -0
  205. data/test/files/whitespace.ods +0 -0
  206. data/test/files/whitespace.xls +0 -0
  207. data/test/files/whitespace.xlsx +0 -0
  208. data/test/files/whitespace.xml +0 -184
  209. data/test/rm_sub_test.rb +0 -12
  210. data/test/rm_test.rb +0 -7
  211. data/test/test_generic_spreadsheet.rb +0 -259
  212. data/website/index.html +0 -385
  213. data/website/index.txt +0 -423
  214. data/website/javascripts/rounded_corners_lite.inc.js +0 -285
  215. data/website/stylesheets/screen.css +0 -130
  216. data/website/template.rhtml +0 -48
data/lib/roo/google.rb DELETED
@@ -1,292 +0,0 @@
1
- begin
2
- require "google_drive"
3
- rescue LoadError => e
4
- raise e, "Using Roo::Google requires the google_drive gem"
5
- end
6
-
7
- class Roo::Google < Roo::Base
8
- attr_accessor :date_format, :datetime_format
9
-
10
- # Creates a new Google Drive object.
11
- def initialize(spreadsheet_key, options = {})
12
- @filename = spreadsheet_key
13
- @user = options[:user] || ENV['GOOGLE_MAIL']
14
- @password = options[:password] || ENV['GOOGLE_PASSWORD']
15
- @access_token = options[:access_token] || ENV['GOOGLE_TOKEN']
16
-
17
- @worksheets = session.spreadsheet_by_key(@filename).worksheets
18
- @sheets = @worksheets.map {|sheet| sheet.title }
19
- super
20
- @cell = Hash.new {|h,k| h[k]=Hash.new}
21
- @cell_type = Hash.new {|h,k| h[k]=Hash.new}
22
- @formula = Hash.new
23
- @date_format = '%d/%m/%Y'
24
- @datetime_format = '%d/%m/%Y %H:%M:%S'
25
- @time_format = '%H:%M:%S'
26
- end
27
-
28
- # returns an array of sheet names in the spreadsheet
29
- attr_reader :sheets
30
-
31
- def date?(string)
32
- Date.strptime(string, @date_format)
33
- true
34
- rescue
35
- false
36
- end
37
-
38
- # is String a time with format HH:MM:SS?
39
- def time?(string)
40
- DateTime.strptime(string, @time_format)
41
- true
42
- rescue
43
- false
44
- end
45
-
46
- def datetime?(string)
47
- DateTime.strptime(string, @datetime_format)
48
- true
49
- rescue
50
- false
51
- end
52
-
53
- def numeric?(string)
54
- string =~ /^[0-9]+[\.]*[0-9]*$/
55
- end
56
-
57
- def timestring_to_seconds(value)
58
- hms = value.split(':')
59
- hms[0].to_i*3600 + hms[1].to_i*60 + hms[2].to_i
60
- end
61
-
62
- # Returns the content of a spreadsheet-cell.
63
- # (1,1) is the upper left corner.
64
- # (1,1), (1,'A'), ('A',1), ('a',1) all refers to the
65
- # cell at the first line and first row.
66
- def cell(row, col, sheet=nil)
67
- sheet ||= @default_sheet
68
- validate_sheet!(sheet) #TODO: 2007-12-16
69
- read_cells(sheet)
70
- row,col = normalize(row,col)
71
- value = @cell[sheet]["#{row},#{col}"]
72
- if celltype(row,col,sheet) == :date
73
- begin
74
- return Date.strptime(value, @date_format)
75
- rescue ArgumentError
76
- raise "Invalid Date #{sheet}[#{row},#{col}] #{value} using format '{@date_format}'"
77
- end
78
- elsif celltype(row,col,sheet) == :datetime
79
- begin
80
- return DateTime.strptime(value, @datetime_format)
81
- rescue ArgumentError
82
- raise "Invalid DateTime #{sheet}[#{row},#{col}] #{value} using format '{@datetime_format}'"
83
- end
84
- end
85
- return value
86
- end
87
-
88
- # returns the type of a cell:
89
- # * :float
90
- # * :string
91
- # * :date
92
- # * :percentage
93
- # * :formula
94
- # * :time
95
- # * :datetime
96
- def celltype(row, col, sheet=nil)
97
- sheet ||= @default_sheet
98
- read_cells(sheet)
99
- row,col = normalize(row,col)
100
- if @formula.size > 0 && @formula[sheet]["#{row},#{col}"]
101
- :formula
102
- else
103
- @cell_type[sheet]["#{row},#{col}"]
104
- end
105
- end
106
-
107
- # Returns the formula at (row,col).
108
- # Returns nil if there is no formula.
109
- # The method #formula? checks if there is a formula.
110
- def formula(row,col,sheet=nil)
111
- sheet ||= @default_sheet
112
- read_cells(sheet)
113
- row,col = normalize(row,col)
114
- @formula[sheet]["#{row},#{col}"] && @formula[sheet]["#{row},#{col}"]
115
- end
116
- alias_method :formula?, :formula
117
-
118
- # true, if the cell is empty
119
- def empty?(row, col, sheet=nil)
120
- value = cell(row, col, sheet)
121
- return true unless value
122
- return false if value.class == Date # a date is never empty
123
- return false if value.class == Float
124
- return false if celltype(row,col,sheet) == :time
125
- value.empty?
126
- end
127
-
128
- # sets the cell to the content of 'value'
129
- # a formula can be set in the form of '=SUM(...)'
130
- def set(row,col,value,sheet=nil)
131
- sheet ||= @default_sheet
132
- validate_sheet!(sheet)
133
-
134
- sheet_no = sheets.index(sheet)+1
135
- row,col = normalize(row,col)
136
- add_to_cell_roo(row,col,value,sheet_no)
137
- # re-read the portion of the document that has changed
138
- if @cells_read[sheet]
139
- value, value_type = determine_datatype(value.to_s)
140
-
141
- _set_value(row,col,value,sheet)
142
- set_type(row,col,value_type,sheet)
143
- end
144
- end
145
-
146
- # *DEPRECATED*: Use Roo::Google#set instead
147
- def set_value(row,col,value,sheet=nil)
148
- warn "[DEPRECATION] `set_value` is deprecated. Please use `set` instead."
149
- set(row,col,value,sheet)
150
- end
151
-
152
- # returns the first non-empty row in a sheet
153
- def first_row(sheet=nil)
154
- sheet ||= @default_sheet
155
- unless @first_row[sheet]
156
- sheet_no = sheets.index(sheet) + 1
157
- @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
158
- oben_unten_links_rechts(sheet_no)
159
- end
160
- return @first_row[sheet]
161
- end
162
-
163
- # returns the last non-empty row in a sheet
164
- def last_row(sheet=nil)
165
- sheet ||= @default_sheet
166
- unless @last_row[sheet]
167
- sheet_no = sheets.index(sheet) + 1
168
- @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
169
- oben_unten_links_rechts(sheet_no)
170
- end
171
- return @last_row[sheet]
172
- end
173
-
174
- # returns the first non-empty column in a sheet
175
- def first_column(sheet=nil)
176
- sheet ||= @default_sheet
177
- unless @first_column[sheet]
178
- sheet_no = sheets.index(sheet) + 1
179
- @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
180
- oben_unten_links_rechts(sheet_no)
181
- end
182
- return @first_column[sheet]
183
- end
184
-
185
- # returns the last non-empty column in a sheet
186
- def last_column(sheet=nil)
187
- sheet ||= @default_sheet
188
- unless @last_column[sheet]
189
- sheet_no = sheets.index(sheet) + 1
190
- @first_row[sheet], @last_row[sheet], @first_column[sheet], @last_column[sheet] =
191
- oben_unten_links_rechts(sheet_no)
192
- end
193
- return @last_column[sheet]
194
- end
195
-
196
- private
197
-
198
- def _set_value(row,col,value,sheet=nil)
199
- sheet ||= @default_sheet
200
- @cell[sheet][ "#{row},#{col}"] = value
201
- end
202
-
203
- def set_type(row,col,type,sheet=nil)
204
- sheet ||= @default_sheet
205
- @cell_type[sheet]["#{row},#{col}"] = type
206
- end
207
-
208
- # read all cells in a sheet.
209
- def read_cells(sheet=nil)
210
- sheet ||= @default_sheet
211
- validate_sheet!(sheet)
212
- return if @cells_read[sheet]
213
-
214
- sheet_no = sheets.index(sheet)
215
- ws = @worksheets[sheet_no]
216
- for row in 1..ws.num_rows
217
- for col in 1..ws.num_cols
218
- key = "#{row},#{col}"
219
- string_value = ws.input_value(row,col) # item['inputvalue'] || item['inputValue']
220
- numeric_value = ws[row,col] #item['numericvalue'] || item['numericValue']
221
- (value, value_type) = determine_datatype(string_value, numeric_value)
222
- @cell[sheet][key] = value unless value == "" or value == nil
223
- @cell_type[sheet][key] = value_type
224
- @formula[sheet] = {} unless @formula[sheet]
225
- @formula[sheet][key] = string_value if value_type == :formula
226
- end
227
- end
228
- @cells_read[sheet] = true
229
- end
230
-
231
- def determine_datatype(val, numval=nil)
232
- if val.nil? || val[0,1] == '='
233
- ty = :formula
234
- if numeric?(numval)
235
- val = numval.to_f
236
- else
237
- val = numval
238
- end
239
- else
240
- if datetime?(val)
241
- ty = :datetime
242
- elsif date?(val)
243
- ty = :date
244
- elsif numeric?(val)
245
- ty = :float
246
- val = val.to_f
247
- elsif time?(val)
248
- ty = :time
249
- val = timestring_to_seconds(val)
250
- else
251
- ty = :string
252
- end
253
- end
254
- return val, ty
255
- end
256
-
257
- def add_to_cell_roo(row,col,value, sheet_no=1)
258
- sheet_no -= 1
259
- @worksheets[sheet_no][row,col] = value
260
- @worksheets[sheet_no].save
261
- end
262
- def entry_roo(value,row,col)
263
- return value,row,col
264
- end
265
-
266
- def oben_unten_links_rechts(sheet_no)
267
- ws = @worksheets[sheet_no-1]
268
- rows = []
269
- cols = []
270
- for row in 1..ws.num_rows
271
- for col in 1..ws.num_cols
272
- rows << row if ws[row,col] and ws[row,col] != '' #TODO: besser?
273
- cols << col if ws[row,col] and ws[row,col] != '' #TODO: besser?
274
- end
275
- end
276
- return rows.min, rows.max, cols.min, cols.max
277
- end
278
-
279
- def reinitialize
280
- initialize(@filename, user: @user, password: @password, access_token: @access_token)
281
- end
282
-
283
- def session
284
- @session ||= if @user && @password
285
- GoogleDrive.login(@user, @password)
286
- elsif @access_token
287
- GoogleDrive.login_with_oauth(@access_token)
288
- else
289
- warn 'set user and password or access token'
290
- end
291
- end
292
- end