openxml-xlsx 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,18 +0,0 @@
|
|
1
|
-
module Xlsx
|
2
|
-
module Elements
|
3
|
-
class PatternFill < Struct.new(:type, :foreground_color, :background_color)
|
4
|
-
|
5
|
-
def to_xml(xml)
|
6
|
-
xml.fill do
|
7
|
-
xml.patternFill(patternType: type) do
|
8
|
-
if type.to_s == "solid"
|
9
|
-
foreground_color.to_xml("fgColor", xml)
|
10
|
-
background_color.to_xml("bgColor", xml)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require "securerandom"
|
2
|
-
|
3
|
-
module Xlsx
|
4
|
-
module Elements
|
5
|
-
class Relationship < Struct.new(:type, :target, :id)
|
6
|
-
|
7
|
-
def initialize(type, target, id=nil)
|
8
|
-
id ||= "R#{SecureRandom.hex}"
|
9
|
-
super type, target, id
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_xml(xml)
|
13
|
-
xml.Relationship("Id" => id, "Type" => type, "Target" => target)
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
data/lib/xlsx/elements/row.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
module Xlsx
|
2
|
-
module Elements
|
3
|
-
class Row
|
4
|
-
attr_reader :worksheet, :number, :height, :hidden, :cells
|
5
|
-
|
6
|
-
def initialize(worksheet, options={})
|
7
|
-
@worksheet = worksheet
|
8
|
-
@number = options.fetch(:number)
|
9
|
-
@height = options[:height]
|
10
|
-
@hidden = options[:hidden]
|
11
|
-
@cells = []
|
12
|
-
|
13
|
-
Array(options[:cells]).each do |attributes|
|
14
|
-
add_cell attributes
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def add_cell(attributes)
|
19
|
-
cells.push Xlsx::Elements::Cell.new(self, attributes)
|
20
|
-
end
|
21
|
-
|
22
|
-
def to_xml(xml)
|
23
|
-
attributes = {"r" => number}
|
24
|
-
attributes.merge!("ht" => height, "customHeight" => 1) if height
|
25
|
-
attributes.merge!("hidden" => 1) if hidden
|
26
|
-
xml.row(attributes) do
|
27
|
-
cells.each do |cell|
|
28
|
-
cell.to_xml(xml)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
data/lib/xlsx/elements/style.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
module Xlsx
|
2
|
-
module Elements
|
3
|
-
class Style < Struct.new(:format_id, :font_id, :fill_id, :border_id, :alignment)
|
4
|
-
|
5
|
-
def initialize(format_id=0, font_id=0, fill_id=0, border_id=0, alignment=nil)
|
6
|
-
super format_id || 0, font_id || 0, fill_id || 0, border_id || 0, alignment
|
7
|
-
end
|
8
|
-
|
9
|
-
def to_xml(xml)
|
10
|
-
attributes = {
|
11
|
-
numFmtId: format_id,
|
12
|
-
fontId: font_id,
|
13
|
-
fillId: fill_id,
|
14
|
-
borderId: border_id }
|
15
|
-
attributes.merge!(applyNumberFormat: 1) if format_id > 0
|
16
|
-
attributes.merge!(applyFont: 1) if font_id > 0
|
17
|
-
attributes.merge!(applyFill: 1) if fill_id > 0
|
18
|
-
attributes.merge!(applyBorder: 1) if border_id > 0
|
19
|
-
attributes.merge!(applyAlignment: 1) if alignment
|
20
|
-
xml.xf(attributes) do
|
21
|
-
alignment.to_xml(xml) if alignment
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
data/lib/xlsx/package.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
require "open_xml/package"
|
2
|
-
|
3
|
-
module Xlsx
|
4
|
-
class Package < OpenXml::Package
|
5
|
-
attr_reader :xl_rels,
|
6
|
-
:shared_strings,
|
7
|
-
:stylesheet,
|
8
|
-
:workbook
|
9
|
-
|
10
|
-
|
11
|
-
content_types do
|
12
|
-
override "/xl/workbook.xml", TYPE_WORKBOOK
|
13
|
-
override "/xl/worksheets/sheet1.xml", TYPE_WORKSHEET
|
14
|
-
override "/xl/sharedStrings.xml", TYPE_SHARED_STRINGS
|
15
|
-
override "/xl/styles.xml", TYPE_STYLES
|
16
|
-
end
|
17
|
-
|
18
|
-
|
19
|
-
def initialize
|
20
|
-
super
|
21
|
-
rels.add_relationship REL_DOCUMENT, "xl/workbook.xml"
|
22
|
-
|
23
|
-
@xl_rels = OpenXml::Parts::Rels.new([
|
24
|
-
{ "Type" => REL_SHARED_STRINGS, "Target" => "sharedStrings.xml" },
|
25
|
-
{ "Type" => REL_STYLES, "Target" => "styles.xml" }
|
26
|
-
])
|
27
|
-
@shared_strings = Xlsx::Parts::SharedStrings.new
|
28
|
-
@stylesheet = Xlsx::Parts::Stylesheet.new
|
29
|
-
@workbook = Xlsx::Parts::Workbook.new(self)
|
30
|
-
|
31
|
-
# docProps/app.xml
|
32
|
-
# docProps/core.xml
|
33
|
-
add_part "xl/_rels/workbook.xml.rels", xl_rels
|
34
|
-
# xl/calcChain.xml
|
35
|
-
add_part "xl/sharedStrings.xml", shared_strings
|
36
|
-
add_part "xl/styles.xml", stylesheet
|
37
|
-
# xl/theme/theme1.xml
|
38
|
-
add_part "xl/workbook.xml", workbook
|
39
|
-
end
|
40
|
-
|
41
|
-
def string_ref(string)
|
42
|
-
shared_strings.reference_of(string)
|
43
|
-
end
|
44
|
-
|
45
|
-
def style_ref(style)
|
46
|
-
stylesheet.reference_of(style)
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
50
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module Xlsx
|
2
|
-
module Parts
|
3
|
-
class SharedStrings < OpenXml::Part
|
4
|
-
attr_reader :strings
|
5
|
-
|
6
|
-
def initialize
|
7
|
-
@strings = Hash.new { |hash, key| hash[key] = hash.length }
|
8
|
-
end
|
9
|
-
|
10
|
-
def reference_of(string)
|
11
|
-
strings[string]
|
12
|
-
end
|
13
|
-
|
14
|
-
def to_xml
|
15
|
-
build_standalone_xml do |xml|
|
16
|
-
xml.sst(xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main", uniqueCount: strings.length) do
|
17
|
-
strings.each do |string, i|
|
18
|
-
xml.si { xml.t(string) }
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
module Xlsx
|
2
|
-
module Parts
|
3
|
-
class Stylesheet < OpenXml::Part
|
4
|
-
include Xlsx::Elements
|
5
|
-
|
6
|
-
attr_reader :formats, :fonts, :fills, :borders, :styles
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@formats = []
|
10
|
-
@fonts = [Font.new("Calibri", 12)]
|
11
|
-
@fills = [PatternFill.new("none"), PatternFill.new("gray125")]
|
12
|
-
@borders = [Border.new]
|
13
|
-
@styles = [Style.new]
|
14
|
-
end
|
15
|
-
|
16
|
-
def reference_of(options={})
|
17
|
-
case format = options[:format]
|
18
|
-
when NumberFormat
|
19
|
-
options[:format_id] = Xlsx.index!(formats, format) + NUMBER_FORMAT_START_ID
|
20
|
-
when ImpliedNumberFormat
|
21
|
-
options[:format_id] = format.id
|
22
|
-
end
|
23
|
-
options[:font_id] = Xlsx.index!(fonts, options[:font]) if options.key? :font
|
24
|
-
options[:fill_id] = Xlsx.index!(fills, options[:fill]) if options.key? :fill
|
25
|
-
options[:border_id] = Xlsx.index!(borders, options[:border]) if options.key? :border
|
26
|
-
|
27
|
-
style = Style.new(
|
28
|
-
options.fetch(:format_id, 0),
|
29
|
-
options.fetch(:font_id, 0),
|
30
|
-
options.fetch(:fill_id, 0),
|
31
|
-
options.fetch(:border_id, 0),
|
32
|
-
options.fetch(:alignment, nil))
|
33
|
-
|
34
|
-
Xlsx.index!(styles, style)
|
35
|
-
end
|
36
|
-
|
37
|
-
def to_xml
|
38
|
-
build_standalone_xml do |xml|
|
39
|
-
xml.styleSheet(xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main", "xmlns:mc" => "http://schemas.openxmlformats.org/markup-compatibility/2006") do
|
40
|
-
xml.numFmts(count: formats.length) do
|
41
|
-
formats.each_with_index do |format, index|
|
42
|
-
format.to_xml(index + NUMBER_FORMAT_START_ID, xml)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
xml.fonts(count: fonts.length) do
|
47
|
-
fonts.each do |font|
|
48
|
-
font.to_xml(xml)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
xml.fills(count: fills.length) do
|
53
|
-
fills.each do |fill|
|
54
|
-
fill.to_xml(xml)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
xml.borders(count: borders.length) do
|
59
|
-
borders.each do |border|
|
60
|
-
border.to_xml(xml)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
xml.cellXfs(count: styles.length) do
|
65
|
-
styles.each do |style|
|
66
|
-
style.to_xml(xml)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
private
|
74
|
-
NUMBER_FORMAT_START_ID = 165.freeze
|
75
|
-
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
data/lib/xlsx/parts/table.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
module Xlsx
|
2
|
-
module Parts
|
3
|
-
class Table < OpenXml::Part
|
4
|
-
attr_reader :id, :name, :ref, :columns
|
5
|
-
|
6
|
-
def initialize(id, name, ref, columns)
|
7
|
-
@id = id
|
8
|
-
@name = name
|
9
|
-
@ref = ref
|
10
|
-
@columns = columns
|
11
|
-
end
|
12
|
-
|
13
|
-
def filename
|
14
|
-
"table#{id}.xml"
|
15
|
-
end
|
16
|
-
|
17
|
-
def to_xml
|
18
|
-
build_standalone_xml do |xml|
|
19
|
-
xml.table(xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
|
20
|
-
id: id, name: name, displayName: name, ref: ref, totalsRowShown: 0) do
|
21
|
-
xml.autoFilter ref: ref
|
22
|
-
xml.tableColumns(count: columns.length) do
|
23
|
-
columns.each_with_index do |column, index|
|
24
|
-
xml.tableColumn(id: index + 1, name: column.name)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
xml.tableStyleInfo(name: "TableStyleLight6", showFirstColumn: 0, showLastColumn: 0, showRowStripes: 1, showColumnStripes: 0)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
data/lib/xlsx/parts/workbook.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
module Xlsx
|
2
|
-
module Parts
|
3
|
-
class Workbook < OpenXml::Part
|
4
|
-
attr_reader :package, :worksheets, :tables, :defined_names
|
5
|
-
|
6
|
-
def initialize(package)
|
7
|
-
@package = package
|
8
|
-
@worksheets = []
|
9
|
-
@tables = []
|
10
|
-
@defined_names =[]
|
11
|
-
add_worksheet
|
12
|
-
end
|
13
|
-
|
14
|
-
def add_worksheet
|
15
|
-
worksheet = Worksheet.new(self, worksheets.length + 1)
|
16
|
-
package.xl_rels.add_relationship(
|
17
|
-
REL_WORKSHEET,
|
18
|
-
"worksheets/sheet#{worksheet.index}.xml",
|
19
|
-
"rId#{worksheet.index}")
|
20
|
-
package.add_part "xl/worksheets/_rels/sheet#{worksheet.index}.xml.rels", worksheet.rels
|
21
|
-
package.add_part "xl/worksheets/sheet#{worksheet.index}.xml", worksheet
|
22
|
-
worksheets.push worksheet
|
23
|
-
end
|
24
|
-
|
25
|
-
def add_table(table)
|
26
|
-
package.content_types.add_override "/xl/tables/#{table.filename}", TYPE_TABLE
|
27
|
-
package.add_part "xl/tables/#{table.filename}", table
|
28
|
-
tables.push table
|
29
|
-
end
|
30
|
-
|
31
|
-
def add_defined_names(*defined_names)
|
32
|
-
defined_names.flatten.each do |attributes|
|
33
|
-
add_defined_name attributes
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def add_defined_name(attributes)
|
38
|
-
defined_names.push Xlsx::Elements::DefinedName.new(attributes[:name], attributes[:formula])
|
39
|
-
end
|
40
|
-
|
41
|
-
def to_xml
|
42
|
-
build_standalone_xml do |xml|
|
43
|
-
xml.workbook(root_namespaces) {
|
44
|
-
xml.sheets { worksheets.each { |worksheet|
|
45
|
-
xml.sheet(
|
46
|
-
"name" => worksheet.name,
|
47
|
-
"sheetId" => worksheet.index,
|
48
|
-
"r:id" => "rId#{worksheet.index}")
|
49
|
-
} }
|
50
|
-
xml.definedNames do
|
51
|
-
defined_names.each { |defined_name| defined_name.to_xml(xml) }
|
52
|
-
end if defined_names.any?
|
53
|
-
}
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
def root_namespaces
|
60
|
-
{ "xmlns" => "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
|
61
|
-
"xmlns:r" => 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' }
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
data/lib/xlsx/parts/worksheet.rb
DELETED
@@ -1,88 +0,0 @@
|
|
1
|
-
module Xlsx
|
2
|
-
module Parts
|
3
|
-
class Worksheet < OpenXml::Part
|
4
|
-
attr_reader :workbook, :index, :rows, :tables, :rels, :cell_ranges
|
5
|
-
|
6
|
-
def initialize(workbook, index)
|
7
|
-
@workbook = workbook
|
8
|
-
@index = index
|
9
|
-
@rows = []
|
10
|
-
@tables = []
|
11
|
-
@cell_ranges = []
|
12
|
-
@rels = OpenXml::Parts::Rels.new
|
13
|
-
@column_widths = {}
|
14
|
-
end
|
15
|
-
|
16
|
-
def column_widths(*args)
|
17
|
-
return @column_widths if args.none?
|
18
|
-
@column_widths = args.first
|
19
|
-
end
|
20
|
-
|
21
|
-
def add_rows(*rows)
|
22
|
-
rows.flatten.each do |attributes|
|
23
|
-
add_row attributes
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def add_row(attributes)
|
28
|
-
rows.push Xlsx::Elements::Row.new(self, attributes)
|
29
|
-
end
|
30
|
-
|
31
|
-
def merge_cells(*ranges)
|
32
|
-
ranges.each { |range| cell_ranges.push range }
|
33
|
-
end
|
34
|
-
|
35
|
-
def add_table(id, name, ref, columns)
|
36
|
-
table = Xlsx::Parts::Table.new(id, name, ref, columns)
|
37
|
-
rels.add_relationship(REL_TABLE, "../tables/#{table.filename}")
|
38
|
-
workbook.add_table table
|
39
|
-
end
|
40
|
-
|
41
|
-
def to_xml
|
42
|
-
build_standalone_xml do |xml|
|
43
|
-
xml.worksheet(root_namespaces) do
|
44
|
-
xml.sheetViews do
|
45
|
-
xml.sheetView(showGridLines: 0, tabSelected: 1, workbookViewId: 0)
|
46
|
-
end
|
47
|
-
xml.sheetFormatPr(baseColWidth: 10, defaultColWidth: 13.33203125, defaultRowHeight: 20, customHeight: 1)
|
48
|
-
xml.cols do
|
49
|
-
column_widths.each do |column, width|
|
50
|
-
xml.col(min: column, max: column, width: width, customWidth: 1)
|
51
|
-
end
|
52
|
-
end if column_widths.any?
|
53
|
-
xml.sheetData do
|
54
|
-
rows.each { |row| row.to_xml(xml) }
|
55
|
-
end
|
56
|
-
xml.mergeCells(count: merge_cells.size) do
|
57
|
-
cell_ranges.each { |range| xml.mergeCell ref: range }
|
58
|
-
end if cell_ranges.any?
|
59
|
-
xml.pageMargins(left: 0.75, right: 0.75, top: 1, bottom: 1, header: 0.5, footer: 0.5)
|
60
|
-
xml.pageSetup(orientation: "portrait", horizontalDpi: 4294967292, verticalDpi: 4294967292)
|
61
|
-
xml.tableParts(count: tables.count) do
|
62
|
-
tables.each do |rel|
|
63
|
-
xml.tablePart("r:id" => rel.id)
|
64
|
-
end
|
65
|
-
end if tables.any?
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def name
|
71
|
-
"Sheet#{index}"
|
72
|
-
end
|
73
|
-
|
74
|
-
private
|
75
|
-
|
76
|
-
def root_namespaces
|
77
|
-
{ "xmlns" => "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
|
78
|
-
"xmlns:r" => "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
|
79
|
-
"xmlns:mc" => "http://schemas.openxmlformats.org/markup-compatibility/2006" }
|
80
|
-
end
|
81
|
-
|
82
|
-
def tables
|
83
|
-
rels.select { |rel| rel.type == REL_TABLE }
|
84
|
-
end
|
85
|
-
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|