rubyXL-git-ref-6002046 2.0.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.
- checksums.yaml +7 -0
- data/Gemfile +20 -0
- data/Gemfile.lock +63 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +197 -0
- data/Rakefile +58 -0
- data/VERSION +1 -0
- data/lib/rubyXL.rb +21 -0
- data/lib/rubyXL/cell.rb +325 -0
- data/lib/rubyXL/generic_storage.rb +40 -0
- data/lib/rubyXL/objects/border.rb +53 -0
- data/lib/rubyXL/objects/cell_style.rb +73 -0
- data/lib/rubyXL/objects/color.rb +23 -0
- data/lib/rubyXL/objects/column_range.rb +88 -0
- data/lib/rubyXL/objects/data_validation.rb +31 -0
- data/lib/rubyXL/objects/defined_name.rb +27 -0
- data/lib/rubyXL/objects/fill.rb +42 -0
- data/lib/rubyXL/objects/font.rb +109 -0
- data/lib/rubyXL/objects/formula.rb +8 -0
- data/lib/rubyXL/objects/ooxml_object.rb +177 -0
- data/lib/rubyXL/objects/reference.rb +98 -0
- data/lib/rubyXL/objects/sheet_view.rb +62 -0
- data/lib/rubyXL/objects/worksheet.rb +11 -0
- data/lib/rubyXL/parser.rb +307 -0
- data/lib/rubyXL/private_class.rb +95 -0
- data/lib/rubyXL/shared_strings.rb +35 -0
- data/lib/rubyXL/workbook.rb +342 -0
- data/lib/rubyXL/worksheet.rb +1118 -0
- data/lib/rubyXL/writer/app_writer.rb +51 -0
- data/lib/rubyXL/writer/calc_chain_writer.rb +18 -0
- data/lib/rubyXL/writer/content_types_writer.rb +113 -0
- data/lib/rubyXL/writer/core_writer.rb +34 -0
- data/lib/rubyXL/writer/generic_writer.rb +33 -0
- data/lib/rubyXL/writer/root_rels_writer.rb +17 -0
- data/lib/rubyXL/writer/shared_strings_writer.rb +21 -0
- data/lib/rubyXL/writer/styles_writer.rb +64 -0
- data/lib/rubyXL/writer/theme_writer.rb +337 -0
- data/lib/rubyXL/writer/workbook_rels_writer.rb +43 -0
- data/lib/rubyXL/writer/workbook_writer.rb +73 -0
- data/lib/rubyXL/writer/worksheet_writer.rb +164 -0
- data/lib/rubyXL/zip.rb +20 -0
- data/rdoc/created.rid +36 -0
- data/rdoc/fonts.css +167 -0
- data/rdoc/fonts/Lato-Light.ttf +0 -0
- data/rdoc/fonts/Lato-LightItalic.ttf +0 -0
- data/rdoc/fonts/Lato-Regular.ttf +0 -0
- data/rdoc/fonts/Lato-RegularItalic.ttf +0 -0
- data/rdoc/fonts/SourceCodePro-Bold.ttf +0 -0
- data/rdoc/fonts/SourceCodePro-Regular.ttf +0 -0
- data/rdoc/images/add.png +0 -0
- data/rdoc/images/arrow_up.png +0 -0
- data/rdoc/images/brick.png +0 -0
- data/rdoc/images/brick_link.png +0 -0
- data/rdoc/images/bug.png +0 -0
- data/rdoc/images/bullet_black.png +0 -0
- data/rdoc/images/bullet_toggle_minus.png +0 -0
- data/rdoc/images/bullet_toggle_plus.png +0 -0
- data/rdoc/images/date.png +0 -0
- data/rdoc/images/delete.png +0 -0
- data/rdoc/images/find.png +0 -0
- data/rdoc/images/loadingAnimation.gif +0 -0
- data/rdoc/images/macFFBgHack.png +0 -0
- data/rdoc/images/package.png +0 -0
- data/rdoc/images/page_green.png +0 -0
- data/rdoc/images/page_white_text.png +0 -0
- data/rdoc/images/page_white_width.png +0 -0
- data/rdoc/images/plugin.png +0 -0
- data/rdoc/images/ruby.png +0 -0
- data/rdoc/images/tag_blue.png +0 -0
- data/rdoc/images/tag_green.png +0 -0
- data/rdoc/images/transparent.png +0 -0
- data/rdoc/images/wrench.png +0 -0
- data/rdoc/images/wrench_orange.png +0 -0
- data/rdoc/images/zoom.png +0 -0
- data/rdoc/js/darkfish.js +140 -0
- data/rdoc/js/jquery.js +18 -0
- data/rdoc/js/navigation.js +142 -0
- data/rdoc/js/search.js +109 -0
- data/rdoc/js/search_index.js +1 -0
- data/rdoc/js/searcher.js +228 -0
- data/rdoc/rdoc.css +580 -0
- data/rubyXL-git-ref-6002046.gemspec +143 -0
- data/spec/lib/cell_spec.rb +407 -0
- data/spec/lib/color_spec.rb +14 -0
- data/spec/lib/parser_spec.rb +80 -0
- data/spec/lib/workbook_spec.rb +73 -0
- data/spec/lib/worksheet_spec.rb +1789 -0
- metadata +231 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
module RubyXL
|
2
|
+
class PrivateClass
|
3
|
+
private
|
4
|
+
|
5
|
+
#validate and modify methods
|
6
|
+
def validate_horizontal_alignment(alignment)
|
7
|
+
if alignment.to_s == '' || alignment == 'center' || alignment == 'distributed' || alignment == 'justify' || alignment == 'left' || alignment == 'right'
|
8
|
+
return true
|
9
|
+
end
|
10
|
+
raise 'Only center, distributed, justify, left, and right are valid horizontal alignments'
|
11
|
+
end
|
12
|
+
|
13
|
+
def validate_vertical_alignment(alignment)
|
14
|
+
if alignment.to_s == '' || alignment == 'center' || alignment == 'distributed' || alignment == 'justify' || alignment == 'top' || alignment == 'bottom'
|
15
|
+
return true
|
16
|
+
end
|
17
|
+
raise 'Only center, distributed, justify, top, and bottom are valid vertical alignments'
|
18
|
+
end
|
19
|
+
|
20
|
+
def validate_text_wrap(wrap)
|
21
|
+
raise 'Only true or false are valid wraps' unless wrap.is_a?(FalseClass) || wrap.is_a?(TrueClass)
|
22
|
+
end
|
23
|
+
|
24
|
+
def validate_border(weight)
|
25
|
+
if weight.to_s == '' || weight == 'thin' || weight == 'thick' || weight == 'hairline' || weight == 'medium'
|
26
|
+
return true
|
27
|
+
end
|
28
|
+
raise 'Border weights must only be "hairline", "thin", "medium", or "thick"'
|
29
|
+
end
|
30
|
+
|
31
|
+
def validate_nonnegative(row_or_col)
|
32
|
+
if row_or_col < 0
|
33
|
+
raise 'Row and Column arguments must be nonnegative'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# This method checks to see if there is an equivalent xf that exists
|
38
|
+
def find_xf(workbook, xf)
|
39
|
+
workbook.cell_xfs.each_with_index { |xfs, index| return index if xfs == xf }
|
40
|
+
return nil
|
41
|
+
end
|
42
|
+
|
43
|
+
# Determines if xf exists
|
44
|
+
# If yes, return id of existing xf
|
45
|
+
# If no, appends xf to xf array
|
46
|
+
def modify_xf(workbook, xf)
|
47
|
+
existing_xf_id = find_xf(workbook, xf)
|
48
|
+
if !existing_xf_id.nil?
|
49
|
+
xf_id = existing_xf_id
|
50
|
+
else
|
51
|
+
xf.apply_font = true
|
52
|
+
xf_id = workbook.cell_xfs.size - 1
|
53
|
+
end
|
54
|
+
return xf_id
|
55
|
+
end
|
56
|
+
|
57
|
+
#modifies fill array (copies, appends, adds color and solid attribute)
|
58
|
+
#then styles array (copies, appends)
|
59
|
+
def modify_fill(workbook, style_index, rgb)
|
60
|
+
xf = workbook.cell_xfs[style_index]
|
61
|
+
new_fill = RubyXL::Fill.new(:pattern_fill =>
|
62
|
+
RubyXL::PatternFill.new(:pattern_type => 'solid', :fg_color => RubyXL::Color.new(:rgb => rgb)))
|
63
|
+
new_xf = workbook.register_new_fill(new_fill, xf)
|
64
|
+
workbook.register_new_xf(new_xf, style_index)
|
65
|
+
end
|
66
|
+
|
67
|
+
#is_horizontal is true when doing horizontal alignment,
|
68
|
+
#false when doing vertical alignment
|
69
|
+
def modify_alignment(workbook, style_index, is_horizontal, alignment)
|
70
|
+
old_xf = workbook.cell_xfs[style_index]
|
71
|
+
|
72
|
+
xf = old_xf.dup
|
73
|
+
xf.alignment ||= RubyXL::Alignment.new
|
74
|
+
|
75
|
+
if is_horizontal then xf.alignment.horizontal = alignment
|
76
|
+
else xf.alignment.vertical = alignment
|
77
|
+
end
|
78
|
+
xf.apply_alignment = true
|
79
|
+
|
80
|
+
workbook.register_new_xf(xf, style_index)
|
81
|
+
end
|
82
|
+
|
83
|
+
def modify_text_wrap(workbook, style_index, wrapText = false)
|
84
|
+
old_xf = workbook.cell_xfs[style_index]
|
85
|
+
|
86
|
+
xf = old_xf.dup
|
87
|
+
xf.alignment ||= RubyXL::Alignment.new
|
88
|
+
xf.alignment.wrap_text = wrapText
|
89
|
+
xf.apply_alignment = true
|
90
|
+
|
91
|
+
workbook.register_new_xf(xf, style_index)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module RubyXL
|
2
|
+
class SharedStrings
|
3
|
+
|
4
|
+
attr_accessor :count_attr, :unique_count_attr
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
# So far, going by the structure that the original creator had in mind. However,
|
8
|
+
# since the actual implementation is now extracted into a separate class,
|
9
|
+
# we will be able to transparrently change it later if needs be.
|
10
|
+
@content_by_index = []
|
11
|
+
@index_by_content = {}
|
12
|
+
@unique_count_attr = @count_attr = nil # TODO
|
13
|
+
end
|
14
|
+
|
15
|
+
def empty?
|
16
|
+
@content_by_index.empty?
|
17
|
+
end
|
18
|
+
|
19
|
+
def add(str, index)
|
20
|
+
@content_by_index[index] = str
|
21
|
+
@index_by_content[str] = index
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_index(str, add_if_missing = false)
|
25
|
+
index = @index_by_content[str]
|
26
|
+
index = add(str) if index.nil? && add_if_missing
|
27
|
+
index
|
28
|
+
end
|
29
|
+
|
30
|
+
def[](index)
|
31
|
+
@content_by_index[index]
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,342 @@
|
|
1
|
+
require 'rubyXL/writer/generic_writer'
|
2
|
+
require 'rubyXL/writer/content_types_writer'
|
3
|
+
require 'rubyXL/writer/root_rels_writer'
|
4
|
+
require 'rubyXL/writer/app_writer'
|
5
|
+
require 'rubyXL/writer/core_writer'
|
6
|
+
require 'rubyXL/writer/theme_writer'
|
7
|
+
require 'rubyXL/writer/workbook_rels_writer'
|
8
|
+
require 'rubyXL/writer/workbook_writer'
|
9
|
+
require 'rubyXL/writer/styles_writer'
|
10
|
+
require 'rubyXL/writer/shared_strings_writer'
|
11
|
+
require 'rubyXL/writer/worksheet_writer'
|
12
|
+
require 'rubyXL/zip'
|
13
|
+
require 'rubyXL/shared_strings'
|
14
|
+
require 'date'
|
15
|
+
|
16
|
+
module RubyXL
|
17
|
+
class Workbook
|
18
|
+
include Enumerable
|
19
|
+
attr_accessor :worksheets, :filepath, :creator, :modifier, :created_at,
|
20
|
+
:modified_at, :company, :application, :appversion, :num_fmts, :fonts, :fills,
|
21
|
+
:borders, :cell_xfs, :cell_style_xfs, :cell_styles, :calc_chain, :theme,
|
22
|
+
:date1904, :media, :external_links, :external_links_rels, :style_corrector,
|
23
|
+
:drawings, :drawings_rels, :charts, :chart_rels,
|
24
|
+
:worksheet_rels, :printer_settings, :macros, :colors, :shared_strings_XML, :defined_names, :column_lookup_hash
|
25
|
+
|
26
|
+
attr_reader :shared_strings
|
27
|
+
|
28
|
+
APPLICATION = 'Microsoft Macintosh Excel'
|
29
|
+
APPVERSION = '12.0000'
|
30
|
+
|
31
|
+
def initialize(worksheets=[], filepath=nil, creator=nil, modifier=nil, created_at=nil,
|
32
|
+
company='', application=APPLICATION,
|
33
|
+
appversion=APPVERSION, date1904=0)
|
34
|
+
|
35
|
+
# Order of sheets in the +worksheets+ array corresponds to the order of pages in Excel UI.
|
36
|
+
# SheetId's, rId's, etc. are completely unrelated to ordering.
|
37
|
+
@worksheets = worksheets || []
|
38
|
+
|
39
|
+
@worksheets << Worksheet.new(self) if @worksheets.empty?
|
40
|
+
|
41
|
+
@filepath = filepath
|
42
|
+
@creator = creator
|
43
|
+
@modifier = modifier
|
44
|
+
@company = company
|
45
|
+
@application = application
|
46
|
+
@appversion = appversion
|
47
|
+
@num_fmts = []
|
48
|
+
@num_fmts_by_id = nil
|
49
|
+
@fonts = []
|
50
|
+
@fills = nil
|
51
|
+
@borders = []
|
52
|
+
@cell_xfs = []
|
53
|
+
@cell_style_xfs = []
|
54
|
+
@cell_styles = []
|
55
|
+
@shared_strings = RubyXL::SharedStrings.new
|
56
|
+
@calc_chain = nil #unnecessary?
|
57
|
+
@date1904 = date1904 > 0
|
58
|
+
@media = RubyXL::GenericStorage.new(File.join('xl', 'media')).binary
|
59
|
+
@external_links = RubyXL::GenericStorage.new(File.join('xl', 'externalLinks'))
|
60
|
+
@external_links_rels= RubyXL::GenericStorage.new(File.join('xl', 'externalLinks', '_rels'))
|
61
|
+
@style_corrector = nil
|
62
|
+
@drawings = RubyXL::GenericStorage.new(File.join('xl', 'drawings'))
|
63
|
+
@drawings_rels = RubyXL::GenericStorage.new(File.join('xl', 'drawings', '_rels'))
|
64
|
+
@charts = RubyXL::GenericStorage.new(File.join('xl', 'charts'))
|
65
|
+
@chart_rels = RubyXL::GenericStorage.new(File.join('xl', 'charts', '_rels'))
|
66
|
+
@worksheet_rels = RubyXL::GenericStorage.new(File.join('xl', 'worksheets', '_rels'))
|
67
|
+
@theme = RubyXL::GenericStorage.new(File.join('xl', 'theme'))
|
68
|
+
@printer_settings = RubyXL::GenericStorage.new(File.join('xl', 'printerSettings')).binary
|
69
|
+
@macros = RubyXL::GenericStorage.new('xl').binary
|
70
|
+
@colors = {}
|
71
|
+
@shared_strings_XML = nil
|
72
|
+
@defined_names = []
|
73
|
+
@column_lookup_hash = {}
|
74
|
+
|
75
|
+
begin
|
76
|
+
@created_at = DateTime.parse(created_at).strftime('%Y-%m-%dT%TZ')
|
77
|
+
rescue
|
78
|
+
t = Time.now
|
79
|
+
@created_at = t.strftime('%Y-%m-%dT%TZ')
|
80
|
+
end
|
81
|
+
@modified_at = @created_at
|
82
|
+
|
83
|
+
fill_styles()
|
84
|
+
fill_shared_strings()
|
85
|
+
end
|
86
|
+
|
87
|
+
# Finds worksheet by its name or numerical index
|
88
|
+
def [](ind)
|
89
|
+
case ind
|
90
|
+
when Integer then worksheets[ind]
|
91
|
+
when String then worksheets.find { |ws| ws.sheet_name == ind }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Create new simple worksheet and add it to the workbook worksheets
|
96
|
+
#
|
97
|
+
# @param [String] The name for the new worksheet
|
98
|
+
def add_worksheet(name = nil)
|
99
|
+
new_worksheet = Worksheet.new(self, name)
|
100
|
+
worksheets << new_worksheet
|
101
|
+
new_worksheet
|
102
|
+
end
|
103
|
+
|
104
|
+
def each
|
105
|
+
worksheets.each{|i| yield i}
|
106
|
+
end
|
107
|
+
|
108
|
+
def num_fmts_by_id
|
109
|
+
return @num_fmts_by_id unless @num_fmts_by_id.nil?
|
110
|
+
|
111
|
+
@num_fmts_by_id = {}
|
112
|
+
|
113
|
+
num_fmts.each { |fmt| @num_fmts_by_id[fmt.num_fmt_id] = fmt }
|
114
|
+
|
115
|
+
@num_fmts_by_id
|
116
|
+
end
|
117
|
+
|
118
|
+
#filepath of xlsx file (including file itself)
|
119
|
+
def write(filepath = @filepath)
|
120
|
+
validate_before_write
|
121
|
+
|
122
|
+
extension = File.extname(filepath)
|
123
|
+
unless %w{.xlsx .xlsm}.include?(extension)
|
124
|
+
raise "Only xlsx and xlsm files are supported. Unsupported extension: #{extension}"
|
125
|
+
end
|
126
|
+
|
127
|
+
dirpath = File.dirname(filepath)
|
128
|
+
temppath = File.join(dirpath, Dir::Tmpname.make_tmpname([ File.basename(filepath), '.tmp' ], nil))
|
129
|
+
FileUtils.mkdir_p(temppath)
|
130
|
+
zippath = File.join(temppath, 'file.zip')
|
131
|
+
|
132
|
+
Zip::File.open(zippath, Zip::File::CREATE) { |zipfile|
|
133
|
+
[ Writer::ContentTypesWriter, Writer::RootRelsWriter, Writer::AppWriter, Writer::CoreWriter,
|
134
|
+
Writer::ThemeWriter, Writer::WorkbookRelsWriter, Writer::WorkbookWriter, Writer::StylesWriter
|
135
|
+
].each { |writer_class| writer_class.new(self).add_to_zip(zipfile) }
|
136
|
+
|
137
|
+
Writer::SharedStringsWriter.new(self).add_to_zip(zipfile) unless @shared_strings.empty?
|
138
|
+
|
139
|
+
[ @media, @external_links, @external_links_rels,
|
140
|
+
@drawings, @drawings_rels, @charts, @chart_rels,
|
141
|
+
@printer_settings, @worksheet_rels, @macros ].each { |s| s.add_to_zip(zipfile) }
|
142
|
+
|
143
|
+
@worksheets.each_index { |i| Writer::WorksheetWriter.new(self, i).add_to_zip(zipfile) }
|
144
|
+
}
|
145
|
+
|
146
|
+
FileUtils.mv(zippath, filepath)
|
147
|
+
FileUtils.rm_rf(temppath) if File.exist?(filepath)
|
148
|
+
|
149
|
+
return filepath
|
150
|
+
end
|
151
|
+
|
152
|
+
def base_date
|
153
|
+
if @date1904 then
|
154
|
+
Date.new(1904, 1, 1)
|
155
|
+
else
|
156
|
+
# Subtracting one day to accomodate for erroneous 1900 leap year compatibility only for 1900 based dates
|
157
|
+
Date.new(1899, 12, 31) - 1
|
158
|
+
end
|
159
|
+
end
|
160
|
+
private :base_date
|
161
|
+
|
162
|
+
def date_to_num(date)
|
163
|
+
date && (date.ajd - base_date().ajd).to_i
|
164
|
+
end
|
165
|
+
|
166
|
+
def num_to_date(num)
|
167
|
+
num && (base_date + num)
|
168
|
+
end
|
169
|
+
|
170
|
+
def date_num_fmt?(num_fmt)
|
171
|
+
@num_fmt_date_hash ||= {}
|
172
|
+
if @num_fmt_date_hash[num_fmt].nil?
|
173
|
+
@num_fmt_date_hash[num_fmt] = is_date_format?(num_fmt)
|
174
|
+
end
|
175
|
+
return @num_fmt_date_hash[num_fmt]
|
176
|
+
end
|
177
|
+
|
178
|
+
def is_date_format?(num_fmt)
|
179
|
+
num_fmt = num_fmt.downcase
|
180
|
+
skip_chars = ['$', '-', '+', '/', '(', ')', ':', ' ']
|
181
|
+
num_chars = ['0', '#', '?']
|
182
|
+
non_date_formats = ['0.00e+00', '##0.0e+0', 'general', '@']
|
183
|
+
date_chars = ['y','m','d','h','s']
|
184
|
+
|
185
|
+
state = 0
|
186
|
+
s = ''
|
187
|
+
|
188
|
+
num_fmt.split(//).each do |c|
|
189
|
+
case state
|
190
|
+
when 0 then
|
191
|
+
if c == '"'
|
192
|
+
state = 1
|
193
|
+
elsif ['\\', '_', '*'].include?(c)
|
194
|
+
state = 2
|
195
|
+
elsif skip_chars.include?(c)
|
196
|
+
next
|
197
|
+
else
|
198
|
+
s << c
|
199
|
+
end
|
200
|
+
when 1 then
|
201
|
+
state = 0 if c == '"'
|
202
|
+
when 2 then
|
203
|
+
state = 0
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
s.gsub!(/\[[^\]]*\]/, '')
|
208
|
+
|
209
|
+
return false if non_date_formats.include?(s)
|
210
|
+
|
211
|
+
separator = ';'
|
212
|
+
got_sep = 0
|
213
|
+
date_count = 0
|
214
|
+
num_count = 0
|
215
|
+
|
216
|
+
s.split(//).each do |c|
|
217
|
+
if date_chars.include?(c)
|
218
|
+
date_count += 1
|
219
|
+
elsif num_chars.include?(c)
|
220
|
+
num_count += 1
|
221
|
+
elsif c == separator
|
222
|
+
got_sep = 1
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
if date_count > 0 && num_count == 0
|
227
|
+
return true
|
228
|
+
elsif num_count > 0 && date_count == 0
|
229
|
+
return false
|
230
|
+
elsif date_count
|
231
|
+
# ambiguous result
|
232
|
+
elsif got_sep == 0
|
233
|
+
# constant result
|
234
|
+
end
|
235
|
+
|
236
|
+
return date_count > num_count
|
237
|
+
end
|
238
|
+
|
239
|
+
def get_fill_color(xf)
|
240
|
+
fill = @fills[xf.fill_id]
|
241
|
+
pattern = fill && fill.pattern_fill
|
242
|
+
color = pattern && pattern.fg_color
|
243
|
+
color && color.rgb || 'ffffff'
|
244
|
+
end
|
245
|
+
|
246
|
+
def register_new_fill(new_fill, old_xf)
|
247
|
+
new_xf = old_xf.dup
|
248
|
+
|
249
|
+
unless fills[old_xf.fill_id].count == 1 && old_xf.fill_id > 2 # If the old fill is not used anymore, just replace it
|
250
|
+
new_xf.fill_id = fills.find_index { |x| x == new_fill } # Use existing fill, if it exists
|
251
|
+
new_xf.fill_id ||= fills.size # If this fill has never existed before, add it to collection.
|
252
|
+
end
|
253
|
+
|
254
|
+
fills[old_xf.fill_id].count -= 1
|
255
|
+
new_fill.count += 1
|
256
|
+
fills[new_xf.fill_id] = new_fill
|
257
|
+
|
258
|
+
new_xf.apply_fill = true
|
259
|
+
new_xf
|
260
|
+
end
|
261
|
+
|
262
|
+
def register_new_font(new_font, old_xf)
|
263
|
+
new_xf = old_xf.dup
|
264
|
+
|
265
|
+
unless fonts[old_xf.font_id].count == 1 && old_xf.font_id > 1 # If the old font is not used anymore, just replace it
|
266
|
+
new_xf.font_id = fonts.find_index { |x| x == new_font } # Use existing font, if it exists
|
267
|
+
new_xf.font_id ||= fonts.size # If this font has never existed before, add it to collection.
|
268
|
+
end
|
269
|
+
|
270
|
+
fonts[old_xf.font_id].count -= 1
|
271
|
+
new_font.count += 1
|
272
|
+
fonts[new_xf.font_id] = new_font
|
273
|
+
|
274
|
+
new_xf.apply_font = true
|
275
|
+
new_xf
|
276
|
+
end
|
277
|
+
|
278
|
+
def register_new_border(new_border, old_xf)
|
279
|
+
new_xf = old_xf.dup
|
280
|
+
|
281
|
+
unless borders[old_xf.border_id].count == 1 && old_xf.border_id > 0 # If the old border not used anymore, just replace it
|
282
|
+
new_xf.border_id = borders.find_index { |x| x == new_border } # Use existing border, if it exists
|
283
|
+
new_xf.border_id ||= borders.size # If this border has never existed before, add it to collection.
|
284
|
+
end
|
285
|
+
|
286
|
+
borders[old_xf.border_id].count -= 1
|
287
|
+
new_border.count += 1
|
288
|
+
borders[new_xf.border_id] = new_border
|
289
|
+
|
290
|
+
new_xf.apply_border = true
|
291
|
+
new_xf
|
292
|
+
end
|
293
|
+
|
294
|
+
def register_new_xf(new_xf, old_style_index)
|
295
|
+
new_xf_id = cell_xfs.find_index { |xf| xf == new_xf } # Use existing XF, if it exists
|
296
|
+
new_xf_id ||= cell_xfs.size # If this XF has never existed before, add it to collection.
|
297
|
+
|
298
|
+
cell_xfs[old_style_index].count -= 1
|
299
|
+
new_xf.count += 1
|
300
|
+
cell_xfs[new_xf_id] = new_xf
|
301
|
+
|
302
|
+
new_xf_id
|
303
|
+
end
|
304
|
+
|
305
|
+
private
|
306
|
+
|
307
|
+
# Do not change. Excel requires that some of these styles be default,
|
308
|
+
# and will simply assume that the 0 and 1 indexed fonts are the default values.
|
309
|
+
def fill_styles()
|
310
|
+
|
311
|
+
@fonts = [ RubyXL::Font.new(:name => RubyXL::StringValue.new(:val => 'Verdana'), :sz => RubyXL::FloatValue.new(:val => 10) ),
|
312
|
+
RubyXL::Font.new(:name => RubyXL::StringValue.new(:val => 'Verdana'), :sz => RubyXL::FloatValue.new(:val => 8) ) ]
|
313
|
+
|
314
|
+
@fills = [ RubyXL::Fill.new(:pattern_fill => RubyXL::PatternFill.new(:pattern_type => 'none')),
|
315
|
+
RubyXL::Fill.new(:pattern_fill => RubyXL::PatternFill.new(:pattern_type => 'gray125')) ]
|
316
|
+
|
317
|
+
@borders = [ RubyXL::Border.new ]
|
318
|
+
|
319
|
+
@cell_style_xfs = [ RubyXL::XF.new(:num_fmt_id => 0, :font_id => 0, :fill_id => 0, :border_id => 0) ]
|
320
|
+
@cell_xfs = [ RubyXL::XF.new(:num_fmt_id => 0, :font_id => 0, :fill_id => 0, :border_id => 0, :xfId => 0) ]
|
321
|
+
@cell_styles = [ RubyXL::CellStyle.new({ :builtin_id => 0, :name => 'Normal', :xf_id => 0 }) ]
|
322
|
+
end
|
323
|
+
|
324
|
+
|
325
|
+
#fills shared strings hash, contains each unique string
|
326
|
+
def fill_shared_strings()
|
327
|
+
@worksheets.compact.each { |sheet|
|
328
|
+
sheet.sheet_data.each { |row|
|
329
|
+
row.each { |cell|
|
330
|
+
if cell && cell.value && cell.datatype == RubyXL::Cell::SHARED_STRING then
|
331
|
+
get_index(cell.value.to_s, :add_if_missing)
|
332
|
+
end
|
333
|
+
}
|
334
|
+
}
|
335
|
+
}
|
336
|
+
end
|
337
|
+
|
338
|
+
def validate_before_write
|
339
|
+
## TODO CHECK IF STYLE IS OK if not raise
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|