Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 49dc9c5
Showing
12 changed files
with
384 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
*.gem | ||
*.rbc | ||
.bundle | ||
.config | ||
.yardoc | ||
Gemfile.lock | ||
InstalledFiles | ||
_yardoc | ||
coverage | ||
doc/ | ||
lib/bundler/man | ||
pkg | ||
rdoc | ||
spec/reports | ||
test/tmp | ||
test/version_tmp | ||
tmp | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
language: ruby | ||
script: "bundle exec cucumber" | ||
rvm: | ||
- 1.9.3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
source 'https://rubygems.org' | ||
|
||
# Specify your gem's dependencies in lazy-wombat.gemspec | ||
gemspec | ||
|
||
group :test do | ||
gem 'rake' | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
Copyright (c) 2012 Alexander Kaupanin | ||
|
||
MIT License | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
"Software"), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
# Lazy::Wombat ![Build Status](https://travis-ci.org/simsalabim/lazy-wombat.png "Build Status") | ||
|
||
A simple yet powerful DSL to generate Excel spreadsheets built on top of [axlsx](https://github.com/randym/axlsx) gem. | ||
|
||
## Why Lazy Wombat? | ||
Axlsx is awesome and quite complex in usage. | ||
Often you need something simple and easy-to-use to generate an excel spreadsheet as easy, as you markup tables with HTML. | ||
Now you can. | ||
|
||
## Installation | ||
|
||
Add this line to your application's Gemfile: | ||
|
||
gem 'lazy-wombat' | ||
|
||
And then execute: | ||
|
||
$ bundle | ||
|
||
Or install it yourself as: | ||
|
||
$ gem install lazy-wombat | ||
|
||
## Usage | ||
|
||
### Basic sample: no styles, just content | ||
|
||
Code | ||
```ruby | ||
LazyWombat::Xlsx.new do | ||
spreadsheet do | ||
row do | ||
cell 'Cyberdyne Systems' | ||
cell 'Model 101' | ||
cell 'The Terminator' | ||
end | ||
end | ||
end.save 'my_laziness.xlsx' | ||
``` | ||
Or shortened: | ||
```ruby | ||
LazyWombat::Xlsx.new do | ||
cell 'Cyberdyne Systems' | ||
cell 'Model 101' | ||
cell 'The Terminator' | ||
end.save 'my_laziness.xlsx' | ||
``` | ||
will create `my_laziness` spreadsheet looks like this: ![Generated spreadsheet](http://img525.imageshack.us/img525/7037/spreadsheet1.png) | ||
|
||
Since spreadsheet elements inheritance is alike `spreadsheet -> row -> cell`, you can arbitrary omit every unnecessary | ||
elder element of your spreadsheets. | ||
|
||
### Where is my HTML?? | ||
Oh yeah, I promised you `as you markup tables with HTML`: there're logic aliases: | ||
`spreadsheet` is `table`, `row` is `tr`, `cell` is, of course, `td` | ||
|
||
Thus here's our simplest example: | ||
```ruby | ||
LazyWombat::Xlsx.new do | ||
table do | ||
tr do | ||
td 'Cyberdyne Systems' | ||
td 'Model 101' | ||
td 'The Terminator' | ||
end | ||
end | ||
end.save 'my_laziness.xlsx' | ||
|
||
# or | ||
LazyWombat::Xlsx.new do | ||
td 'Cyberdyne Systems' | ||
td 'Model 101' | ||
td 'The Terminator' | ||
end.save 'my_laziness.xlsx' | ||
``` | ||
|
||
### Additional options: spreadsheet names, rows and cells styles | ||
By default spreadsheets are named as `Sheet 1`, `Sheet 2`, etc. It can be overwritten using `name` option. | ||
``ruby | ||
LazyWombat::Xlsx.new do | ||
spreadsheet name: 'My Laziness' do | ||
row style: :bold do | ||
cell 'Cyberdyne Systems' | ||
cell 'Model 101', style: :italic | ||
cell 'The Terminator' | ||
end | ||
end | ||
end.save 'my_laziness.xlsx' | ||
``` | ||
![Generated spreadsheet](http://img521.imageshack.us/img521/4272/spreadsheet2.png) | ||
## Contributing | ||
1. Fork it | ||
2. Create your feature branch (`git checkout -b my-new-feature`) | ||
3. Commit your changes (`git commit -am 'Add some feature'`) | ||
4. Push to the branch (`git push origin my-new-feature`) | ||
5. Create new Pull Request |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
require "bundler/gem_tasks" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
Feature: As a lazy wombat I should be able to generate an xlsx spreadsheet | ||
|
||
Scenario: I generate spreadsheet and save it to file | ||
Given I generate following spreadsheet: | ||
| Arnold | Schwarzenegger | Cyberdyne Systems Model 101 | The Terminator | 1 | | ||
| Wombat | Animal | Universal | Optimum Nutrition | 001 | | ||
| Hamster | Mole | Apartments | Valuation | Mockups | | ||
And save it as "my_spreadsheet.xlsx" | ||
Then "my_spreadsheet.xlsx" file should exist | ||
And "my_spreadsheet.xlsx" should have 1 spreadsheet | ||
And "my_spreadsheet.xlsx" should look like this: | ||
| Arnold | Schwarzenegger | Cyberdyne Systems Model 101 | The Terminator | <1.0> | | ||
| Wombat | Animal | Universal | Optimum Nutrition | <1.0> | | ||
| Hamster | Mole | Apartments | Valuation | Mockups | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
require 'roo' | ||
|
||
Given /^I generate following spreadsheet:$/ do |table| | ||
@excel = LazyWombat::Xlsx.new do | ||
row do | ||
table.hashes.first.keys.each { |key| cell key } | ||
end | ||
table.hashes.each do |hash| | ||
row do | ||
hash.values.each { |value| cell value } | ||
end | ||
end | ||
end | ||
end | ||
|
||
Given /^save it as "(.*?)"$/ do |file_name| | ||
@excel.save file_name | ||
end | ||
|
||
Then /^"(.*?)" file should exist$/ do |file_name| | ||
File.exists? file_name | ||
end | ||
|
||
Then /^"(.*?)" should have (\d+) spreadsheet$/ do |file_name, count| | ||
Excelx.new(file_name).sheets.should have(count).records | ||
end | ||
|
||
# gem 'roo' casts all read numbers to float | ||
Then /^"(.*?)" should look like this:$/ do |file_name, table| | ||
workbook = Excelx.new file_name | ||
prototype = table.raw | ||
columns_count = prototype.first.count | ||
1.upto(workbook.last_row) do |row_number| | ||
row = columns_count.times.map { |column| workbook.cell row_number, column + 1 } | ||
row.should == row_with_types(prototype[ row_number - 1 ]) | ||
end | ||
end | ||
|
||
def row_with_types row | ||
return if row.nil? | ||
row.each_with_index do |value, index| | ||
row[index] = (value =~ /\<(.*)\>/) ? eval(value[1..-2]) : value | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
$:.push File.expand_path('../../../lib', __FILE__) | ||
|
||
require 'lazy-wombat' | ||
require 'rspec/matchers' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# -*- encoding: utf-8 -*- | ||
lib = File.expand_path('../lib', __FILE__) | ||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) | ||
require 'lazy-wombat/version' | ||
|
||
Gem::Specification.new do |s| | ||
s.name = 'lazy-wombat' | ||
s.version = LazyWombat::VERSION | ||
s.authors = ['Alexander Kaupanin'] | ||
s.email = %w(kaupanin@gmail.com) | ||
s.description = %q{A simple yet powerful DSL to create Excel spreadsheets built on top of axlsx gem} | ||
s.summary = %q{A simple yet powerful DSL to create Excel spreadsheets built on top of axlsx gem} | ||
s.homepage = 'http://github.com/simsalabim/lazy-wombat' | ||
|
||
s.files = `git ls-files`.split($/) | ||
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) } | ||
s.test_files = s.files.grep(%r{^(test|spec|features)/}) | ||
s.require_paths = %w(lib) | ||
|
||
s.add_development_dependency 'cucumber', '~> 1.1' | ||
s.add_development_dependency 'rspec', '~> 2.9' | ||
s.add_development_dependency 'roo' | ||
s.add_runtime_dependency 'axlsx' | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
# encoding: utf-8 | ||
require 'lazy-wombat/version' | ||
require 'axlsx' | ||
|
||
module LazyWombat | ||
|
||
class Xlsx | ||
|
||
def initialize options = {}, &block | ||
@package_options = options | ||
@package = Axlsx::Package.new | ||
instance_exec &block | ||
end | ||
|
||
def spreadsheet options = {}, &block | ||
if block_given? | ||
@package.workbook.add_worksheet do |spreadsheet| | ||
@spreadsheet = spreadsheet | ||
@spreadsheet.name = options[:name] unless options[:name].nil? || options[:name].empty? | ||
build_spreadsheet_styles | ||
instance_exec &block | ||
end | ||
else | ||
build_spreadsheet | ||
end | ||
end | ||
alias_method :table, :spreadsheet | ||
|
||
def build_spreadsheet | ||
@spreadsheet ||= @package.workbook.add_worksheet.tap { @row = @cell = nil } | ||
end | ||
|
||
def row options = {}, &block | ||
if block_given? | ||
@row_options = options | ||
spreadsheet.add_row do |row| | ||
@row = row | ||
instance_exec &block | ||
end | ||
else | ||
build_row | ||
end | ||
end | ||
alias_method :tr, :row | ||
|
||
def build_row | ||
@row ||= spreadsheet.add_row.tap{ @cell = nil } | ||
end | ||
|
||
def cell value, options = {} | ||
unless @row_options.nil? || @row_options.empty? | ||
options = @row_options.merge(options){ |key, row_option, cell_option| Array.new << row_option << cell_option } | ||
end | ||
@cell = row.add_cell value.to_s, style: style_from_options(options) | ||
unless options[:colspan].nil? || options[:colspan].empty? | ||
spreadsheet.merge_cells "#{pos[:x]}#{pos[:y]}:#{shift_x(pos[:x], 5)}#{pos[:y]}" | ||
end | ||
end | ||
alias_method :td, :cell | ||
|
||
def save file_name | ||
@package.serialize file_name | ||
File.open file_name | ||
end | ||
|
||
def to_temp_file | ||
stream = @package.to_stream | ||
Tempfile.new(%w(temporary-workbook .xlsx), encoding: 'utf-8').tap do |file| | ||
file.write stream.read | ||
file.close | ||
end | ||
end | ||
|
||
def to_xml | ||
spreadsheet.to_xml_string | ||
end | ||
|
||
private | ||
|
||
def pos | ||
{ x: x_axis[@cell.pos[0]], y: y_axis[@cell.pos[1]] } | ||
end | ||
|
||
def shift_x x, diff | ||
x_axis[x_axis.index(x) + diff] | ||
end | ||
|
||
def style_from_options options | ||
if options[:style].is_a? Array | ||
add_complex_style options[:style] | ||
end | ||
spreadsheet_style_by_name style_name(options[:style]) | ||
end | ||
|
||
def style_name style_keys | ||
Array(style_keys).join('_').to_sym | ||
end | ||
|
||
def add_complex_style style_keys | ||
complex_option_args = {} | ||
style_keys.map{ |style_key| style_builder_args[style_key] }.compact.map{ |args| complex_option_args.merge! args } | ||
@style_builder_args[style_name(style_keys)] = complex_option_args | ||
rebuild_spreadsheet_styles | ||
end | ||
|
||
def style_builder_args | ||
@style_builder_args ||= { | ||
center: { alignment: { horizontal: :center } }, | ||
bold: { b: true }, | ||
italic: { i: true } | ||
} | ||
end | ||
|
||
def build_spreadsheet_styles | ||
@spreadsheet_styles = {} | ||
spreadsheet.workbook.styles do |style_builder| | ||
style_builder_args.each do |style_name, style_args| | ||
@spreadsheet_styles[style_name] = style_builder.add_style style_args | ||
end | ||
end | ||
@spreadsheet_styles | ||
end | ||
alias_method :rebuild_spreadsheet_styles, :build_spreadsheet_styles | ||
|
||
def spreadsheet_styles | ||
@spreadsheet_styles ||= build_spreadsheet_styles | ||
end | ||
|
||
def spreadsheet_style_by_name name | ||
spreadsheet_styles[name] | ||
end | ||
|
||
# should be dynamic but for now to avoid calculations is static | ||
def x_axis | ||
('A'..'Z').to_a | ||
end | ||
|
||
# should be dynamic but for now to avoid calculations is static | ||
def y_axis | ||
(1..1000).to_a | ||
end | ||
end | ||
end |
Oops, something went wrong.