workbook 0.1.6.2 → 0.2.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.
data/Gemfile.lock CHANGED
@@ -1,18 +1,20 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- workbook (0.1.0)
4
+ workbook (0.2.0)
5
5
  fastercsv
6
6
  rchardet (~> 1.3)
7
- spreadsheet (>= 0.6.8)
7
+ rubyXL
8
+ spreadsheet (>= 0.7.5)
8
9
 
9
10
  GEM
10
11
  remote: http://rubygems.org/
11
12
  specs:
12
- fastercsv (1.5.4)
13
- rchardet (1.3)
14
- ruby-ole (1.2.11.3)
15
- spreadsheet (0.6.8)
13
+ fastercsv (1.5.5)
14
+ rchardet (1.3.1)
15
+ ruby-ole (1.2.11.6)
16
+ rubyXL (1.2.10)
17
+ spreadsheet (0.7.5)
16
18
  ruby-ole (>= 1.0)
17
19
 
18
20
  PLATFORMS
data/lib/workbook/book.rb CHANGED
@@ -6,6 +6,9 @@ require 'workbook/readers/txt_reader'
6
6
  require 'rchardet'
7
7
 
8
8
  module Workbook
9
+ # The Book class is the container of sheets. It can be inialized by either the standard initalizer or the open method. The
10
+ # Book class can also keep a reference to a template class, storing shared formatting options.
11
+ #
9
12
  class Book < Array
10
13
  include Workbook::Writers::XlsWriter
11
14
  include Workbook::Readers::XlsReader
@@ -15,7 +18,6 @@ module Workbook
15
18
 
16
19
  attr_accessor :title
17
20
  attr_accessor :template
18
- attr_accessor :default_rewrite_header
19
21
 
20
22
  # @param [Workbook::Sheet, Array] Create a new workbook based on an existing sheet, or initialize a sheet based on the array
21
23
  # @return [Workbook::Book]
@@ -53,13 +55,16 @@ module Workbook
53
55
  first
54
56
  end
55
57
 
58
+ # @return [Boolean] returns true if the first sheet has contents
56
59
  def has_contents?
57
60
  sheet.has_contents?
58
61
  end
59
62
 
60
63
  # Loads an external file into an existing worbook
64
+ #
61
65
  # @param [String] a string with a reference to the file to be opened
62
66
  # @param [String] an optional string enforcing a certain parser (based on the file extension, e.g. 'txt', 'csv' or 'xls')
67
+ # @return [Workbook::Book] A new instance, based on the filename
63
68
  def open filename, ext=nil
64
69
  ext = file_extension(filename) unless ext
65
70
  if ['txt','csv','xml'].include?(ext)
@@ -70,8 +75,10 @@ module Workbook
70
75
  end
71
76
 
72
77
  # Open the file in binary, read-only mode, do not read it, but pas it throug to the extension determined loaded
78
+ #
73
79
  # @param [String] a string with a reference to the file to be opened
74
80
  # @param [String] an optional string enforcing a certain parser (based on the file extension, e.g. 'txt', 'csv' or 'xls')
81
+ # @return [Workbook::Book] A new instance, based on the filename
75
82
  def open_binary filename, ext=nil
76
83
  ext = file_extension(filename) unless ext
77
84
  f = File.open(filename,'rb')
@@ -79,6 +86,7 @@ module Workbook
79
86
  end
80
87
 
81
88
  # Open the file in non-binary, read-only mode, read it and parse it to UTF-8
89
+ #
82
90
  # @param [String] a string with a reference to the file to be opened
83
91
  # @param [String] an optional string enforcing a certain parser (based on the file extension, e.g. 'txt', 'csv' or 'xls')
84
92
  def open_text filename, ext=nil
@@ -91,12 +99,16 @@ module Workbook
91
99
  end
92
100
 
93
101
  # @param [String] The full filename, or path
102
+ #
94
103
  # @return [String] The file extension
95
104
  def file_extension(filename)
96
105
  File.extname(filename).gsub('.','').downcase if filename
97
106
  end
98
107
 
99
108
  # Create an instance from a file, using open.
109
+ #
110
+ # @param [String] the filename of the document
111
+ # @param [String] (not required) enforce a certain extension, the parser is based on the extension of the file
100
112
  # @return [Workbook::Book] A new instance, based on the filename
101
113
  def self.open filename, ext=nil
102
114
  wb = self.new
@@ -114,11 +126,7 @@ module Workbook
114
126
  def sort
115
127
  raise Exception("Books can't be sorted")
116
128
  end
117
-
118
- def default_rewrite_header?
119
- return true if default_rewrite_header.nil?
120
- default_rewrite_header
121
- end
129
+
122
130
 
123
131
  end
124
132
  end
@@ -62,6 +62,7 @@ module RubyXL
62
62
  end
