goldendocx 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/goldendocx.svg)](https://badge.fury.io/rb/goldendocx)
|
4
|
+
[![Coverage Status](https://coveralls.io/repos/github/SheldonLeo/goldendocx/badge.svg)](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
|