xlsx_writer 0.2.0 → 0.2.1
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.
- data/.gitignore +1 -0
- data/CHANGELOG +14 -0
- data/Gemfile +0 -6
- data/foo.rb +28 -0
- data/lib/xlsx_writer/autofilter.rb +11 -1
- data/lib/xlsx_writer/document.rb +2 -4
- data/lib/xlsx_writer/generators/sheet.rb +5 -1
- data/lib/xlsx_writer/generators/workbook.erb +7 -0
- data/lib/xlsx_writer/version.rb +1 -1
- data/repack.rb +25 -0
- data/test/test_xlsx_writer.rb +6 -6
- data/unpack.rb +23 -0
- data/xlsx_writer.gemspec +5 -0
- metadata +70 -3
data/.gitignore
CHANGED
data/CHANGELOG
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
0.2.1 / 2012-06-08
|
2
|
+
|
3
|
+
* Bug fixes
|
4
|
+
|
5
|
+
* Clean up after tests (don't leave junk files around)
|
6
|
+
|
7
|
+
* Enhancements
|
8
|
+
|
9
|
+
* Sorting by autofilter doesn't crash any more! (at least on Office for Mac 2011)
|
10
|
+
|
11
|
+
* Developer notes
|
12
|
+
|
13
|
+
* Added repack.rb and unpack.rb, which are useful for trying out incremental changes to xlsx files
|
14
|
+
|
1
15
|
0.2.0 / 2012-04-23
|
2
16
|
|
3
17
|
* Enhancements
|
data/Gemfile
CHANGED
data/foo.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
|
3
|
+
if ::Bundler.definition.specs['debugger'].first
|
4
|
+
require 'debugger'
|
5
|
+
elsif ::Bundler.definition.specs['ruby-debug'].first
|
6
|
+
require 'ruby-debug'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'xlsx_writer'
|
10
|
+
|
11
|
+
@doc = XlsxWriter::Document.new
|
12
|
+
|
13
|
+
@sheet1 = @doc.add_sheet("Sheet1")
|
14
|
+
@sheet1.add_row(['a', 'a'])
|
15
|
+
@sheet1.add_row(['a', 'a'])
|
16
|
+
@sheet1.add_row(['a', 'a'])
|
17
|
+
# @sheet1.add_row(['foo', 'bar'])
|
18
|
+
@sheet1.add_autofilter 'A1:B1'
|
19
|
+
|
20
|
+
@sheet2 = @doc.add_sheet("Sheet2")
|
21
|
+
@sheet2.add_row(['a', 'a'])
|
22
|
+
# @sheet2.add_row(['hello', 'world'])
|
23
|
+
# @sheet2.add_row(['yo', 'there'])
|
24
|
+
# @sheet2.add_row(['foo', 'bar'])
|
25
|
+
@sheet2.add_autofilter 'A1:B1'
|
26
|
+
|
27
|
+
FileUtils.mv @doc.path, 'foo.xlsx'
|
28
|
+
@doc.cleanup
|
@@ -1,7 +1,17 @@
|
|
1
1
|
module XlsxWriter
|
2
|
-
class Autofilter < ::Struct.new(:range)
|
2
|
+
class Autofilter < ::Struct.new(:sheet, :range)
|
3
3
|
def to_xml
|
4
4
|
%{<autoFilter ref="#{range}" />}
|
5
5
|
end
|
6
|
+
|
7
|
+
# Sheet1!$A$1:$B$1
|
8
|
+
def defined_name
|
9
|
+
"#{sheet.name}!#{dollar_range}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def dollar_range
|
13
|
+
a = /([A-Z]+)(\d+):([A-Z]+)(\d+)/.match(range).captures.map { |c| c.prepend '$' }
|
14
|
+
[ a.first(2).join, a.last(2).join ].join(':')
|
15
|
+
end
|
6
16
|
end
|
7
17
|
end
|
data/lib/xlsx_writer/document.rb
CHANGED
@@ -63,10 +63,8 @@ module XlsxWriter
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def cleanup
|
66
|
-
::FileUtils.rm_rf
|
67
|
-
|
68
|
-
::File.unlink(@path) if ::File.exist?(@path.to_s)
|
69
|
-
end
|
66
|
+
::FileUtils.rm_rf @staging_dir.to_s
|
67
|
+
::FileUtils.rm_f @path.to_s
|
70
68
|
end
|
71
69
|
|
72
70
|
def generate
|
@@ -29,6 +29,10 @@ module XlsxWriter
|
|
29
29
|
document.sheets.index(self) + 1
|
30
30
|
end
|
31
31
|
|
32
|
+
def local_id
|
33
|
+
ndx - 1
|
34
|
+
end
|
35
|
+
|
32
36
|
# +1 because styles.xml occupies the first spot
|
33
37
|
def rid
|
34
38
|
"rId#{ndx + 1}"
|
@@ -45,7 +49,7 @@ module XlsxWriter
|
|
45
49
|
# specify range like "A1:C1"
|
46
50
|
def add_autofilter(range)
|
47
51
|
raise ::RuntimeError, "Can't add autofilter, already generated!" if generated?
|
48
|
-
autofilters << Autofilter.new(range)
|
52
|
+
autofilters << Autofilter.new(self, range)
|
49
53
|
end
|
50
54
|
|
51
55
|
def add_row(data)
|
@@ -9,4 +9,11 @@
|
|
9
9
|
<sheet name="<%= sheet.name %>" sheetId="<%= sheet.ndx %>" r:id="<%= sheet.rid %>"/>
|
10
10
|
<% end %>
|
11
11
|
</sheets>
|
12
|
+
<definedNames>
|
13
|
+
<% document.sheets.each do |sheet| %>
|
14
|
+
<% sheet.autofilters.each do |autofilter| %>
|
15
|
+
<definedName name="_xlnm._FilterDatabase" localSheetId="<%= sheet.local_id %>" hidden="1"><%= autofilter.defined_name %></definedName>
|
16
|
+
<% end %>
|
17
|
+
<% end %>
|
18
|
+
</definedNames>
|
12
19
|
</workbook>
|
data/lib/xlsx_writer/version.rb
CHANGED
data/repack.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Usage: ./repack.rb foo
|
4
|
+
# where "foo" is a directory previously unpacked to by unpack.rb
|
5
|
+
# outputs to out.xlsx
|
6
|
+
|
7
|
+
require 'unix_utils'
|
8
|
+
|
9
|
+
src = File.expand_path ARGV[0]
|
10
|
+
dest = File.join(File.dirname(src), 'out.xlsx')
|
11
|
+
|
12
|
+
raise "#{dest} exists" if File.exist?(dest)
|
13
|
+
|
14
|
+
src_copy = UnixUtils.tmp_path src
|
15
|
+
FileUtils.cp_r src, src_copy
|
16
|
+
Dir["#{src_copy}/**/*"].each do |infile|
|
17
|
+
if File.file?(infile) and not File.extname(infile) == '.vml' and File.read(infile, 50).include?('<?xml')
|
18
|
+
raise "uhh ohh #{File.dirname(infile)}" unless File.dirname(infile).start_with?(Dir.tmpdir)
|
19
|
+
tmp_path = UnixUtils.unix2dos infile
|
20
|
+
FileUtils.mv tmp_path, infile
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
tmp_path = UnixUtils.zip src_copy
|
25
|
+
FileUtils.mv tmp_path, dest
|
data/test/test_xlsx_writer.rb
CHANGED
@@ -76,20 +76,20 @@ describe XlsxWriter do
|
|
76
76
|
@doc.header.right.contents = 'Reporting Program'
|
77
77
|
@doc.footer.center.contents = [ 'Powered by ', center_footer_image ]
|
78
78
|
@doc.footer.right.contents = :page_x_of_y
|
79
|
+
@unzipped = UnixUtils.unzip @doc.path
|
79
80
|
end
|
80
81
|
after do
|
81
82
|
@doc.cleanup
|
83
|
+
FileUtils.rm_rf @unzipped
|
82
84
|
end
|
83
85
|
it "has an autofilter" do
|
84
|
-
|
85
|
-
File.read("#{contents}/xl/worksheets/sheet1.xml").must_include %{<autoFilter ref="A1:F1" />}
|
86
|
+
File.read("#{@unzipped}/xl/worksheets/sheet1.xml").must_include %{<autoFilter ref="A1:F1" />}
|
86
87
|
end
|
87
88
|
it "has a header image" do
|
88
|
-
|
89
|
-
File.read("#{
|
90
|
-
File.read("#{contents}/xl/drawings/vmlDrawing1.vml").must_include %{<v:imagedata o:relid="rId1" o:title="image1.emf" croptop="11025f" cropleft="9997f"/>}
|
89
|
+
File.read("#{@unzipped}/xl/drawings/_rels/vmlDrawing1.vml.rels").must_include %{<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="/xl/media/image1.emf"/>}
|
90
|
+
File.read("#{@unzipped}/xl/drawings/vmlDrawing1.vml").must_include %{<v:imagedata o:relid="rId1" o:title="image1.emf" croptop="11025f" cropleft="9997f"/>}
|
91
91
|
original = UnixUtils.md5sum File.expand_path("../support/image1.emf", __FILE__)
|
92
|
-
UnixUtils.md5sum("#{
|
92
|
+
UnixUtils.md5sum("#{@unzipped}/xl/media/image1.emf").must_equal original
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
data/unpack.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Usage: ./unpack.rb foo.xlsx
|
4
|
+
# outputs to foo/
|
5
|
+
|
6
|
+
# requires xmllint to be in your path
|
7
|
+
|
8
|
+
require 'unix_utils'
|
9
|
+
|
10
|
+
src = File.expand_path ARGV[0]
|
11
|
+
dest = File.join(File.dirname(src), File.basename(src, '.xlsx').gsub(/\W/, '_'))
|
12
|
+
|
13
|
+
raise "#{dest} exists" if File.exist?(dest)
|
14
|
+
tmp_path = UnixUtils.unzip src
|
15
|
+
FileUtils.mv tmp_path, dest
|
16
|
+
|
17
|
+
Dir["#{dest}/**/*"].each do |infile|
|
18
|
+
if File.file?(infile) and not File.extname(infile) == '.vml' and File.read(infile, 50).include?('<?xml')
|
19
|
+
outfile = infile + '.tmp'
|
20
|
+
`xmllint --format #{infile} > #{outfile}`
|
21
|
+
FileUtils.mv outfile, infile
|
22
|
+
end
|
23
|
+
end
|
data/xlsx_writer.gemspec
CHANGED
@@ -13,6 +13,11 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.add_runtime_dependency 'activesupport'
|
14
14
|
s.add_runtime_dependency 'fast_xs'
|
15
15
|
s.add_runtime_dependency 'unix_utils'
|
16
|
+
|
17
|
+
s.add_development_dependency 'minitest'
|
18
|
+
s.add_development_dependency 'minitest-reporters'
|
19
|
+
s.add_development_dependency 'yard'
|
20
|
+
s.add_development_dependency 'remote_table'
|
16
21
|
|
17
22
|
s.files = `git ls-files`.split("\n")
|
18
23
|
s.test_files = `git ls-files -- {test,features}/*`.split("\n")
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xlsx_writer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-
|
14
|
+
date: 2012-06-08 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activesupport
|
@@ -61,6 +61,70 @@ dependencies:
|
|
61
61
|
- - ! '>='
|
62
62
|
- !ruby/object:Gem::Version
|
63
63
|
version: '0'
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: minitest
|
66
|
+
requirement: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
type: :development
|
73
|
+
prerelease: false
|
74
|
+
version_requirements: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ! '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: minitest-reporters
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: yard
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: remote_table
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ! '>='
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
type: :development
|
121
|
+
prerelease: false
|
122
|
+
version_requirements: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ! '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
64
128
|
description: Writes XLSX files. Minimal XML and style. Supports autofilters and headers/footers
|
65
129
|
with images and page numbers.
|
66
130
|
email:
|
@@ -76,6 +140,7 @@ files:
|
|
76
140
|
- LICENSE
|
77
141
|
- README.markdown
|
78
142
|
- Rakefile
|
143
|
+
- foo.rb
|
79
144
|
- lib/xlsx_writer.rb
|
80
145
|
- lib/xlsx_writer/autofilter.rb
|
81
146
|
- lib/xlsx_writer/cell.rb
|
@@ -107,10 +172,12 @@ files:
|
|
107
172
|
- lib/xlsx_writer/row.rb
|
108
173
|
- lib/xlsx_writer/version.rb
|
109
174
|
- lib/xlsx_writer/xml.rb
|
175
|
+
- repack.rb
|
110
176
|
- test/helper.rb
|
111
177
|
- test/support/image1.emf
|
112
178
|
- test/support/image2.emf
|
113
179
|
- test/test_xlsx_writer.rb
|
180
|
+
- unpack.rb
|
114
181
|
- xlsx_writer.gemspec
|
115
182
|
homepage: https://github.com/seamusabshere/xlsx_writer
|
116
183
|
licenses: []
|
@@ -132,7 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
199
|
version: '0'
|
133
200
|
requirements: []
|
134
201
|
rubyforge_project:
|
135
|
-
rubygems_version: 1.8.
|
202
|
+
rubygems_version: 1.8.24
|
136
203
|
signing_key:
|
137
204
|
specification_version: 3
|
138
205
|
summary: Writes XLSX files. Minimal XML and style. Supports autofilters and headers/footers
|