63
63
  end
64
64
  # end monkey patch submitted
65
+
65
66
  module RubyXL
66
67
  class Workbook
67
68
  def num_fmts_by_id
@@ -106,6 +107,7 @@ module RubyXL
106
107
  end
107
108
  end
108
109
  end
110
+
109
111
  # other monkey patch
110
112
  module RubyXL
111
113
  class Cell
data/lib/workbook/row.rb CHANGED
@@ -2,11 +2,14 @@ module Workbook
2
2
  class Row < Array
3
3
  alias_method :compare_without_header, :<=>
4
4
 
5
- #used in compares
5
+ # The placeholder attribute is used in compares (corresponds to newly created or removed lines (depending which side you're on)
6
6
  attr_accessor :placeholder
7
7
  attr_accessor :format
8
8
 
9
9
 
10
+ # @param [Workbook::Row, Array<Workbook::Cell>, Array] list of cells to initialize the row with, default is empty
11
+ # @param [Workbook::Table] a row normally belongs to a table, reference it here
12
+ # @param [Hash], option hash. Supprted options: parse_cells_on_batch_creation (parse cell values during row-initalization, default: false), cell_parse_options (default {}, see Workbook::Modules::TypeParser)
10
13
  def initialize cells=[], table=nil, options={}
11
14
  options=options ? {:parse_cells_on_batch_creation=>false,:cell_parse_options=>{}}.merge(options) : {}
12
15
  cells = [] if cells==nil
@@ -30,7 +33,9 @@ module Workbook
30
33
  @table
31
34
  end
32
35
 
33
- # @param [Workbook::Table] Reference to the table this row belongs to (and adds the row to this table)
36
+ # Set reference to the table this row belongs to (and adds the row to this table)
37
+ #
38
+ # @param [Workbook::Table]
34
39
  def table= t
35
40
  raise ArgumentError, "table should be a Workbook::Table (you passed a #{t.class})" unless t.is_a?(Workbook::Table) or t == nil
36
41
  if t
@@ -39,6 +44,14 @@ module Workbook
39
44
  end
40
45
  end
41
46
 
47
+ # Overrides normal Array's []-function with support for symbols that identify a column based on the header-values
48
+ #
49
+ # @example Lookup using fixnum or header value encoded as symbol
50
+ # row[1] #=> <Cell value="a">
51
+ # row[:a] #=> <Cell value="a">
52
+ #
53
+ # @param [Fixnum, Symbol]
54
+ # @return [Workbook::Cell, nil]
42
55
  def [](index_or_hash)
43
56
  if index_or_hash.is_a? Fixnum
44
57
  return to_a[index_or_hash]
@@ -52,7 +65,11 @@ module Workbook
52
65
  end
53
66
  end
54
67
 
55
- # find_cells_by_color returns an array of cells allows you to find cells by a given color, normally a string containing a hex
68
+ # Returns an array of cells allows you to find cells by a given color, normally a string containing a hex
69
+ #
70
+ # @param [String] default :any colour, can be a CSS-style hex-string
71
+ # @param [Hash] options. Option :hash_keys (default true) returns row as an array of symbols
72
+ # @return [Array<Symbol>, Workbook::Row<Workbook::Cell>]
56
73
  def find_cells_by_background_color color=:any, options={}
57
74
  options = {:hash_keys=>true}.merge(options)
58
75
  cells = self.collect {|c| c if c.format.has_background_color?(color) }.compact
@@ -60,14 +77,19 @@ module Workbook
60
77
  options[:hash_keys] ? r.to_symbols : r
61
78
  end
62
79
 
80
+ # Returns true when the row belongs to a table and it is the header row (typically the first row)
81
+ #
82
+ # @return [Boolean]
63
83
  def header?
64
84
  table != nil and self.object_id == table.header.object_id
65
85
  end
66
86
 
87
+ # @return [Array<Symbol>] returns row as an array of symbols
67
88
  def to_symbols
68
89
  collect{|c| c.to_sym}
69
90
  end
70
91
 
92
+ # @return [Array<Workbook::Cell>] returns row as an array of symbols
71
93
  def to_a
72
94
  self.collect{|c| c}
73
95
  end
@@ -21,9 +21,12 @@ module Workbook
21
21
  end
22
22
  self.sheet = sheet
23
23
  # Column data is considered as a 'row' with 'cells' that contain 'formatting'
24
-
25
24
  end
26
25
 
26
+ # Returns the header of this table (typically the first row, but can be a different row).
27
+ # The header row is also used for finding values in a aribrary row.
28
+ #
29
+ # @return [Workbook::Row] The header
27
30
  def header
28
31
  if @header == false
29
32
  false
@@ -34,9 +37,9 @@ module Workbook
34
37
  end
35
38
  end
36
39
 
