goldendocx 0.2.2 → 0.3.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/.rubocop.yml +1 -1
- data/.ruby-version +1 -0
- data/CHANGELOG.md +8 -2
- data/Gemfile.lock +3 -1
- data/README.md +10 -2
- data/Rakefile +14 -3
- data/demo/tables/create_embed_image_table.rb +3 -3
- data/demo/templates/generate_codes.rb +10 -0
- data/demo/templates/xml_to_class.rb +97 -0
- data/demo/texts/append_plain_text.rb +1 -1
- data/demo/texts/append_styled_text.rb +1 -2
- data/demo/texts/create_text.rb +14 -0
- data/lib/extensions/active_support_extensions.rb +16 -0
- data/lib/extensions/nokogiri_extensions.rb +41 -0
- data/lib/extensions/ox_extensions.rb +35 -0
- data/lib/extensions/xml_serialize_extensions.rb +45 -0
- data/lib/goldendocx/charts/properties.rb +1 -1
- data/lib/goldendocx/charts/series.rb +2 -2
- data/lib/goldendocx/charts.rb +1 -1
- data/lib/goldendocx/components/bar_chart.rb +2 -2
- data/lib/goldendocx/components/chart.rb +6 -6
- data/lib/goldendocx/components/column_chart.rb +2 -2
- data/lib/goldendocx/components/doughnut_chart.rb +2 -2
- data/lib/goldendocx/components/line_chart.rb +2 -2
- data/lib/goldendocx/components/properties/font_property.rb +19 -0
- data/lib/goldendocx/components/properties/language_property.rb +18 -0
- data/lib/goldendocx/components/properties/run_property.rb +2 -0
- data/lib/goldendocx/components/properties.rb +1 -1
- data/lib/goldendocx/components/table.rb +2 -2
- data/lib/goldendocx/components.rb +1 -1
- data/lib/goldendocx/content_types/default.rb +2 -6
- data/lib/goldendocx/content_types/override.rb +2 -6
- data/lib/goldendocx/document.rb +9 -28
- data/lib/goldendocx/documents/body.rb +23 -14
- data/lib/goldendocx/documents/document.rb +2 -4
- data/lib/goldendocx/documents/latent_styles.rb +12 -0
- data/lib/goldendocx/documents/properties/default_style_property.rb +17 -0
- data/lib/goldendocx/documents/properties/page_margin_property.rb +37 -0
- data/lib/goldendocx/documents/properties/page_size_property.rb +17 -0
- data/lib/goldendocx/documents/properties/paragraph_default_style_property.rb +16 -0
- data/lib/goldendocx/documents/properties/run_default_style_property.rb +22 -0
- data/lib/goldendocx/documents/properties/section_property.rb +17 -0
- data/lib/goldendocx/documents/properties/style_name_property.rb +16 -0
- data/lib/goldendocx/documents/properties.rb +12 -0
- data/lib/goldendocx/documents/settings.rb +23 -0
- data/lib/goldendocx/documents/style.rb +10 -10
- data/lib/goldendocx/documents/styles.rb +9 -33
- data/lib/goldendocx/documents.rb +1 -1
- data/lib/goldendocx/docx.rb +55 -12
- data/lib/goldendocx/element.rb +33 -140
- data/lib/goldendocx/has_associations.rb +54 -0
- data/lib/goldendocx/has_attributes.rb +67 -0
- data/lib/goldendocx/has_children.rb +116 -0
- data/lib/goldendocx/images/picture.rb +1 -1
- data/lib/goldendocx/images/properties.rb +1 -1
- data/lib/goldendocx/images.rb +1 -1
- data/lib/goldendocx/{documents → models}/relationship.rb +1 -1
- data/lib/goldendocx/models/relationships.rb +31 -0
- data/lib/goldendocx/models.rb +10 -0
- data/lib/goldendocx/parts/app.rb +46 -0
- data/lib/goldendocx/parts/content_types.rb +16 -30
- data/lib/goldendocx/parts/core.rb +46 -0
- data/lib/goldendocx/parts/documents.rb +27 -14
- data/lib/goldendocx/parts/media.rb +1 -1
- data/lib/goldendocx/parts/properties/created_at_property.rb +17 -0
- data/lib/goldendocx/parts/properties/creator_property.rb +16 -0
- data/lib/goldendocx/parts/properties/revision_property.rb +16 -0
- data/lib/goldendocx/parts/properties/updated_at_property.rb +17 -0
- data/lib/goldendocx/parts/properties/updater_property.rb +16 -0
- data/lib/goldendocx/parts/properties.rb +12 -0
- data/lib/goldendocx/parts.rb +1 -1
- data/lib/goldendocx/tables/header_cell.rb +1 -1
- data/lib/goldendocx/tables/properties.rb +1 -1
- data/lib/goldendocx/tables/row.rb +1 -1
- data/lib/goldendocx/tables.rb +1 -1
- data/lib/goldendocx/version.rb +1 -1
- data/lib/goldendocx/xml_serializers/nokogiri.rb +32 -24
- data/lib/goldendocx/xml_serializers/ox.rb +15 -25
- data/lib/goldendocx.rb +14 -2
- metadata +54 -9
- data/lib/goldendocx/documents/element.rb +0 -23
- data/lib/goldendocx/documents/relationships.rb +0 -39
- data/lib/goldendocx/documents/unparsed_style.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc5f8d130528f4e1f5e5738146ab61e9cc771968d549ec251d1996aa7704c1e8
|
4
|
+
data.tar.gz: 37981979a35e94d81c5515783f28752ebcf0425a635d2d610afdab1b05b4c897
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1e8b756aa8960aa6796a23539498bb9632c68cc8f2c7e18bd02cc5546926afc61347302e8251eeb5e676075dfc97f2bc7c5126d626aec7b6b7f48400aa7f4b1
|
7
|
+
data.tar.gz: 7e4b16e552fbac46c52880c39267472d07481a5a895a9e98d892b508d51a040de7e0bd32bac05ad26c29cb722cd7829df0321b02f47ad14c53e977a758802bac
|
data/.rubocop.yml
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.2.0
|
data/CHANGELOG.md
CHANGED
@@ -30,7 +30,7 @@ Mostly refactoring
|
|
30
30
|
- Introduce `ActiveSupport` to make coding easier
|
31
31
|
- Clean irrelevant demos
|
32
32
|
|
33
|
-
## [0.2.2] - 2023-03-31
|
33
|
+
## [0.2.2] - 2023-03-31
|
34
34
|
|
35
35
|
### Features
|
36
36
|
|
@@ -40,4 +40,10 @@ Mostly refactoring
|
|
40
40
|
### Fixes
|
41
41
|
|
42
42
|
- Fix create charts issues
|
43
|
-
- Fix Nokogiri XML serializer compatible issues
|
43
|
+
- Fix Nokogiri XML serializer compatible issues
|
44
|
+
|
45
|
+
## [0.2.3] - 2023-04-07
|
46
|
+
|
47
|
+
### Features
|
48
|
+
|
49
|
+
- Support create new MS Word docx file without template
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
goldendocx (0.
|
4
|
+
goldendocx (0.3.0)
|
5
5
|
activesupport (~> 7.0)
|
6
6
|
nokogiri (~> 1.14)
|
7
7
|
ox (~> 2.14)
|
@@ -78,6 +78,7 @@ GEM
|
|
78
78
|
simplecov-html (0.12.3)
|
79
79
|
simplecov-lcov (0.8.0)
|
80
80
|
simplecov_json_formatter (0.1.4)
|
81
|
+
timecop (0.9.6)
|
81
82
|
tzinfo (2.0.6)
|
82
83
|
concurrent-ruby (~> 1.0)
|
83
84
|
unicode-display_width (2.2.0)
|
@@ -96,6 +97,7 @@ DEPENDENCIES
|
|
96
97
|
rubocop-rspec (~> 2.19)
|
97
98
|
simplecov (~> 0.22.0)
|
98
99
|
simplecov-lcov (~> 0.8.0)
|
100
|
+
timecop (~> 0.9.6)
|
99
101
|
|
100
102
|
BUNDLED WITH
|
101
103
|
2.3.23
|
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# The Ruby API for Microsoft Word
|
2
2
|
|
3
|
+
[](https://badge.fury.io/rb/goldendocx)
|
4
|
+
[](https://coveralls.io/github/SheldonLeo/goldendocx)
|
5
|
+
|
3
6
|
Ruby APIs for manipulating Microsoft Word based upon OOXML standards.
|
4
7
|
|
5
8
|
## Installation
|
@@ -23,6 +26,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
23
26
|
Support both `ox` and `nokogiri` as XML serializer, and `ox` as default.
|
24
27
|
|
25
28
|
You can customize with configuration
|
29
|
+
|
26
30
|
```ruby
|
27
31
|
Goldendocx.configure do |config|
|
28
32
|
config.xml_serializer = :nokogiri
|
@@ -30,9 +34,13 @@ end
|
|
30
34
|
```
|
31
35
|
|
32
36
|
### Compose MS Word
|
33
|
-
|
37
|
+
|
38
|
+
- Create new MS Word file or read exists file and write to another path
|
34
39
|
```ruby
|
40
|
+
docx = Goldendocx::Docx.new
|
35
41
|
docx = Goldendocx::Docx.new(docx_file_path)
|
42
|
+
docx.read_from(docx_file_path)
|
43
|
+
|
36
44
|
docx.write_to(new_file_path)
|
37
45
|
```
|
38
46
|
- Create texts to MS Word
|
@@ -71,6 +79,6 @@ end
|
|
71
79
|
values = [13, 12, 9, 9, 8, 7, 7, 6, 5, 3]
|
72
80
|
chart.add_series('地域分布详情数据', categories, values)
|
73
81
|
```
|
74
|
-
|
82
|
+
|
75
83
|
More demos view at [Demos](demo/)
|
76
84
|
|
data/Rakefile
CHANGED
@@ -4,7 +4,18 @@ require 'bundler/gem_tasks'
|
|
4
4
|
require 'rspec/core/rake_task'
|
5
5
|
require 'rubocop/rake_task'
|
6
6
|
|
7
|
-
RSpec::Core::RakeTask.new(:
|
8
|
-
|
7
|
+
RSpec::Core::RakeTask.new(:ox_compatible_spec) do |task|
|
8
|
+
ENV['XML_SERIALIZER'] = 'ox'
|
9
|
+
task.failure_message = 'Failed with ox xml serializer compatible'
|
10
|
+
end
|
9
11
|
|
10
|
-
|
12
|
+
RSpec::Core::RakeTask.new(:nokogiri_compatible_spec) do |task|
|
13
|
+
ENV['XML_SERIALIZER'] = 'nokogiri'
|
14
|
+
task.failure_message = 'Failed with nokogiri xml serializer compatible'
|
15
|
+
end
|
16
|
+
|
17
|
+
RuboCop::RakeTask.new(:rubocop) do |task|
|
18
|
+
task.options = ['-P']
|
19
|
+
end
|
20
|
+
|
21
|
+
task default: %i[rubocop ox_compatible_spec nokogiri_compatible_spec]
|
@@ -27,9 +27,9 @@ image_base64 = File.read("#{Dir.pwd}/demo/templates/image_base64")
|
|
27
27
|
image = docx.create_embed_image(image_base64, width: 720000, height: 720000, align: :left)
|
28
28
|
|
29
29
|
rows = [
|
30
|
-
[Goldendocx::Tables::ImageCell.new(image
|
31
|
-
[Goldendocx::Tables::ImageCell.new(image
|
32
|
-
[Goldendocx::Tables::ImageCell.new(image
|
30
|
+
[Goldendocx::Tables::ImageCell.new(image:, content: '选项A'), 3, '¥3.00', '¥9.00'],
|
31
|
+
[Goldendocx::Tables::ImageCell.new(image:, content: '选项B'), 4, '¥6.50', '¥18.00'],
|
32
|
+
[Goldendocx::Tables::ImageCell.new(image:, content: '选项C'), 10, '¥6.00', '¥60.00']
|
33
33
|
]
|
34
34
|
rows.each do |r|
|
35
35
|
row = table.add_row(r)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ox'
|
4
|
+
require_relative 'xml_to_class'
|
5
|
+
|
6
|
+
xml_fragment = File.read("#{Dir.pwd}/demo/templates/styles/reportTitle")
|
7
|
+
root_class = XmlToClass.new.parse(Ox.parse(xml_fragment))
|
8
|
+
|
9
|
+
root_class.write_rb('goldendocx/styles')
|
10
|
+
root_class.write_spec('goldendocx/styles')
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Metrics/AbcSize
|
4
|
+
# rubocop:disable Metrics/MethodLength
|
5
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
6
|
+
require 'ox'
|
7
|
+
require 'fileutils'
|
8
|
+
require 'active_support/core_ext/string/inflections'
|
9
|
+
|
10
|
+
class XmlToClass
|
11
|
+
def parse(node)
|
12
|
+
@node = node
|
13
|
+
@namespace, @tag = parse_tag(@node.name)
|
14
|
+
@class_name = "#{@tag}Property".classify
|
15
|
+
parse_attributes
|
16
|
+
parse_children
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def write_rb(dir)
|
21
|
+
dir_to_write = "#{Dir.pwd}/lib/#{dir}"
|
22
|
+
FileUtils.mkdir_p(dir_to_write)
|
23
|
+
|
24
|
+
File.open("#{dir_to_write}/#{@tag}.rb", 'w') do |f|
|
25
|
+
f.puts '# frozen_string_literal: true'
|
26
|
+
f.puts ''
|
27
|
+
f.puts "class Goldendocx::#{@class_name}"
|
28
|
+
f.puts ' include Goldendocx::Element'
|
29
|
+
f.puts ''
|
30
|
+
f.puts " namespace :#{@namespace}" if @namespace
|
31
|
+
f.puts " tag :#{@tag}"
|
32
|
+
f.puts ''
|
33
|
+
@attributes.each do |name, opt|
|
34
|
+
options = opt.map { |k, v| "#{k}: :#{v}" }.join(',')
|
35
|
+
f.puts " attribute :#{name.underscore}, #{options}"
|
36
|
+
end
|
37
|
+
f.puts ''
|
38
|
+
@children.group_by(&:to_s).each do |name, values|
|
39
|
+
method = values.size > 1 ? :embeds_many : :embeds_one
|
40
|
+
_, class_name = parse_tag(name)
|
41
|
+
f.puts " #{method} :#{class_name.underscore}, class_name: 'Goldendocx::#{class_name.classify}Property'"
|
42
|
+
end
|
43
|
+
f.puts 'end'
|
44
|
+
end
|
45
|
+
|
46
|
+
@subclasses.each { |c| c.write_rb("#{dir}/#{@tag}") }
|
47
|
+
end
|
48
|
+
|
49
|
+
def write_spec(dir)
|
50
|
+
dir_to_write = "#{Dir.pwd}/spec/#{dir}"
|
51
|
+
FileUtils.mkdir_p(dir_to_write)
|
52
|
+
|
53
|
+
File.open("#{dir_to_write}/#{@tag}_spec.rb", 'w') do |f|
|
54
|
+
f.puts '# frozen_string_literal: true'
|
55
|
+
f.puts ''
|
56
|
+
f.puts "describe Goldendocx::#{@class_name} do"
|
57
|
+
f.puts ' let(:property) { described_class.new }'
|
58
|
+
f.puts ''
|
59
|
+
f.puts " specify 'builds default #{@tag} property xml' do "
|
60
|
+
f.puts " expect(property.to_xml).to eq('<#{@namespace}:#{@tag}/>')"
|
61
|
+
f.puts ' end'
|
62
|
+
f.puts ''
|
63
|
+
f.puts " specify 'builds customized #{@tag} property xml' do"
|
64
|
+
f.puts ' property.attribute = :value '
|
65
|
+
f.puts " expect(property.to_xml).to eq('<#{@namespace}:#{@tag}/>') "
|
66
|
+
f.puts ' end '
|
67
|
+
f.puts 'end'
|
68
|
+
end
|
69
|
+
|
70
|
+
@subclasses.each { |c| c.write_spec("#{dir}/#{@tag}") }
|
71
|
+
end
|
72
|
+
|
73
|
+
def parse_tag(string)
|
74
|
+
string = string.to_s
|
75
|
+
string.include?(':') ? string.split(':') : [nil, string]
|
76
|
+
end
|
77
|
+
|
78
|
+
def parse_attributes
|
79
|
+
@attributes ||= {}
|
80
|
+
@node.attributes.each_key do |name|
|
81
|
+
ns, tg = parse_tag(name)
|
82
|
+
@attributes[tg] = { alias_name: tg, namespace: ns }.compact
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def parse_children
|
87
|
+
@children = []
|
88
|
+
@subclasses = []
|
89
|
+
@node.nodes.each do |node|
|
90
|
+
@children << node.name.to_s
|
91
|
+
@subclasses << XmlToClass.new.parse(node)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
# rubocop:enable Metrics/AbcSize
|
96
|
+
# rubocop:enable Metrics/MethodLength
|
97
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
@@ -2,8 +2,7 @@
|
|
2
2
|
|
3
3
|
$LOAD_PATH.push "#{Dir.pwd}/lib"
|
4
4
|
require 'goldendocx'
|
5
|
-
|
6
|
-
docx = Goldendocx::Docx.new("#{Dir.pwd}/demo/templates/blankDocument.docx")
|
5
|
+
docx = Goldendocx::Docx.new.read_from("#{Dir.pwd}/demo/templates/blankDocument.docx")
|
7
6
|
|
8
7
|
# Register styles because default document without any style
|
9
8
|
docx.add_style(File.read("#{Dir.pwd}/demo/templates/styles/reportTitle"))
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.push "#{Dir.pwd}/lib"
|
4
|
+
require 'goldendocx'
|
5
|
+
|
6
|
+
docx = Goldendocx::Docx.new
|
7
|
+
|
8
|
+
docx.create_text('Hello World!')
|
9
|
+
docx.create_text('Hello World!', align: :center, color: 'FF8533', bold: true)
|
10
|
+
|
11
|
+
filename = 'plainTextDocument.docx'
|
12
|
+
system "rm -f ~/Desktop/#{filename}" # -f so that we don't have an error if the file doesn't exist
|
13
|
+
docx.write_to File.expand_path("~/Desktop/#{filename}")
|
14
|
+
exec "open ~/Desktop/#{filename}"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/concern'
|
4
|
+
require 'active_support/core_ext/array/access'
|
5
|
+
require 'active_support/core_ext/class/attribute'
|
6
|
+
require 'active_support/core_ext/class/subclasses'
|
7
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
8
|
+
require 'active_support/core_ext/string/inflections'
|
9
|
+
require 'active_support/core_ext/string/conversions'
|
10
|
+
|
11
|
+
ActiveSupport::Inflector.inflections do |inflect|
|
12
|
+
inflect.uncountable 'extents', 'image_data', 'data', 'defaults', 'latentStyles'
|
13
|
+
inflect.irregular 'axis', 'axes'
|
14
|
+
|
15
|
+
inflect.uncountable 'values' # TODO: Find better names
|
16
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
# FIXME: Temporarily here to provider syntactic sugar
|
6
|
+
module Nokogiri
|
7
|
+
module XML
|
8
|
+
class Document
|
9
|
+
def tag_name
|
10
|
+
root.tag_name
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Node
|
15
|
+
def <<(node_or_tags)
|
16
|
+
# FIXME: Add this line to transform element implicitly
|
17
|
+
node_or_tags = node_or_tags.public_send(:to_element, parent: self) if node_or_tags.respond_to?(:to_element)
|
18
|
+
|
19
|
+
add_child(node_or_tags)
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def adapt?(klass)
|
24
|
+
adaptable_classes = [String, Integer, Time]
|
25
|
+
is_a?(Nokogiri::XML::Text) && adaptable_classes.include?(klass)
|
26
|
+
end
|
27
|
+
|
28
|
+
def tag_name
|
29
|
+
[namespace&.prefix, name].compact.join(':')
|
30
|
+
end
|
31
|
+
|
32
|
+
def unparsed_children
|
33
|
+
@unparsed_children ||= children.dup
|
34
|
+
end
|
35
|
+
|
36
|
+
def attributes_hash
|
37
|
+
attribute_nodes.reject { |node| node.tag_name == 'mc:Ignorable' }.to_h { |node| [node.tag_name, node.value] }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ox'
|
4
|
+
|
5
|
+
module Ox
|
6
|
+
class Document
|
7
|
+
def root
|
8
|
+
children.first
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Element
|
13
|
+
def <<(node)
|
14
|
+
# FIXME: Add this line to transform element implicitly
|
15
|
+
node = node.public_send(:to_element) if node.respond_to?(:to_element)
|
16
|
+
|
17
|
+
raise 'argument to << must be a String or Ox::Node.' unless node.is_a?(String) || node.is_a?(Node)
|
18
|
+
|
19
|
+
@nodes = [] if !instance_variable_defined?(:@nodes) || @nodes.nil?
|
20
|
+
@nodes << node
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
alias children nodes
|
25
|
+
alias tag_name name
|
26
|
+
|
27
|
+
def unparsed_children
|
28
|
+
@unparsed_children ||= children.dup
|
29
|
+
end
|
30
|
+
|
31
|
+
def attributes_hash
|
32
|
+
attributes.with_indifferent_access.reject { |k, _| k.to_s.start_with?('xmlns') || k.to_s == 'mc:Ignorable' }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class String
|
4
|
+
class << self
|
5
|
+
def adapt?(xml_node)
|
6
|
+
xml_node.is_a?(String) || xml_node.adapt?(String)
|
7
|
+
end
|
8
|
+
|
9
|
+
def read_from(xml_node)
|
10
|
+
xml_node.to_s
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Time
|
16
|
+
class << self
|
17
|
+
def adapt?(xml_node)
|
18
|
+
xml_node.is_a?(String) || xml_node.adapt?(Time)
|
19
|
+
end
|
20
|
+
|
21
|
+
def read_from(xml_node)
|
22
|
+
xml_node.to_s.to_time
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_element(**_context)
|
27
|
+
strftime('%Y-%m-%dT%H:%M:%SZ')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Integer
|
32
|
+
class << self
|
33
|
+
def adapt?(xml_node)
|
34
|
+
xml_node.is_a?(String) || xml_node.adapt?(Integer)
|
35
|
+
end
|
36
|
+
|
37
|
+
def read_from(xml_node)
|
38
|
+
xml_node.to_s.to_i
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_element(**_context)
|
43
|
+
to_s
|
44
|
+
end
|
45
|
+
end
|
@@ -27,7 +27,7 @@ module Goldendocx
|
|
27
27
|
def categories=(categories)
|
28
28
|
category_axis.values.build_count(count: categories.size)
|
29
29
|
categories.each_with_index do |cat, index|
|
30
|
-
point = category_axis.values.build_point(index:
|
30
|
+
point = category_axis.values.build_point(index:)
|
31
31
|
point.build_value(value: cat)
|
32
32
|
end
|
33
33
|
end
|
@@ -35,7 +35,7 @@ module Goldendocx
|
|
35
35
|
def values=(values)
|
36
36
|
value_axis.values.build_count(count: values.size)
|
37
37
|
values.each_with_index do |val, index|
|
38
|
-
point = value_axis.values.build_point(index:
|
38
|
+
point = value_axis.values.build_point(index:)
|
39
39
|
point.build_value(value: val)
|
40
40
|
end
|
41
41
|
end
|
data/lib/goldendocx/charts.rb
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
module Goldendocx
|
4
4
|
module Components
|
5
5
|
class BarChart < Chart
|
6
|
-
def initialize(chart_id, relationship_id,
|
7
|
-
super(chart_id, relationship_id,
|
6
|
+
def initialize(chart_id, relationship_id, attributes = {})
|
7
|
+
super(chart_id, relationship_id, attributes)
|
8
8
|
|
9
9
|
build_chart.plot_area.build_bar_chart
|
10
10
|
end
|
@@ -18,21 +18,21 @@ module Goldendocx
|
|
18
18
|
attr_accessor :name
|
19
19
|
attr_reader :id, :series
|
20
20
|
|
21
|
-
def initialize(chart_id, relationship_id,
|
21
|
+
def initialize(chart_id, relationship_id, attributes = {})
|
22
22
|
@id = chart_id
|
23
23
|
@series = []
|
24
24
|
|
25
25
|
@paragraph = Goldendocx::Components::Paragraph.new
|
26
26
|
inline_drawing = @paragraph.build_run.build_drawing.build_inline
|
27
|
-
inline_drawing.build_non_visual_property(relationship_id:
|
27
|
+
inline_drawing.build_non_visual_property(relationship_id:)
|
28
28
|
inline_drawing.build_extents(width: attributes[:width], height: attributes[:height])
|
29
|
-
inline_drawing.build_graphic.build_data.build_chart(relationship_id:
|
29
|
+
inline_drawing.build_graphic.build_data.build_chart(relationship_id:)
|
30
30
|
end
|
31
31
|
|
32
32
|
def add_series(name, categories, values)
|
33
33
|
ser_id = series.size + 1
|
34
|
-
the_chart.build_series(categories
|
35
|
-
ser = Goldendocx::Charts::Series.new(categories
|
34
|
+
the_chart.build_series(categories:, values:, id: ser_id, name:)
|
35
|
+
ser = Goldendocx::Charts::Series.new(categories:, values:, id: ser_id, name:)
|
36
36
|
series << ser
|
37
37
|
ser
|
38
38
|
end
|
@@ -46,7 +46,7 @@ module Goldendocx
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def write_to(zos)
|
49
|
-
entry_name = format(Goldendocx::Charts::RELATIONSHIP_NAME_PATTERN, id:
|
49
|
+
entry_name = format(Goldendocx::Charts::RELATIONSHIP_NAME_PATTERN, id:)
|
50
50
|
zos.put_next_entry "word/#{entry_name}"
|
51
51
|
zos.write to_document_xml
|
52
52
|
end
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module Goldendocx
|
4
4
|
module Components
|
5
5
|
class ColumnChart < Chart
|
6
|
-
def initialize(chart_id, relationship_id,
|
7
|
-
super(chart_id, relationship_id,
|
6
|
+
def initialize(chart_id, relationship_id, attributes = {})
|
7
|
+
super(chart_id, relationship_id, attributes)
|
8
8
|
|
9
9
|
build_chart.plot_area.build_column_chart
|
10
10
|
end
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module Goldendocx
|
4
4
|
module Components
|
5
5
|
class DoughnutChart < Chart
|
6
|
-
def initialize(chart_id, relationship_id,
|
7
|
-
super(chart_id, relationship_id,
|
6
|
+
def initialize(chart_id, relationship_id, attributes = {})
|
7
|
+
super(chart_id, relationship_id, attributes)
|
8
8
|
|
9
9
|
build_chart.plot_area.build_doughnut_chart
|
10
10
|
end
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module Goldendocx
|
4
4
|
module Components
|
5
5
|
class LineChart < Chart
|
6
|
-
def initialize(chart_id, relationship_id,
|
7
|
-
super(chart_id, relationship_id,
|
6
|
+
def initialize(chart_id, relationship_id, attributes = {})
|
7
|
+
super(chart_id, relationship_id, attributes)
|
8
8
|
|
9
9
|
build_chart.plot_area.build_line_chart
|
10
10
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Goldendocx
|
4
|
+
module Components
|
5
|
+
module Properties
|
6
|
+
class FontProperty
|
7
|
+
include Goldendocx::Element
|
8
|
+
|
9
|
+
namespace :w
|
10
|
+
tag :rFonts
|
11
|
+
|
12
|
+
attribute :ascii, namespace: :w, default: 'Times New Roman'
|
13
|
+
attribute :east_asia, alias_name: :eastAsia, namespace: :w, default: '宋体'
|
14
|
+
attribute :high_ansi, alias_name: :hAnsi, namespace: :w, default: 'Times New Roman'
|
15
|
+
attribute :complex, alias_name: :cs, namespace: :w, default: 'Times New Roman'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Goldendocx
|
4
|
+
module Components
|
5
|
+
module Properties
|
6
|
+
class LanguageProperty
|
7
|
+
include Goldendocx::Element
|
8
|
+
|
9
|
+
namespace :w
|
10
|
+
tag :lang
|
11
|
+
|
12
|
+
attribute :complex, alias_name: :bidi, namespace: :w, default: 'ar-SA'
|
13
|
+
attribute :east_asia, alias_name: :eastAsia, namespace: :w, default: 'zh-CN'
|
14
|
+
attribute :latin, alias_name: :val, namespace: :w, default: 'en-US'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -11,6 +11,8 @@ module Goldendocx
|
|
11
11
|
|
12
12
|
embeds_one :color, class_name: 'Goldendocx::Components::Properties::ColorProperty', auto_build: false
|
13
13
|
embeds_one :bold, class_name: 'Goldendocx::Components::Properties::BoldProperty', auto_build: false
|
14
|
+
embeds_one :language, class_name: 'Goldendocx::Components::Properties::LanguageProperty', auto_build: false
|
15
|
+
embeds_one :font, class_name: 'Goldendocx::Components::Properties::FontProperty', auto_build: false
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
@@ -29,8 +29,8 @@ module Goldendocx
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def add_header(title, width: nil)
|
32
|
-
header.build_cell(content: title, width:
|
33
|
-
grid_property.build_grid_column(width:
|
32
|
+
header.build_cell(content: title, width:)
|
33
|
+
grid_property.build_grid_column(width:) if width
|
34
34
|
header
|
35
35
|
end
|
36
36
|
|
@@ -11,6 +11,6 @@ end
|
|
11
11
|
require 'goldendocx/components/properties'
|
12
12
|
require 'goldendocx/components/chart'
|
13
13
|
|
14
|
-
Dir.glob(File.join(File.dirname(__FILE__), 'components', '*.rb').to_s).
|
14
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'components', '*.rb').to_s).each do |file|
|
15
15
|
require file
|
16
16
|
end
|
@@ -6,13 +6,9 @@ module Goldendocx
|
|
6
6
|
include Goldendocx::Element
|
7
7
|
|
8
8
|
tag :Default
|
9
|
-
attribute :extension, alias_name: :Extension, readonly: true
|
10
|
-
attribute :content_type, alias_name: :ContentType, readonly: true
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
@content_type = content_type
|
15
|
-
end
|
10
|
+
attribute :extension, alias_name: :Extension
|
11
|
+
attribute :content_type, alias_name: :ContentType
|
16
12
|
|
17
13
|
def ==(other)
|
18
14
|
extension == other.extension && content_type == other.content_type
|