openxml-xlsx 0.1.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.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +4 -4
- data/example +4 -3
- data/lib/openxml-xlsx.rb +1 -0
- data/lib/openxml/xlsx.rb +30 -0
- data/lib/{xlsx → openxml/xlsx}/elements.rb +4 -2
- data/lib/openxml/xlsx/elements/alignment.rb +22 -0
- data/lib/openxml/xlsx/elements/border.rb +28 -0
- data/lib/openxml/xlsx/elements/border_component.rb +21 -0
- data/lib/openxml/xlsx/elements/border_style.rb +22 -0
- data/lib/openxml/xlsx/elements/cell.rb +96 -0
- data/lib/openxml/xlsx/elements/defined_name.rb +13 -0
- data/lib/openxml/xlsx/elements/font.rb +22 -0
- data/lib/openxml/xlsx/elements/implied_number_format.rb +7 -0
- data/lib/openxml/xlsx/elements/indexed_color.rb +13 -0
- data/lib/openxml/xlsx/elements/number_format.rb +47 -0
- data/lib/openxml/xlsx/elements/pattern_fill.rb +20 -0
- data/lib/openxml/xlsx/elements/relationship.rb +20 -0
- data/lib/openxml/xlsx/elements/row.rb +37 -0
- data/lib/openxml/xlsx/elements/style.rb +29 -0
- data/lib/openxml/xlsx/elements/table_column.rb +8 -0
- data/lib/openxml/xlsx/elements/theme_color.rb +13 -0
- data/lib/openxml/xlsx/package.rb +52 -0
- data/lib/{xlsx → openxml/xlsx}/parts.rb +4 -2
- data/lib/openxml/xlsx/parts/shared_strings.rb +28 -0
- data/lib/openxml/xlsx/parts/stylesheet.rb +80 -0
- data/lib/openxml/xlsx/parts/table.rb +36 -0
- data/lib/openxml/xlsx/parts/workbook.rb +71 -0
- data/lib/openxml/xlsx/parts/worksheet.rb +90 -0
- data/lib/openxml/xlsx/version.rb +5 -0
- data/{xlsx.gemspec → openxml-xlsx.gemspec} +5 -5
- metadata +37 -36
- data/lib/xlsx.rb +0 -28
- data/lib/xlsx/elements/alignment.rb +0 -20
- data/lib/xlsx/elements/border.rb +0 -26
- data/lib/xlsx/elements/border_component.rb +0 -19
- data/lib/xlsx/elements/border_style.rb +0 -20
- data/lib/xlsx/elements/cell.rb +0 -94
- data/lib/xlsx/elements/defined_name.rb +0 -11
- data/lib/xlsx/elements/font.rb +0 -20
- data/lib/xlsx/elements/implied_number_format.rb +0 -5
- data/lib/xlsx/elements/indexed_color.rb +0 -11
- data/lib/xlsx/elements/number_format.rb +0 -45
- data/lib/xlsx/elements/pattern_fill.rb +0 -18
- data/lib/xlsx/elements/relationship.rb +0 -18
- data/lib/xlsx/elements/row.rb +0 -35
- data/lib/xlsx/elements/style.rb +0 -27
- data/lib/xlsx/elements/table_column.rb +0 -6
- data/lib/xlsx/elements/theme_color.rb +0 -11
- data/lib/xlsx/package.rb +0 -50
- data/lib/xlsx/parts/shared_strings.rb +0 -26
- data/lib/xlsx/parts/stylesheet.rb +0 -78
- data/lib/xlsx/parts/table.rb +0 -34
- data/lib/xlsx/parts/workbook.rb +0 -66
- data/lib/xlsx/parts/worksheet.rb +0 -88
- data/lib/xlsx/version.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f094c3f3d320d437160ecde6d7bfa6658e4cbfb0
|
4
|
+
data.tar.gz: abff7db10f7d3eae869fe36070badb0f3ddb12a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e125f39a4a02221a9610b96dcedc3544ca9aa8285d3b7d04abe5b2196e3c89477d24c5d09ce77eceb210495dc277c9c206a5a601ad888368b2e943cc0a3ce97a
|
7
|
+
data.tar.gz: c1d013edf0c517011f5d4f0b1948ec017a966e92528c3d67e2c7deb544c0717b1dd174fd718428b7cc0e9e70ac7e60cce57d25b103d018607fa1e1bba50fa5a7
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
openxml-xlsx (0.
|
4
|
+
openxml-xlsx (0.2.0)
|
5
5
|
nokogiri
|
6
|
-
|
6
|
+
openxml-package (>= 0.2.0)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
@@ -13,9 +13,9 @@ GEM
|
|
13
13
|
method_source (0.8.1)
|
14
14
|
mini_portile (0.6.2)
|
15
15
|
multi_json (1.7.2)
|
16
|
-
nokogiri (1.6.6.
|
16
|
+
nokogiri (1.6.6.3)
|
17
17
|
mini_portile (~> 0.6.0)
|
18
|
-
|
18
|
+
openxml-package (0.2.0)
|
19
19
|
nokogiri
|
20
20
|
ox
|
21
21
|
rubyzip (~> 1.1.0)
|
data/example
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
require "rails" # workaround: openxml-package uses `extract_options!`
|
3
4
|
$:.push Dir.pwd + "/lib"
|
4
|
-
require "xlsx"
|
5
|
-
package = Xlsx::Package.new
|
5
|
+
require "openxml/xlsx"
|
6
|
+
package = OpenXml::Xlsx::Package.new
|
6
7
|
workbook = package.workbook
|
7
8
|
worksheet = workbook.worksheets[0]
|
8
9
|
|
9
|
-
include Xlsx::Elements
|
10
|
+
include OpenXml::Xlsx::Elements
|
10
11
|
|
11
12
|
workbook.add_defined_names({name: "Alpha", formula:"Sheet1!$A$1"}, {name: "Charlie", formula:"Sheet1!$C$1"})
|
12
13
|
|
data/lib/openxml-xlsx.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "openxml/xlsx"
|
data/lib/openxml/xlsx.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module OpenXml
|
2
|
+
module Xlsx
|
3
|
+
REL_DOCUMENT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument".freeze
|
4
|
+
REL_WORKSHEET = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet".freeze
|
5
|
+
REL_STYLES = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles".freeze
|
6
|
+
REL_SHARED_STRINGS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings".freeze
|
7
|
+
REL_CALC_CHAIN = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/calcChain".freeze
|
8
|
+
REL_THEME = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme".freeze
|
9
|
+
REL_TABLE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table".freeze
|
10
|
+
|
11
|
+
TYPE_WORKBOOK = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml".freeze
|
12
|
+
TYPE_WORKSHEET = "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml".freeze
|
13
|
+
TYPE_THEME = "application/vnd.openxmlformats-officedocument.theme+xml".freeze
|
14
|
+
TYPE_STYLES = "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml".freeze
|
15
|
+
TYPE_SHARED_STRINGS = "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml".freeze
|
16
|
+
TYPE_CALC_CHAIN = "application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml".freeze
|
17
|
+
TYPE_CORE_PROPS = "application/vnd.openxmlformats-package.core-properties+xml".freeze
|
18
|
+
TYPE_APP_PROPS = "application/vnd.openxmlformats-officedocument.extended-properties+xml".freeze
|
19
|
+
TYPE_TABLE = "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml".freeze
|
20
|
+
|
21
|
+
def self.index!(collection, item)
|
22
|
+
collection.index(item) || collection.push(item).length - 1
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
require "openxml/xlsx/elements"
|
29
|
+
require "openxml/xlsx/package"
|
30
|
+
require "openxml/xlsx/parts"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module OpenXml
|
2
|
+
module Xlsx
|
3
|
+
module Elements
|
4
|
+
class Alignment < Struct.new(:horizontal, :vertical, :indent, :wrapText)
|
5
|
+
|
6
|
+
def attributes
|
7
|
+
{}.tap do |attrs|
|
8
|
+
attrs[:horizontal] = horizontal if horizontal
|
9
|
+
attrs[:vertical] = vertical if vertical
|
10
|
+
attrs[:indent] = indent if indent
|
11
|
+
attrs[:wrapText] = wrapText if wrapText
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_xml(xml)
|
16
|
+
xml.alignment(attributes)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module OpenXml
|
2
|
+
module Xlsx
|
3
|
+
module Elements
|
4
|
+
class Border
|
5
|
+
attr_reader :left_component, :right_component, :top_component, :bottom_component, :diagonal_component
|
6
|
+
|
7
|
+
def initialize(options={})
|
8
|
+
@left_component = options.fetch(:left, BorderComponent.new)
|
9
|
+
@right_component = options.fetch(:right, BorderComponent.new)
|
10
|
+
@top_component = options.fetch(:top, BorderComponent.new)
|
11
|
+
@bottom_component = options.fetch(:bottom, BorderComponent.new)
|
12
|
+
@diagonal_component = options.fetch(:diagonal, BorderComponent.new)
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_xml(xml)
|
16
|
+
xml.border do
|
17
|
+
left_component.to_xml("left", xml)
|
18
|
+
right_component.to_xml("right", xml)
|
19
|
+
top_component.to_xml("top", xml)
|
20
|
+
bottom_component.to_xml("bottom", xml)
|
21
|
+
diagonal_component.to_xml("diagonal", xml)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module OpenXml
|
2
|
+
module Xlsx
|
3
|
+
module Elements
|
4
|
+
class BorderComponent < Struct.new(:style, :color)
|
5
|
+
|
6
|
+
def to_xml(name, xml)
|
7
|
+
if style && color
|
8
|
+
xml.public_send(name, style: style) do
|
9
|
+
color.to_xml("color", xml)
|
10
|
+
end
|
11
|
+
elsif style
|
12
|
+
xml.public_send(name, style: style)
|
13
|
+
else
|
14
|
+
xml.public_send(name)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module OpenXml
|
2
|
+
module Xlsx
|
3
|
+
module Elements
|
4
|
+
class BorderStyle
|
5
|
+
NONE = "none".freeze
|
6
|
+
THIN = "thin".freeze
|
7
|
+
MEDIUM = "medium".freeze
|
8
|
+
DASHED = "dashed".freeze
|
9
|
+
DOTTED = "dotted".freeze
|
10
|
+
THICK = "thick".freeze
|
11
|
+
DOUBLE = "double".freeze
|
12
|
+
HAIR = "hair".freeze
|
13
|
+
MEDIUM_DASHED = "mediumDashed".freeze
|
14
|
+
DASH_DOT = "dashDot".freeze
|
15
|
+
MEDIUM_DASH_DOT = "mediumDashDot".freeze
|
16
|
+
DASH_DOT_DOT = "dashDotDot".freeze
|
17
|
+
MEDIUM_DASH_DOT_DOT = "mediumDashDotDot".freeze
|
18
|
+
SLANT_DASH_DOT = "slantDashDot".freeze
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require "date"
|
2
|
+
|
3
|
+
module OpenXml
|
4
|
+
module Xlsx
|
5
|
+
module Elements
|
6
|
+
class Cell
|
7
|
+
attr_reader :row, :column, :value, :type, :style, :formula
|
8
|
+
|
9
|
+
def initialize(row, options={})
|
10
|
+
@row = row
|
11
|
+
@column = options.fetch(:column)
|
12
|
+
@value = options[:value]
|
13
|
+
case value
|
14
|
+
when String
|
15
|
+
@type = :string
|
16
|
+
@string_id = package.string_ref(value)
|
17
|
+
when Date then
|
18
|
+
@type = :date
|
19
|
+
@serial_date = to_serial_date(value)
|
20
|
+
when Time then
|
21
|
+
@type = :time
|
22
|
+
@serial_time = to_serial_time(value)
|
23
|
+
else
|
24
|
+
@type = :general
|
25
|
+
end
|
26
|
+
@style = package.style_ref(options[:style]) if options.key? :style
|
27
|
+
@formula = options[:formula]
|
28
|
+
end
|
29
|
+
|
30
|
+
def id
|
31
|
+
"#{column_letter}#{row.number}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def column_letter
|
35
|
+
bytes = []
|
36
|
+
remaining = column
|
37
|
+
while remaining > 0
|
38
|
+
bytes.unshift (remaining - 1) % 26 + 65
|
39
|
+
remaining = (remaining - 1) / 26
|
40
|
+
end
|
41
|
+
bytes.pack "c*"
|
42
|
+
end
|
43
|
+
|
44
|
+
def worksheet
|
45
|
+
row.worksheet
|
46
|
+
end
|
47
|
+
|
48
|
+
def workbook
|
49
|
+
worksheet.workbook
|
50
|
+
end
|
51
|
+
|
52
|
+
def package
|
53
|
+
workbook.package
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_xml(xml)
|
57
|
+
attributes = {"r" => id}
|
58
|
+
attributes.merge!("s" => style) if style
|
59
|
+
attributes.merge!("t" => "s") if type == :string
|
60
|
+
|
61
|
+
value = self.value
|
62
|
+
value = string_id if type == :string
|
63
|
+
value = serial_date if type == :date
|
64
|
+
value = serial_time if type == :time
|
65
|
+
|
66
|
+
xml.c(attributes) do
|
67
|
+
xml.f formula if formula
|
68
|
+
xml.v value if value
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
attr_reader :string_id, :serial_date, :serial_time
|
74
|
+
|
75
|
+
EXCEL_ANCHOR_DATE = Date.new(1900, 1, 1).freeze
|
76
|
+
SECONDS_PER_DAY = 86400.freeze
|
77
|
+
|
78
|
+
def to_serial_date(date)
|
79
|
+
# Excel stores dates as the number of days since 1900-Jan-0
|
80
|
+
# Excel behaves as if 1900 was a leap year, so the number is
|
81
|
+
# generally 1 greater than you would expect.
|
82
|
+
# http://www.cpearson.com/excel/datetime.htm
|
83
|
+
(date - EXCEL_ANCHOR_DATE).to_i + 2
|
84
|
+
end
|
85
|
+
|
86
|
+
def to_serial_time(time)
|
87
|
+
date = to_serial_date(time.to_date)
|
88
|
+
|
89
|
+
seconds_since_midnight = time.hour * 3600 + time.min * 60 + time.sec
|
90
|
+
date + (seconds_since_midnight.to_f / SECONDS_PER_DAY)
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module OpenXml
|
2
|
+
module Xlsx
|
3
|
+
module Elements
|
4
|
+
class Font < Struct.new(:name, :size, :styles)
|
5
|
+
|
6
|
+
def to_xml(xml)
|
7
|
+
xml.font do
|
8
|
+
xml.sz val: size
|
9
|
+
xml.name val: name
|
10
|
+
if styles
|
11
|
+
xml.b if styles[:bold]
|
12
|
+
xml.i if styles[:italic]
|
13
|
+
xml.u if styles[:underline]
|
14
|
+
styles[:color].to_xml("color", xml) if styles[:color]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "openxml/xlsx/elements/implied_number_format"
|
2
|
+
|
3
|
+
module OpenXml
|
4
|
+
module Xlsx
|
5
|
+
module Elements
|
6
|
+
class NumberFormat < Struct.new(:format)
|
7
|
+
INTEGER = ImpliedNumberFormat.new(1).freeze # 0
|
8
|
+
DECIMAL = ImpliedNumberFormat.new(2).freeze # 0.00
|
9
|
+
INTEGER_THOUSANDS = ImpliedNumberFormat.new(3).freeze # #,##0
|
10
|
+
DECIMAL_THOUSANDS = ImpliedNumberFormat.new(4).freeze # #,##0.00
|
11
|
+
|
12
|
+
INTEGER_PERCENT = ImpliedNumberFormat.new(9).freeze # 0%
|
13
|
+
DECIMAL_PERCENT = ImpliedNumberFormat.new(10).freeze # 0.00%
|
14
|
+
SCIENTIFIC = ImpliedNumberFormat.new(11).freeze # 0.00E+00
|
15
|
+
FRACTION = ImpliedNumberFormat.new(12).freeze # ?/?
|
16
|
+
FRACTION2 = ImpliedNumberFormat.new(13).freeze # ??/??
|
17
|
+
DATE = ImpliedNumberFormat.new(14).freeze # mm-dd-yy
|
18
|
+
DATE_ALT = ImpliedNumberFormat.new(15).freeze # d-mmm-yy
|
19
|
+
DAY_MONTH = ImpliedNumberFormat.new(16).freeze # d-mmm
|
20
|
+
MONTH_YEAR = ImpliedNumberFormat.new(17).freeze # mmm-yy
|
21
|
+
TIME = ImpliedNumberFormat.new(18).freeze # h:mm AM/PM
|
22
|
+
TIME_SECONDS = ImpliedNumberFormat.new(19).freeze # h:mm:ss AM/PM
|
23
|
+
TIME_ALT = ImpliedNumberFormat.new(20).freeze # h:mm
|
24
|
+
TIME_SECONDS_ALT = ImpliedNumberFormat.new(21).freeze # h:mm:ss
|
25
|
+
DATETIME = ImpliedNumberFormat.new(22).freeze # m/d/yy h:mm
|
26
|
+
|
27
|
+
FINANCIAL_INTEGER = ImpliedNumberFormat.new(37).freeze # #,##0 ;(#,##0)
|
28
|
+
FINANCIAL_INTEGER_RED = ImpliedNumberFormat.new(38).freeze # #,##0 ;[Red](#,##0)
|
29
|
+
FINANCIAL_DECIMAL = ImpliedNumberFormat.new(39).freeze # #,##0.00 ;(#,##0.00)
|
30
|
+
FINANCIAL_DECIMAL_RED = ImpliedNumberFormat.new(40).freeze # #,##0.00 ;[Red](#,##0.00)
|
31
|
+
|
32
|
+
INTERVAL = ImpliedNumberFormat.new(45).freeze # mm:ss
|
33
|
+
INTERVAL_HOURS = ImpliedNumberFormat.new(46).freeze # [h]:mm:ss
|
34
|
+
TIMESTAMP = ImpliedNumberFormat.new(47).freeze # mmss.0
|
35
|
+
# SCIENTIFIC_ALT = ImpliedNumberFormat.new(48).freeze # ##0.0E+0
|
36
|
+
# UNKONWN = ImpliedNumberFormat.new(49).freeze # @
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
def to_xml(id, xml)
|
41
|
+
xml.numFmt(numFmtId: id, formatCode: format)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module OpenXml
|
2
|
+
module Xlsx
|
3
|
+
module Elements
|
4
|
+
class PatternFill < Struct.new(:type, :foreground_color, :background_color)
|
5
|
+
|
6
|
+
def to_xml(xml)
|
7
|
+
xml.fill do
|
8
|
+
xml.patternFill(patternType: type) do
|
9
|
+
if type.to_s == "solid"
|
10
|
+
foreground_color.to_xml("fgColor", xml)
|
11
|
+
background_color.to_xml("bgColor", xml)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "securerandom"
|
2
|
+
|
3
|
+
module OpenXml
|
4
|
+
module Xlsx
|
5
|
+
module Elements
|
6
|
+
class Relationship < Struct.new(:type, :target, :id)
|
7
|
+
|
8
|
+
def initialize(type, target, id=nil)
|
9
|
+
id ||= "R#{SecureRandom.hex}"
|
10
|
+
super type, target, id
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_xml(xml)
|
14
|
+
xml.Relationship("Id" => id, "Type" => type, "Target" => target)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|