lib/write_xlsx/workbook.rb in write_xlsx-0.64.1 vs lib/write_xlsx/workbook.rb in write_xlsx-0.65.0
- old
+ new
@@ -1,10 +1,12 @@
# -*- coding: utf-8 -*-
require 'write_xlsx/package/xml_writer_simple'
require 'write_xlsx/package/packager'
+require 'write_xlsx/sheets'
require 'write_xlsx/worksheet'
require 'write_xlsx/chartsheet'
+require 'write_xlsx/formats'
require 'write_xlsx/format'
require 'write_xlsx/shape'
require 'write_xlsx/utility'
require 'write_xlsx/chart'
require 'write_xlsx/zip_file_utils'
@@ -12,10 +14,12 @@
require 'tempfile'
require 'digest/md5'
module Writexlsx
+ OFFICE_URL = 'http://schemas.microsoft.com/office/' # :nodoc:
+
# The WriteXLSX provides an object oriented interface to a new Excel workbook.
# The following methods are available through a new workbook.
#
# * new[#method-c-new]
# * add_worksheet[#method-i-add_worksheet]
@@ -32,16 +36,13 @@
#
class Workbook
include Writexlsx::Utility
- BASE_NAME = { :sheet => 'Sheet', :chart => 'Chart'} # :nodoc:
-
attr_writer :firstsheet # :nodoc:
attr_reader :palette # :nodoc:
- attr_reader :font_count, :num_format_count, :border_count, :fill_count, :custom_colors # :nodoc:
- attr_reader :worksheets, :sheetnames, :charts, :drawings # :nodoc:
+ attr_reader :worksheets, :charts, :drawings # :nodoc:
attr_reader :num_comment_files, :num_vml_files, :named_ranges # :nodoc:
attr_reader :doc_properties # :nodoc:
attr_reader :image_types, :images # :nodoc:
attr_reader :shared_strings # :nodoc:
attr_accessor :table_count # :nodoc:
@@ -95,23 +96,16 @@
@date_1904 = false
@activesheet = 0
@firstsheet = 0
@selected = 0
@fileclosed = false
- @sheet_name = 'Sheet'
- @chart_name = 'Chart'
- @sheetname_count = 0
- @chartname_count = 0
- @worksheets = []
+ @worksheets = Sheets.new
@charts = []
@drawings = []
- @sheetnames = []
- @formats = []
+ @formats = Formats.new
@xf_formats = []
- @xf_format_indices = {}
@dxf_formats = []
- @dxf_format_indices = {}
@font_count = 0
@num_format_count = 0
@defined_names = []
@named_ranges = []
@custom_colors = []
@@ -263,11 +257,11 @@
# Write the workbook view properties.
write_book_views
# Write the worksheet names and ids.
- write_sheets
+ @worksheets.write_sheets(@writer)
# Write the workbook defined names.
write_defined_names
# Write the workbook calculation properties.
@@ -303,11 +297,10 @@
#
def add_worksheet(name = '')
name = check_sheetname(name)
worksheet = Worksheet.new(self, @worksheets.size, name)
@worksheets << worksheet
- @sheetnames << name
worksheet
end
#
# This method is use to create a new chart either as a standalone worksheet
@@ -401,11 +394,10 @@
# Check the worksheet name for non-embedded charts.
sheetname = check_chart_sheetname(name)
chartsheet = Chartsheet.new(self, @worksheets.size, sheetname)
chartsheet.chart = chart
@worksheets << chartsheet
- @sheetnames << sheetname
end
@charts << chart
ptrue?(embedded) ? chart : chartsheet
end
@@ -420,20 +412,14 @@
#
# See the {Format Class's rdoc}[Format.html] for more details about
# Format properties and how to set them.
#
def add_format(properties = {})
- init_data = [
- @xf_format_indices,
- @dxf_format_indices,
- properties
- ]
+ format = Format.new(@formats, properties)
- format = Format.new(*init_data)
+ @formats.formats.push(format) # Store format reference
- @formats.push(format) # Store format reference
-
format
end
#
# The +add_shape+ method can be used to create new shapes that may be
@@ -714,11 +700,11 @@
# Local defined names are formatted like "Sheet1!name".
if name =~ /^(.*)!(.*)$/
sheetname = $1
name = $2
- sheet_index = get_sheet_index(sheetname)
+ sheet_index = @worksheets.index_by_name(sheetname)
else
sheet_index = -1 # Use -1 to indicate global names.
end
# Warn if the sheet index wasn't found.
@@ -944,16 +930,25 @@
def shared_strings_empty? # :nodoc:
@shared_strings.empty?
end
- def xf_formats # :nodoc:
- @xf_formats.dup
+ def chartsheet_count
+ @worksheets.chartsheet_count
end
- def dxf_formats # :nodoc:
- @dxf_formats.dup
+ def style_properties
+ [
+ @xf_formats,
+ @palette,
+ @font_count,
+ @num_format_count,
+ @border_count,
+ @fill_count,
+ @custom_colors,
+ @dxf_formats
+ ]
end
private
def setup_filename(file) #:nodoc:
@@ -1035,58 +1030,17 @@
#
# Check for valid worksheet names. We check the length, if it contains any
# invalid characters and if the name is unique in the workbook.
#
def check_sheetname(name) #:nodoc:
- make_and_check_sheet_chart_name(:sheet, name)
+ @worksheets.make_and_check_sheet_chart_name(:sheet, name)
end
def check_chart_sheetname(name)
- make_and_check_sheet_chart_name(:chart, name)
+ @worksheets.make_and_check_sheet_chart_name(:chart, name)
end
- def make_and_check_sheet_chart_name(type, name)
- count = sheet_chart_count_increment(type)
- name = "#{BASE_NAME[type]}#{count}" unless ptrue?(name)
-
- check_valid_sheetname(name)
- name
- end
-
- def sheet_chart_count_increment(type)
- case type
- when :sheet
- @sheetname_count += 1
- when :chart
- @chartname_count += 1
- end
- end
-
- def check_valid_sheetname(name)
- # Check that sheet name is <= 31. Excel limit.
- raise "Sheetname #{name} must be <= #{SHEETNAME_MAX} chars" if name.length > SHEETNAME_MAX
-
- # Check that sheetname doesn't contain any invalid characters
- invalid_char = /[\[\]:*?\/\\]/
- if name =~ invalid_char
- raise 'Invalid character []:*?/\\ in worksheet name: ' + name
- end
-
- # Check that the worksheet name doesn't already exist since this is a fatal
- # error in Excel 97. The check must also exclude case insensitive matches.
- unless is_sheetname_uniq?(name)
- raise "Worksheet name '#{name}', with case ignored, is already used."
- end
- end
-
- def is_sheetname_uniq?(name)
- @worksheets.each do |worksheet|
- return false if name.downcase == worksheet.name.downcase
- end
- true
- end
-
#
# Convert a range formula such as Sheet1!$B$1:$B$5 into a sheet name and cell
# range such as ( 'Sheet1', 0, 1, 4, 1 ).
#
def get_chart_range(range) #:nodoc:
@@ -1182,33 +1136,10 @@
attributes << 'activeTab' << @activesheet
end
@writer.empty_tag('workbookView', attributes)
end
- def write_sheets #:nodoc:
- @writer.tag_elements('sheets') do
- id_num = 1
- @worksheets.each do |sheet|
- write_sheet(sheet.name, id_num, sheet.hidden?)
- id_num += 1
- end
- end
- end
-
- def write_sheet(name, sheet_id, hidden = false) #:nodoc:
- attributes = [
- 'name', name,
- 'sheetId', sheet_id
- ]
-
- if hidden
- attributes << 'state' << 'hidden'
- end
- attributes << 'r:id' << "rId#{sheet_id}"
- @writer.empty_tag_encoded('sheet', attributes)
- end
-
def write_calc_pr #:nodoc:
attributes = ['calcId', 124519]
@writer.empty_tag('calcPr', attributes)
end
@@ -1217,13 +1148,14 @@
@writer.tag_elements(tag) { write_ext }
end
def write_ext #:nodoc:
tag = 'ext'
+ uri = "#{OFFICE_URL}mac/excel/2008/main"
attributes = [
- 'xmlns:mx', 'http://schemas.microsoft.com/office/mac/excel/2008/main',
- 'uri', 'http://schemas.microsoft.com/office/mac/excel/2008/main'
+ 'xmlns:mx', uri,
+ 'uri', uri
]
@writer.tag_elements(tag, attributes) { write_mx_arch_id }
end
def write_mx_arch_id #:nodoc:
@@ -1287,12 +1219,11 @@
prepare_drawings
# Add cached data to charts.
add_chart_data
# Package the workbook.
- packager = Package::Packager.new
- packager.add_workbook(self)
+ packager = Package::Packager.new(self)
packager.set_package_dir(@tempdir)
packager.create_package
# Free up the Packager object.
packager = nil
@@ -1326,11 +1257,11 @@
#
# Iterate through the XF Format objects and separate them into XF and DXF
# formats.
#
def prepare_formats #:nodoc:
- @formats.each do |format|
+ @formats.formats.each do |format|
xf_index = format.xf_index
dxf_index = format.dxf_index
@xf_formats[xf_index] = format if xf_index
@dxf_formats[dxf_index] = format if dxf_index
@@ -1560,21 +1491,20 @@
@num_comment_files = comment_files
# Add a font format for cell comments.
if comment_files > 0
format = Format.new(
- @xf_format_indices,
- @dxf_format_indices,
+ @formats,
:font => 'Tahoma',
:size => 8,
:color_indexed => 81,
:font_only => 1
)
format.get_xf_index
- @formats << format
+ @formats.formats << format
end
end
#
# Add "cached" data to charts to provide the numCache and strCache data for
@@ -1726,11 +1656,11 @@
shape_count = sheet.shapes.size
next if chart_count + image_count + shape_count == 0
drawing_id += 1
- (0 .. chart_count - 1).each do |index|
+ sheet.charts.each_with_index do |chart, index|
chart_ref_id += 1
sheet.prepare_chart(index, chart_ref_id, drawing_id)
end
(0 .. image_count - 1).each do |index|
@@ -1754,26 +1684,9 @@
# Sort the workbook charts references into the order that the were
# written from the worksheets above.
@charts = @charts.sort_by { |chart| chart.id }
@drawing_count = drawing_id
- end
-
- #
- # Convert a sheet name to its index. Return undef otherwise.
- #
- def get_sheet_index(sheetname) #:nodoc:
- sheet_count = @sheetnames.size
- sheet_index = nil
-
- sheetname.sub!(/^'/, '')
- sheetname.sub!(/'$/, '')
-
- ( 0 .. sheet_count - 1 ).each do |i|
- sheet_index = i if sheetname == @sheetnames[i]
- end
-
- sheet_index
end
#
# Extract information from the image file such as dimension, type, filename,
# and extension. Also keep track of previously seen images to optimise out