workbook 0.1.6.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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