37
- # factory pattern...?
38
- def new_row cel_values=[]
39
- r = Workbook::Row.new(cel_values,self)
40
+ # Generates a new row, with optionally predefined cell-values, that is already connected to this table.
41
+ def new_row cell_values=[]
42
+ r = Workbook::Row.new(cell_values,self)
40
43
  return r
41
44
  end
42
45
 
@@ -70,34 +70,28 @@ module Workbook
70
70
  :cyan=>'#00FFFF',
71
71
  :border=>'#FFFFFF',
72
72
  :text=>'#000000',
73
- :lime=>'#00f94c'}
73
+ :lime=>'#00f94c'
74
+ }
74
75
 
76
+ # Generates an Spreadsheet (from the spreadsheet gem) in order to build an XlS
77
+ #
78
+ # @params [Hash] A hash with options (unused so far)
79
+ # @return [Spreadsheet] A Spreadsheet object, ready for writing or more lower level operations
75
80
  def to_xls options={}
76
- options = {:rewrite_header=>default_rewrite_header?}.merge options
77
81
  book = init_spreadsheet_template
78
82
  self.each_with_index do |s,si|
79
83
  xls_sheet = book.worksheet si
80
84
  xls_sheet = book.create_worksheet if xls_sheet == nil
81
85
  s.table.each_with_index do |r, ri|
82
- write_row = false
83
- if r.header?
84
- if options[:rewrite_header] == true
85
- write_row = true
86
- end
87
- else
88
- write_row = true
89
- end
90
- if write_row
91
- xls_sheet.row(ri).height= r.format[:height] if r.format
92
- r.each_with_index do |c, ci|
93
- if c
94
- if r.header?
95
- xls_sheet.columns[ci] ||= Spreadsheet::Column.new(ci,nil)
96
- xls_sheet.columns[ci].width= c.format[:width]
97
- end
98
- xls_sheet.row(ri)[ci] = c.value
99
- xls_sheet.row(ri).set_format(ci, format_to_xls_format(c.format))
86
+ xls_sheet.row(ri).height= r.format[:height] if r.format
87
+ r.each_with_index do |c, ci|
88
+ if c
89
+ if r.header?
90
+ xls_sheet.columns[ci] ||= Spreadsheet::Column.new(ci,nil)
91
+ xls_sheet.columns[ci].width= c.format[:width]
100
92
  end
93
+ xls_sheet.row(ri)[ci] = c.value
94
+ xls_sheet.row(ri).set_format(ci, format_to_xls_format(c.format))
101
95
  end
102
96
  end
103
97
  end
@@ -138,8 +132,12 @@ module Workbook
138
132
  numberformat.gsub('%Y','yyyy').gsub('%A','dddd').gsub('%B','mmmm').gsub('%a','ddd').gsub('%b','mmm').gsub('%y','yy').gsub('%d','dd').gsub('%m','mm').gsub('%y','y').gsub('%y','%%y').gsub('%e','d')
139
133
  end
140
134
 
141
- def write_to_xls options={}
142
- filename = options[:filename] ? options[:filename] : "#{title}.xls"
135
+ # Write the current workbook to Microsoft Excel format (using the spreadsheet gem)
136
+ #
137
+ # @param [String] the filename
138
+ # @param [Hash] options, see #to_xls
139
+
140
+ def write_to_xls filename="#{title}.xls", options={}
143
141
  if to_xls(options).write(filename)
144
142
  return filename
145
143
  end
