lib/write_xlsx/workbook.rb in write_xlsx-0.65.1 vs lib/write_xlsx/workbook.rb in write_xlsx-0.69.0

- old
+ new

@@ -39,11 +39,11 @@ include Writexlsx::Utility attr_writer :firstsheet # :nodoc: attr_reader :palette # :nodoc: attr_reader :worksheets, :charts, :drawings # :nodoc: - attr_reader :num_comment_files, :num_vml_files, :named_ranges # :nodoc: + attr_reader :named_ranges # :nodoc: attr_reader :doc_properties # :nodoc: attr_reader :image_types, :images # :nodoc: attr_reader :shared_strings # :nodoc: attr_accessor :table_count # :nodoc: attr_reader :vba_project # :nodoc: @@ -109,12 +109,10 @@ @defined_names = [] @named_ranges = [] @custom_colors = [] @doc_properties = {} @local_time = Time.now - @num_vml_files = 0 - @num_comment_files = 0 @optimization = 0 @x_window = 240 @y_window = 15 @window_width = 16095 @window_height = 9660 @@ -245,36 +243,34 @@ prepare_format_properties write_xml_declaration # Write the root workbook element. - write_workbook + write_workbook do - # Write the XLSX file version. - write_file_version + # Write the XLSX file version. + write_file_version - # Write the workbook properties. - write_workbook_pr + # Write the workbook properties. + write_workbook_pr - # Write the workbook view properties. - write_book_views + # Write the workbook view properties. + write_book_views - # Write the worksheet names and ids. - @worksheets.write_sheets(@writer) + # Write the worksheet names and ids. + @worksheets.write_sheets(@writer) - # Write the workbook defined names. - write_defined_names + # Write the workbook defined names. + write_defined_names - # Write the workbook calculation properties. - write_calc_pr + # Write the workbook calculation properties. + write_calc_pr - # Write the workbook extension storage. - #write_ext_lst + # Write the workbook extension storage. + #write_ext_lst + end - # Close the workbook tag. - write_workbook_end - # Close the XML writer object and filehandle. @writer.crlf @writer.close end @@ -653,11 +649,11 @@ # modified after insertion. In this case the insert_shape() method # returns a reference to the inserted shape (the master). # This is not very useful for inserting multiple shapes, # since the x/y coordinates also gets modified. # - def add_shape(properties) + def add_shape(properties = {}) shape = Shape.new(properties) shape.palette = @palette @shapes ||= [] @shapes << shape #Store shape reference. @@ -691,15 +687,11 @@ # See the defined_name.rb program in the examples dir of the distro. # def define_name(name, formula) sheet_index = nil sheetname = '' - full_name = name - # Remove the = sign from the formula if it exists. - formula.sub!(/^=/, '') - # Local defined names are formatted like "Sheet1!name". if name =~ /^(.*)!(.*)$/ sheetname = $1 name = $2 sheet_index = @worksheets.index_by_name(sheetname) @@ -720,11 +712,11 @@ # Warn if the sheet name looks like a cell name. if name =~ %r(^[a-zA-Z][a-zA-Z]?[a-dA-D]?[0-9]+$) raise "Invalid name '#{name}' looks like a cell name in defined_name()\n" end - @defined_names.push([ name, sheet_index, formula]) + @defined_names.push([ name, sheet_index, formula.sub(/^=/, '') ]) end # # The set_properties method can be used to set the document properties # of the Excel file created by WriteXLSX. These properties are visible @@ -947,10 +939,18 @@ @custom_colors, @dxf_formats ] end + def num_vml_files + @worksheets.select { |sheet| sheet.has_vml? }.count + end + + def num_comment_files + @worksheets.select { |sheet| sheet.has_comments? }.count + end + private def setup_filename(file) #:nodoc: if file.respond_to?(:to_str) && file != '' @filename = file @@ -1083,17 +1083,15 @@ 'xmlns', schema + '/spreadsheetml/2006/main', 'xmlns:r', schema + '/officeDocument/2006/relationships' ] - @writer.start_tag('workbook', attributes) + @writer.tag_elements('workbook', attributes) do + yield + end end - def write_workbook_end #:nodoc: - @writer.end_tag('workbook') - end - def write_file_version #:nodoc: attributes = [ 'appName', 'xl', 'lastEdited', 4, 'lowestEdited', 4, @@ -1142,38 +1140,34 @@ attributes = ['calcId', 124519] @writer.empty_tag('calcPr', attributes) end def write_ext_lst #:nodoc: - tag = 'extLst' - @writer.tag_elements(tag) { write_ext } + @writer.tag_elements('extLst') { write_ext } end def write_ext #:nodoc: - tag = 'ext' - uri = "#{OFFICE_URL}mac/excel/2008/main" attributes = [ - 'xmlns:mx', uri, + 'xmlns:mx', "#{OFFICE_URL}mac/excel/2008/main", 'uri', uri ] - @writer.tag_elements(tag, attributes) { write_mx_arch_id } + @writer.tag_elements('ext', attributes) { write_mx_arch_id } end def write_mx_arch_id #:nodoc: @writer.empty_tag('mx:ArchID', ['Flags', 2]) end def write_defined_names #:nodoc: return if @defined_names.nil? || @defined_names.empty? - tag = 'definedNames' - @writer.tag_elements(tag) do + @writer.tag_elements('definedNames') do @defined_names.each { |defined_name| write_defined_name(defined_name) } end end - def write_defined_name(data) #:nodoc: - name, id, range, hidden = data + def write_defined_name(defined_name) #:nodoc: + name, id, range, hidden = defined_name attributes = ['name', name] attributes << 'localSheetId' << "#{id}" unless id == -1 attributes << 'hidden' << '1' if hidden @@ -1422,90 +1416,82 @@ # Iterate through the worksheets and store any defined names in addition to # any user defined names. Stores the defined names for the Workbook.xml and # the named ranges for App.xml. # def prepare_defined_names #:nodoc: - defined_names = @defined_names - @worksheets.each do |sheet| # Check for Print Area settings. if sheet.autofilter_area - range = sheet.autofilter_area - hidden = 1 - - # Store the defined names. - defined_names << ['_xlnm._FilterDatabase', sheet.index, range, hidden] + @defined_names << [ + '_xlnm._FilterDatabase', + sheet.index, + sheet.autofilter_area, + 1 + ] end # Check for Print Area settings. if !sheet.print_area.empty? - range = sheet.print_area - - # Store the defined names. - defined_names << ['_xlnm.Print_Area', sheet.index, range] + @defined_names << [ + '_xlnm.Print_Area', + sheet.index, + sheet.print_area + ] end # Check for repeat rows/cols. aka, Print Titles. if !sheet.print_repeat_cols.empty? || !sheet.print_repeat_rows.empty? - range = '' - if !sheet.print_repeat_cols.empty? && !sheet.print_repeat_rows.empty? range = sheet.print_repeat_cols + ',' + sheet.print_repeat_rows else range = sheet.print_repeat_cols + sheet.print_repeat_rows end # Store the defined names. - defined_names << ['_xlnm.Print_Titles', sheet.index, range] + @defined_names << ['_xlnm.Print_Titles', sheet.index, range] end end - defined_names = sort_defined_names(defined_names) - @defined_names = defined_names - @named_ranges = extract_named_ranges(defined_names) + @defined_names = sort_defined_names(@defined_names) + @named_ranges = extract_named_ranges(@defined_names) end # # Iterate through the worksheets and set up the VML objects. # def prepare_vml_objects #:nodoc: - comment_id = 0 - vml_data_id = 1 - vml_shape_id = 1024 - vml_files = 0 - comment_files = 0 + comment_id = 0 + vml_drawing_id = 0 + vml_data_id = 1 + vml_shape_id = 1024 - @worksheets.each do |sheet| - next unless sheet.has_vml? - vml_files += 1 - comment_files += 1 if sheet.has_comments? + @worksheets.select { |sheet| sheet.has_vml? }.each do |sheet| + comment_id += 1 if sheet.has_comments? + vml_drawing_id += 1 - comment_id += 1 - count = sheet.prepare_vml_objects(vml_data_id, vml_shape_id, comment_id) + sheet.prepare_vml_objects(vml_data_id, vml_shape_id, + vml_drawing_id, comment_id) # Each VML file should start with a shape id incremented by 1024. - vml_data_id += 1 * ( ( 1024 + sheet.comments_count ) / 1024.0 ).to_i - vml_shape_id += 1024 * ( ( 1024 + sheet.comments_count ) / 1024.0 ).to_i + vml_data_id += 1 * ( 1 + sheet.num_comments_block ) + vml_shape_id += 1024 * ( 1 + sheet.num_comments_block ) end - @num_vml_files = vml_files - @num_comment_files = comment_files + add_font_format_for_cell_comments if num_comment_files > 0 + end - # Add a font format for cell comments. - if comment_files > 0 - format = Format.new( - @formats, - :font => 'Tahoma', - :size => 8, - :color_indexed => 81, - :font_only => 1 - ) + def add_font_format_for_cell_comments + format = Format.new( + @formats, + :font => 'Tahoma', + :size => 8, + :color_indexed => 81, + :font_only => 1 + ) - format.get_xf_index - - @formats.formats << format - end + format.get_xf_index + @formats.formats << format end # # Add "cached" data to charts to provide the numCache and strCache data for # series and title/axis ranges. @@ -1567,10 +1553,9 @@ else token end end end - private :chart_data # # Sort internal and user defined names in the same order as used by Excel. # This may not be strictly necessary but unsorted elements caused a lot of # issues in the the Spreadsheet::WriteExcel binary version. Also makes