rspreadsheet 0.2.0 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.directory +4 -0
- data/.gitignore +2 -0
- data/.kateproject +4 -0
- data/.kateproject.d/notes.txt +0 -0
- data/DEVEL_BLOG.md +11 -5
- data/GUIDE.md +2 -2
- data/Guardfile +2 -2
- data/README.md +31 -14
- data/lib/class_extensions.rb +0 -11
- data/lib/rspreadsheet/cell.rb +118 -116
- data/lib/rspreadsheet/row.rb +339 -373
- data/lib/rspreadsheet/tools.rb +14 -5
- data/lib/rspreadsheet/version.rb +1 -1
- data/lib/rspreadsheet/worksheet.rb +24 -113
- data/lib/rspreadsheet/xml_tied.rb +234 -0
- data/lib/rspreadsheet.rb +1 -1
- data/reinstall2.sh +7 -0
- data/rspreadsheet.gemspec +6 -7
- data/spec/cell_spec.rb +187 -10
- data/spec/row_spec.rb +63 -7
- data/spec/rspreadsheet_spec.rb +32 -0
- data/spec/testfile1.ods +0 -0
- data/spec/worksheet_spec.rb +6 -4
- metadata +7 -5
- data/lib/rspreadsheet/.row.rb.kate-swp.bak +0 -0
- data/spec/xml_tied_array_spec.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ece0fff71891eecf4cbdf45b2c0d305b63a47e37
|
4
|
+
data.tar.gz: c8429a173fbe6f67d3c870b6cd9220d0a1960ca3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84f8ec487137af55e90ec4227e2828248b60b7e943e49cf261e4538971b25e4b9363f325bcb60ddfd9e98790c07ccb3d9c0bd97570dc168ac312cd559b452748
|
7
|
+
data.tar.gz: 40f34733025850b05f84bd768232bef7f39035733d5973a63d4c24d938e14d9b4021a7a38c7341eab1064535068481e3eaa392b25adec1a3800c19e061cea78c
|
data/.directory
ADDED
data/.gitignore
CHANGED
data/.kateproject
ADDED
File without changes
|
data/DEVEL_BLOG.md
CHANGED
@@ -2,27 +2,33 @@ See [GUIDE.md](GUIDE.md#conventions) for syntax conventions.
|
|
2
2
|
|
3
3
|
## Ideas/wishlist
|
4
4
|
|
5
|
-
* What should be returned when asking for row/cell outside used range? Currently it creates new row/cell on fly, but maybe it should only return nil, so the user needs to insert apropriate rows/cells himself before using them. However it spoils little bit syntax like spreadsheet.rows(5).cells(3) because if rows returns nil, that would fail and ugly constructs like spreadsheet.andand.rows(5).andand.cells(3) would be needed. The only way this could be acoided is by using something like "UncreatedRow" object. This concern falls to category "clash of worlds" like the indexing issue (0 vs 1 based) and many others.
|
5
|
+
* What should be returned when asking for row/cell outside used range? Currently it creates new row/cell on fly, but maybe it should only return nil, so the user needs to insert apropriate rows/cells himself before using them. However it spoils little bit syntax like spreadsheet.rows(5).cells(3) because if rows returns nil, that would fail and ugly constructs like spreadsheet.andand.rows(5).andand.cells(3) would be needed. The only way this could be acoided is by using something like "UncreatedRow" object. This concern falls to category "clash of worlds" like the indexing issue (0 vs 1 based) and many others. - now it returns "UncreatedRow/Cell" which is detached upon value assignement.
|
6
6
|
* In future inntroduce syntax like ``sheet.range('C3:E4')`` for mass operations. Also maybe ``sheet.cells('C3')`` or ``sheet.cells(3, 'C')`` etc.
|
7
7
|
* Trying to make row Enumerable - perhaps skipping empty or undefined cells.
|
8
8
|
* Accessors for nonempty/defined cells.
|
9
9
|
* Maybe insted two syntaxes for accessing cell, we make both of them do the same and return Proxy object which would act either as value or cell.
|
10
10
|
* Allow any of these:
|
11
11
|
* ``book['Spring 2014']`` as alternative to ``book.worksheets('Spring 2014')`` ?
|
12
|
-
* ``sheet.cells
|
13
|
-
* We may have problem with the @parent_row concept in cells. If cell has repeated row as parent and it is detached in some other code, the cell never finds out that its parent_row was changed. A cure to this might be, when there are no "unatacched" cells, and when all cells belong to some row. This way if row detaches it can let know to all its cells.
|
12
|
+
* ``sheet.cells('F13')`` as alternative to ``sheet.cells(14,5)`` ?
|
14
13
|
* Document that there is a little distinction betwean RSpreadsheet and RSpreadsheet::Workbook. The former delegates everythink to the other.
|
14
|
+
* allow `book.worskheets.first` syntax
|
15
|
+
* allow `sheet.cells.sum { |cell| cell.value }
|
16
|
+
* allow `sheet.rows(1).cells.each {} iterate through nonempty cells ??? or all of them until last used
|
17
|
+
* `sheet.rows(1).cells` returns list of cells objects and `sheet.rows(1).cellvalues` return array of values with nils when empty
|
18
|
+
* implement to_csv
|
19
|
+
* longterm plan - go through other used libraries and try to find out whose syntax could be adopted, so this library is drop in replacement (possibly with some config options) for them
|
15
20
|
|
16
21
|
Guiding ideas
|
17
22
|
* xml document is always synchronized with the data. So the save is trivial.
|
18
23
|
* no duplication of data. Objects like RowArray should containg minimum information. This one exists solely to speed up cell search. Taken to extream it is questionable, whether we need such objects at all, it might be possible to always work with xml directly.
|
19
|
-
|
24
|
+
* all cells and rows only server as proxy. they hold index and worksheet pointer and everytime read or write is done, the xml is newly searched. until there is a xmlnode caching we have no problem
|
25
|
+
* all cells returned for particular coordinates are **always the same object**. This way we have no problem to synchronize changes.
|
20
26
|
|
21
27
|
## Developing this gem
|
22
28
|
|
23
29
|
### Automated testing
|
24
30
|
|
25
|
-
* ``
|
31
|
+
* ``bundle exec guard`` will get tested any changes as soon as they are summitted
|
26
32
|
* ``rake spec`` runs all test manually
|
27
33
|
|
28
34
|
### Automated utilities
|
data/GUIDE.md
CHANGED
@@ -46,8 +46,8 @@ book.save
|
|
46
46
|
|
47
47
|
```
|
48
48
|
## Conventions
|
49
|
-
* all
|
49
|
+
* **all indexes are 1-based**. This applies to rows, cells cordinates, and all array like structures like list od worksheets etc. Spreadsheet world is 1-based, ruby is 0-based do I had to make a decision. I intend to make an global option for this, but in early stage I need to keep things simple.
|
50
50
|
* with numeric coordinates row always comes before col as in (row,col)
|
51
51
|
* with alphanumerical col always comes before row as in F12
|
52
|
-
* Shorter syntax worksheet[x,y] returns value, longer syntax worksheet.cells(x,y) return cell objects. This allows to work conviniently with values using short syntax and access the cell object if needed (
|
52
|
+
* Shorter syntax worksheet[x,y] returns value, longer syntax worksheet.cells(x,y) return cell objects. This allows to work conviniently with values using short syntax and access the cell object if needed (to access formatting for example).
|
53
53
|
|
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# rspreadsheet
|
2
2
|
|
3
|
-
[![Build Status](https://travis-ci.org/
|
3
|
+
[![Build Status](https://api.travis-ci.org/gorn/rspreadsheet.svg?branch=master)](https://travis-ci.org/gorn/rspreadsheet) [![Coverage Status](https://coveralls.io/repos/gorn/rspreadsheet/badge.png)](https://coveralls.io/r/gorn/rspreadsheet)
|
4
4
|
|
5
5
|
Manipulating spreadsheets with Ruby. Read, modify, write or create new OpenDocument Spreadsheet files from ruby code.
|
6
6
|
|
@@ -8,30 +8,46 @@ Manipulating spreadsheets with Ruby. Read, modify, write or create new OpenDocum
|
|
8
8
|
|
9
9
|
If you need any help or find a bug please [submit an issue](https://github.com/gorn/rspreadsheet/issues) here. I appreciate any feedback and even if you can not help with code, it is interesting for me to hear from you. Different people have different needs and I want to hear about them. If you are a programmer and you have any ideas, wishes, etc you are welcomed to fork the repository and submit a pull request preferably including a failing test.
|
10
10
|
|
11
|
-
|
11
|
+
Alhought this gem is still in alpha stage I use in my project it and it works fine. Currently I am experimenting with syntax to get stabilized. **Any suggestions regarding the syntax is very welcomed**
|
12
12
|
|
13
13
|
## Examples of usage
|
14
14
|
|
15
15
|
```ruby
|
16
16
|
require 'rspreadsheet'
|
17
|
+
book = Rspreadsheet.open('spreadsheet.ods')
|
18
|
+
sheet = book.worksheets[1]
|
17
19
|
|
18
|
-
book = Rspreadsheet.open('./icecream_list.ods')
|
19
|
-
sheet = book.worksheets 'Icecream list'
|
20
|
-
total = 0
|
21
20
|
|
22
|
-
(
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
# get value of a cell B5 (there are more ways to do this)
|
22
|
+
sheet.B5 # => 'cell value'
|
23
|
+
sheet[5,2] # => 'cell value'
|
24
|
+
sheet.rows(5).cells(2).value # => 'cell value'
|
25
|
+
|
26
|
+
# set value of a cell B5
|
27
|
+
sheet.F5 = 'text'
|
28
|
+
sheet[5,2] = 7
|
29
|
+
sheet.cells(5,2).value = 1.78
|
30
|
+
|
31
|
+
# working with cell format
|
32
|
+
sheet.cells(5,2).format.bold = true
|
33
|
+
sheet.cells(5,2).format.background = '#FF0000'
|
28
34
|
|
29
|
-
|
30
|
-
sheet
|
35
|
+
# calculating sum of cells in row
|
36
|
+
sheet.rows(5).cellvalues.sum
|
37
|
+
sheet.rows(5).cells.sum{ |cell| cell.value }
|
31
38
|
|
32
|
-
|
39
|
+
# iterating over list of people and displaying the data
|
40
|
+
|
41
|
+
total = 0
|
42
|
+
sheet.rows.each do |row|
|
43
|
+
puts "Sponsor #{row[1]} with email #{row(2)} has donated #{row(3)} USD."
|
44
|
+
total += row[3]
|
45
|
+
end
|
46
|
+
puts "Totally fundraised #{total} USD"
|
33
47
|
|
48
|
+
# saving file
|
34
49
|
book.save
|
50
|
+
book.save('different_filename.ods')
|
35
51
|
|
36
52
|
```
|
37
53
|
|
@@ -68,6 +84,7 @@ This project arised from the necessity. Alhought it is not true that there are n
|
|
68
84
|
* [rods](http://www.drbreinlinger.de/ruby/rods/) - this is pretty ok, but it has terrible syntax. I first thought of writing wrapper around it, but it turned to be not so easy. Also last commit is 2 years old.
|
69
85
|
* [rubiod](https://github.com/netoctone/rubiod) - this one is quite ok, the syntax is definitely better that in rods, but it seems also very abandoned. It does not support formats. This is a closest match.
|
70
86
|
* [spreadsheet](https://github.com/zdavatz/spreadsheet) - this does not work with OpenDocument and even with Excel has issues in modyfying document. However since it is supposedly used, and has quite good syntax it might be inspirative. I also find the way this gem handles lazy writing of new rows to Spreadsheet object flawed, as well as strange accesibility of rows array object, which if assigned breaks consistency of sheet.
|
87
|
+
* [roo](https://github.com/roo-rb/roo) can only read spreadsheets and not modify and write them back.
|
71
88
|
|
72
89
|
One of the main ideas is that the manipulation with OpenDOcument files should be forward compatible and as much current data preserving as possible. The parts of the file which are not needed for the change should not be changed. This is different to some of the mentioned gems, which generate the document from scratch, therefore any advanced features present in the original file which are not directly supported are lost.
|
73
90
|
|
data/lib/class_extensions.rb
CHANGED
@@ -1,10 +1,4 @@
|
|
1
1
|
class LibXML::XML::Node
|
2
|
-
def new_with_ns(namespace,name)
|
3
|
-
ns = self.namespaces.find_by_prefix('table') || LibXML::XML::Namespace.new(self, 'table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0')
|
4
|
-
self.namespaces.namespace = ns
|
5
|
-
self
|
6
|
-
LibXML::XML::Node.new('table-row')
|
7
|
-
end
|
8
2
|
def elements
|
9
3
|
result = []
|
10
4
|
each_element { |e| result << e }
|
@@ -40,9 +34,4 @@ class LibXML::XML::Node
|
|
40
34
|
def equals?(node2) #TODO redefine == with this
|
41
35
|
self.simplification_of?(node2) and node2.simplification_of?(self)
|
42
36
|
end
|
43
|
-
def add_table_namesepace
|
44
|
-
ns = self.namespaces.find_by_prefix('table') || LibXML::XML::Namespace.new(self, 'table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0')
|
45
|
-
self.namespaces.namespace = ns
|
46
|
-
self
|
47
|
-
end
|
48
37
|
end
|
data/lib/rspreadsheet/cell.rb
CHANGED
@@ -1,28 +1,38 @@
|
|
1
1
|
require 'andand'
|
2
|
+
require 'rspreadsheet/xml_tied'
|
2
3
|
|
3
4
|
module Rspreadsheet
|
4
|
-
|
5
|
-
class
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class Cell < RowOrNode
|
16
|
-
attr_accessor :worksheet, :rowi, :coli
|
5
|
+
|
6
|
+
class Cell < XMLTiedItem
|
7
|
+
attr_accessor :worksheet, :coli, :rowi
|
8
|
+
def xml_repeated_attribute; 'number-columns-repeated' end
|
9
|
+
def xml_items_node_name; 'table-cell' end
|
10
|
+
def xml_options; {:xml_items_node_name => xml_items_node_name, :xml_repeated_attribute => xml_repeated_attribute} end
|
11
|
+
def parent; row end
|
12
|
+
def index; @coli end
|
13
|
+
def set_index(value); @coli=value end
|
14
|
+
def set_rowi(arowi); @rowi = arowi end # this should ONLY be used by parent row
|
17
15
|
def initialize(aworksheet,arowi,acoli)
|
16
|
+
raise "First parameter should be Worksheet object not #{aworksheet.class}" unless aworksheet.kind_of?(Rspreadsheet::Worksheet)
|
18
17
|
@worksheet = aworksheet
|
19
18
|
@rowi = arowi
|
20
19
|
@coli = acoli
|
21
20
|
end
|
22
21
|
def row; @worksheet.rows(rowi) end
|
23
22
|
def coordinates; [rowi,coli] end
|
24
|
-
|
25
|
-
def
|
23
|
+
def to_s; value.to_s end
|
24
|
+
def valuexml; self.valuexmlnode.andand.inner_xml end
|
25
|
+
def valuexmlnode; self.xmlnode.children.first end
|
26
|
+
# use this to find node in cell xml. ex. xmlfind('.//text:a') finds all link nodes
|
27
|
+
def valuexmlfindall(path)
|
28
|
+
valuexmlnode.nil? ? [] : valuexmlnode.find(path)
|
29
|
+
end
|
30
|
+
def valuexmlfindfirst(path)
|
31
|
+
valuexmlfindall(path).first
|
32
|
+
end
|
33
|
+
def inspect
|
34
|
+
"#<Rspreadsheet::Cell:Cell\n row:#{rowi}, col:#{coli} address:#{address}\n type: #{guess_cell_type.to_s}, value:#{value}\n mode: #{mode}\n>"
|
35
|
+
end
|
26
36
|
def value
|
27
37
|
gt = guess_cell_type
|
28
38
|
if (self.mode == :regular) or (self.mode == :repeated)
|
@@ -31,7 +41,7 @@ class Cell < RowOrNode
|
|
31
41
|
when gt == Float then xmlnode.attributes['value'].to_f
|
32
42
|
when gt == String then xmlnode.elements.first.andand.content.to_s
|
33
43
|
when gt == Date then Date.strptime(xmlnode.attributes['date-value'].to_s, '%Y-%m-%d')
|
34
|
-
when gt ==
|
44
|
+
when gt == :percentage then xmlnode.attributes['value'].to_f
|
35
45
|
end
|
36
46
|
elsif self.mode == :outbound
|
37
47
|
nil
|
@@ -39,7 +49,59 @@ class Cell < RowOrNode
|
|
39
49
|
raise "Unknown cell mode #{self.mode}"
|
40
50
|
end
|
41
51
|
end
|
42
|
-
def
|
52
|
+
def value=(avalue)
|
53
|
+
detach_if_needed
|
54
|
+
if self.mode == :regular
|
55
|
+
gt = guess_cell_type(avalue)
|
56
|
+
case
|
57
|
+
when gt == nil then raise 'This value type is not storable to cell'
|
58
|
+
when gt == Float
|
59
|
+
set_type_attribute('float')
|
60
|
+
remove_all_value_attributes_and_content(xmlnode)
|
61
|
+
Tools.set_ns_attribute(xmlnode,'office','value', avalue.to_s)
|
62
|
+
xmlnode << Tools.create_ns_node('text','p', avalue.to_f.to_s)
|
63
|
+
when gt == String then
|
64
|
+
set_type_attribute('string')
|
65
|
+
remove_all_value_attributes_and_content(xmlnode)
|
66
|
+
xmlnode << Tools.create_ns_node('text','p', avalue.to_s)
|
67
|
+
when gt == Date then
|
68
|
+
set_type_attribute('date')
|
69
|
+
remove_all_value_attributes_and_content(xmlnode)
|
70
|
+
Tools.set_ns_attribute(xmlnode,'office','date-value', avalue.strftime('%Y-%m-%d'))
|
71
|
+
xmlnode << Tools.create_ns_node('text','p', avalue.strftime('%Y-%m-%d'))
|
72
|
+
when gt == :percentage
|
73
|
+
set_type_attribute('percentage')
|
74
|
+
remove_all_value_attributes_and_content(xmlnode)
|
75
|
+
Tools.set_ns_attribute(xmlnode,'office','value', '%0.2d%' % avalue.to_f)
|
76
|
+
xmlnode << Tools.create_ns_node('text','p', (avalue.to_f*100).round.to_s+'%')
|
77
|
+
end
|
78
|
+
else
|
79
|
+
raise "Unknown cell mode #{self.mode}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
def set_type_attribute(typestring)
|
83
|
+
Tools.set_ns_attribute(xmlnode,'office','value-type',typestring)
|
84
|
+
end
|
85
|
+
def remove_all_value_attributes_and_content(node)
|
86
|
+
if att = Tools.get_ns_attribute(node, 'office','value') then att.remove! end
|
87
|
+
if att = Tools.get_ns_attribute(node, 'office','date-value') then att.remove! end
|
88
|
+
node.content=''
|
89
|
+
end
|
90
|
+
def relative(rowdiff,coldiff)
|
91
|
+
@worksheet.cells(self.rowi+rowdiff, self.coli+coldiff)
|
92
|
+
end
|
93
|
+
def type
|
94
|
+
gct = guess_cell_type
|
95
|
+
case
|
96
|
+
when gct == Float then :float
|
97
|
+
when gct == String then :string
|
98
|
+
when gct == Date then :date
|
99
|
+
when gct == :percentage then :percentage
|
100
|
+
when gct == :unassigned then :unassigned
|
101
|
+
when gct == nil then :unknown
|
102
|
+
else :unknown
|
103
|
+
end
|
104
|
+
end
|
43
105
|
def guess_cell_type(avalue=nil)
|
44
106
|
# try guessing by value
|
45
107
|
valueguess = case avalue
|
@@ -88,114 +150,49 @@ class Cell < RowOrNode
|
|
88
150
|
nil
|
89
151
|
end
|
90
152
|
end
|
153
|
+
elsif valueguess == Float and xmlnode.andand.attributes['value-type'] == 'percentage'
|
154
|
+
result = :percentage
|
91
155
|
end
|
92
156
|
result
|
93
157
|
end
|
94
|
-
def
|
95
|
-
|
96
|
-
@worksheet.detach_cell_in_xml(rowi,coli)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
def value=(avalue)
|
100
|
-
detach_if_needed
|
101
|
-
if self.mode == :regular
|
102
|
-
gt = guess_cell_type(avalue)
|
103
|
-
case
|
104
|
-
when gt == nil then raise 'This value type is not storable to cell'
|
105
|
-
when gt == Float
|
106
|
-
set_type_attribute('float')
|
107
|
-
remove_all_value_attributes_and_content(xmlnode)
|
108
|
-
Tools.set_ns_attribute(xmlnode,'office','value', avalue.to_s)
|
109
|
-
xmlnode << LibXML::XML::Node.new('p', avalue.to_f.to_s, ns_text)
|
110
|
-
when gt == String then
|
111
|
-
set_type_attribute('string')
|
112
|
-
remove_all_value_attributes_and_content(xmlnode)
|
113
|
-
xmlnode << LibXML::XML::Node.new('p', avalue.to_s, ns_text)
|
114
|
-
when gt == Date then
|
115
|
-
set_type_attribute('date')
|
116
|
-
remove_all_value_attributes_and_content(xmlnode)
|
117
|
-
Tools.set_ns_attribute(xmlnode,'office','date-value', avalue.strftime('%Y-%m-%d'))
|
118
|
-
xmlnode << LibXML::XML::Node.new('p', avalue.strftime('%Y-%m-%d'), ns_text)
|
119
|
-
when gt == 'percentage'
|
120
|
-
set_type_attribute('float')
|
121
|
-
remove_all_value_attributes_and_content(xmlnode)
|
122
|
-
Tools.set_ns_attribute(xmlnode,'office','value', avalue.to_f.to_s)
|
123
|
-
xmlnode << LibXML::XML::Node.new('p', (avalue.to_f*100).round.to_s+'%', ns_text)
|
124
|
-
end
|
125
|
-
else
|
126
|
-
raise "Unknown cell mode #{self.mode}"
|
127
|
-
end
|
158
|
+
def format
|
159
|
+
@format ||= CellFormat.new(self)
|
128
160
|
end
|
129
|
-
def
|
130
|
-
Tools.
|
161
|
+
def address
|
162
|
+
Tools.convert_cell_coordinates_to_address(coordinates)
|
131
163
|
end
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
# proxy object to allow cell.format syntax. Also handles all logic for formats.
|
168
|
+
class CellFormat
|
169
|
+
attr_reader :bold
|
170
|
+
def initialize(cell)
|
171
|
+
@bold = false
|
172
|
+
@cell = cell
|
136
173
|
end
|
137
|
-
def
|
138
|
-
def
|
139
|
-
|
140
|
-
def relative(rowdiff,coldiff)
|
141
|
-
@worksheet.cells(self.rowi+rowdiff, self.coli+coldiff)
|
174
|
+
def cellnode; @cell.xmlnode end
|
175
|
+
def bold=(value)
|
176
|
+
Rspreadsheet::Tools.set_ns_attribute(cellnode,'table','style-name','ce99')
|
142
177
|
end
|
143
|
-
def
|
144
|
-
def
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
178
|
+
def bold; Tools.get_ns_attribute_value(text_style_node,'fo','font-weight') == 'bold' end
|
179
|
+
def italic; Tools.get_ns_attribute_value(text_style_node,'fo','font-style') == 'italic' end
|
180
|
+
def color; Tools.get_ns_attribute_value(text_style_node,'fo','color') end
|
181
|
+
def font_size; Tools.get_ns_attribute_value(text_style_node,'fo','font-size') end
|
182
|
+
def background_color; Tools.get_ns_attribute_value(cell_style_node,'fo','background-color') end
|
183
|
+
|
184
|
+
def unused_cell_style_name
|
185
|
+
last = cellnode.doc.root.find('./office:automatic-styles/style:style').
|
186
|
+
collect {|node| node['name']}.
|
187
|
+
collect{ |name| /^ce(\d*)$/.match(name); $1.andand.to_i}.
|
188
|
+
compact.max
|
189
|
+
"ce#{last+1}"
|
155
190
|
end
|
191
|
+
def style_name; Tools.get_ns_attribute_value(cellnode,'table','style-name') end
|
192
|
+
def style_node; cellnode.doc.root.find("./office:automatic-styles/style:style[@style:name=\"#{style_name}\"]").first end
|
193
|
+
def text_style_node; cellnode.doc.root.find("./office:automatic-styles/style:style[@style:name=\"#{style_name}\"]/style:text-properties").first end
|
194
|
+
def cell_style_node; cellnode.doc.root.find("./office:automatic-styles/style:style[@style:name=\"#{style_name}\"]/style:table-cell-properties").first end
|
156
195
|
end
|
157
|
-
|
158
|
-
|
159
|
-
# class Cell
|
160
|
-
# attr_reader :col, :xmlnode
|
161
|
-
# attr_reader :parent_row # for debug only
|
162
|
-
# attr_accessor :mode
|
163
|
-
# def self.empty_cell_node
|
164
|
-
# LibXML::XML::Node.new('table-cell',nil, Tools.get_namespace('table'))
|
165
|
-
# end
|
166
|
-
# def initialize(aparent_row,coli,axmlnode=nil)
|
167
|
-
# raise "First parameter should be Row object not #{aparent_row.class}" unless aparent_row.kind_of?(Rspreadsheet::Row)
|
168
|
-
# @parent_row = aparent_row
|
169
|
-
# if axmlnode.nil?
|
170
|
-
# axmlnode = Cell.empty_cell_node
|
171
|
-
# end
|
172
|
-
# @xmlnode = axmlnode
|
173
|
-
# @col = coli
|
174
|
-
# # set @mode
|
175
|
-
# @mode = case
|
176
|
-
# when !@parent_row.used_col_range.include?(coli) then :outbound
|
177
|
-
# when Tools.get_ns_attribute_value(@xmlnode, 'table', 'number-columns-repeated').to_i>1 then :repeated
|
178
|
-
# else:regular
|
179
|
-
# end
|
180
|
-
# end
|
181
|
-
# def to_s; value end
|
182
|
-
# def cell_xml; self.xmlnode.to_s end
|
183
|
-
# def xml; self.xmlnode.children.first.andand.inner_xml end
|
184
|
-
# def address; Rspreadsheet::Tools.c2a(row,col) end
|
185
|
-
# def row; @parent_row.row end
|
186
|
-
# def worksheet; @parent_row.worksheet end
|
187
|
-
# # use this to find node in cell xml. ex. xmlfind('.//text:a') finds all link nodes
|
188
|
-
# def xmlfindall(path)
|
189
|
-
# xmlnode.find(path)
|
190
|
-
# end
|
191
|
-
# def xmlfindfirst(path)
|
192
|
-
# xmlfindall(path).first
|
193
|
-
# end
|
194
|
-
# # based on @xmlnode and optionally value which is about to be assigned, guesses which type the result should be
|
195
|
-
# def inspect
|
196
|
-
# "#<Rspreadsheet::Cell:Cell\n row:#{row}, col:#{col} address:#{address}\n type: #{guess_cell_type.to_s}, value:#{value}\n mode: #{mode}\n>"
|
197
|
-
# end
|
198
|
-
# end
|
199
196
|
|
200
197
|
end
|
201
198
|
|
@@ -210,3 +207,8 @@ end
|
|
210
207
|
|
211
208
|
|
212
209
|
|
210
|
+
|
211
|
+
|
212
|
+
|
213
|
+
|
214
|
+
|