data/readme.markdown CHANGED
@@ -96,4 +96,12 @@ The [ruby toolbox lists plenty of alternatives](https://www.ruby-toolbox.com/sea
96
96
 
97
97
  ## License
98
98
 
99
- MIT... (c) murb / Maarten Brouwers, 2011-2012
99
+ This code MIT (but see below) (c) murb / Maarten Brouwers, 2011-2013
100
+
101
+ Workbook uses the following gems:
102
+
103
+ * [Spreadsheet](https://github.com/zdavatz/spreadsheet) (Copyright (c) 2010 ywesee GmbH (mhatakeyama@ywesee.com, zdavatz@ywesee.com); GPL3 (License required for closed implementations))
104
+ * [FasterCSV](http://fastercsv.rubyforge.org/) (Copyright (c) James Edward Gray II; GPL2 & Ruby License)
105
+ * [rchardet](http://rubyforge.org/projects/rchardet) (Copyright (c) JMHodges; LGPL)
106
+ * [ruby-ole](http://code.google.com/p/ruby-ole/) (Copyright (c) 2007-2010 Charles Lowe; MIT)
107
+ * [RubyXL](https://github.com/gilt/rubyXL) (Copyright (c) 2011 Vivek Bhagwat; MIT-Licensed)
@@ -99,7 +99,7 @@ module Modules
99
99
  diff_result = tself.diff tother
100
100
  assert_equal('a',diff_result.sheet.table.header[0].value)
101
101
  assert_equal("a,b,c,d\n1,2,3,4\n3,2,3,4\n3,3 (was: 2),3,4\n4,2,3,4\n(was: 5),(was: 2),(was: 3),(was: 4)\n",diff_result.sheet.table.to_csv)
102
- diff_result.write_to_xls({:rewrite_header=>true})
102
+ diff_result.write_to_xls
103
103
  end
104
104
  end
105
105
  end
@@ -31,7 +31,7 @@ module Readers
31
31
  assert_equal(Date.new(2001,1,1),w.sheet.table[1][:a].value)
32
32
  assert_equal(DateTime.new(2011,2,12,12,23),w.sheet.table[4][:c].value)
33
33
  assert_equal("6/12 ovk getekend terugontv.+>acq ter tekening. 13/12 ovk getekend terugontv.+>Fred ter tekening.", w.sheet.table[5][:b].value)
34
- assert_equal(Date.new(2012,6,12),w.sheet.table[5][:c].value)
34
+ assert_equal(DateTime.new(Time.now.year,6,12),w.sheet.table[5][:c].value)
35
35
  end
36
36
  def test_excel_standardized_open
37
37
  w = Workbook::Book.new
@@ -44,7 +44,7 @@ module Readers
44
44
  w = Workbook::Book.new
45
45
  w.open("test/artifacts/txt_in_xls.xls")
46
46
  assert_equal([:naam,:nummer,:ilt,:corporate_key,:naam_medewerker, nil, nil, :telefoon, :openingsdatum],w.sheet.table.header.to_symbols)
47
- assert_equal(["dddd",2222,"i9000","asd","Anita",nil,"Betera",DateTime.new(2012,1,12),Date.new(2011,10,5)],w.sheet.table[1].collect{|a| a.value})
47
+ assert_equal(["dddd",2222,"i9000","asd","Anita",nil,"Betera","012-3456789",Date.new(2011,10,5)],w.sheet.table[1].collect{|a| a.value})
48
48
  end
49
49
  def test_zip_in_xls_open
50
50
  w = Workbook::Book.new
@@ -20,6 +20,16 @@ module Writers
20
20
  b = Workbook::Book.open filename
21
21
  assert_equal(3.85546875,b.sheet.table.first[:a].format[:width])
22
22
  end
23
+ def test_cloning_roundtrip
24
+ b = Workbook::Book.open('test/artifacts/book_with_tabs_and_colours.xls')
25
+ b.sheet.table << b.sheet.table[2]
26
+ assert_equal(90588,b.sheet.table[5][:b].value)
27
+ assert_equal("#FFFF00",b.sheet.table[5][:c].format[:background_color])
28
+ filename = b.write_to_xls
29
+ b = Workbook::Book.open filename
30
+ assert_equal(90588,b.sheet.table[5][:b].value)
31
+ assert_equal("#FFFF00",b.sheet.table[5][:c].format[:background_color])
32
+ end
23
33
 
24
34
  def test_init_spreadsheet_template
25
35
  b = Workbook::Book.new
data/workbook.gemspec CHANGED
@@ -5,12 +5,12 @@ require "workbook"
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'workbook'
7
7
  s.rubyforge_project = 'workbook'
8
- s.version = '0.1.6.2'
9
- s.date = '2012-12-11'
8
+ s.version = '0.2.0'
9
+ s.date = '2013-01-10'
10
10
  s.summary = "Workbook is a datastructure to contain books of tables (an anlogy used in e.g. Excel)"
11
11
  s.description = "Workbook contains workbooks, as in a table, contains rows, contains cells, reads/writes excels and csv's and tab separated, and offers basic diffing and sorting capabilities."
12
12
  s.authors = ["Maarten Brouwers"]
13
- s.add_dependency('spreadsheet', '>= 0.6.8')
13
+ s.add_dependency('spreadsheet', '>= 0.7.5')
14
14
  s.add_dependency('fastercsv')
15
15
  s.add_dependency("rchardet", "~> 1.3")
16
16
  s.add_dependency('rubyXL')
metadata CHANGED
@@ -4,10 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 6
9
7
  - 2
10
- version: 0.1.6.2
8
+ - 0
9
+ version: 0.2.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Maarten Brouwers
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2012-12-11 00:00:00 +01:00
17
+ date: 2013-01-10 00:00:00 +01:00
19
18
  default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
@@ -27,9 +26,9 @@ dependencies:
27
26
  - !ruby/object:Gem::Version
28
27
  segments:
29
28
  - 0
30
- - 6
31
- - 8
32
- version: 0.6.8
29
+ - 7
30
+ - 5
31
+ version: 0.7.5
33
32
  type: :runtime
34
33
  version_requirements: *id001
35
34
  - !ruby/object:Gem::Dependency