# Spreadsheet Architect Donate Spreas Spreadsheet Architect is a library that allows you to create XLSX, ODS, or CSV spreadsheets easily from ActiveRecord relations, Plain Ruby classes, or predefined data. Key Features: - Can generate headers & columns from ActiveRecord column_names, or a Class/Model's spreadsheet_columns method, or one creation with 2D array of data - Plain Ruby support - Plain from ActiveRecord relations or Ruby Objects from models ActiveRecord, or 2d Array Data - Easily style headers and rows - Model/Class or Project specific defaults - Simple to use ActionController renderers Spreadsheet Architect adds the following methods to your class: ```ruby # Rails ActiveRecord Model Post.order(name: :asc).where(published: true).to_xlsx Post.order(name: :asc).where(published: true).to_ods Post.order(name: :asc).where(published: true).to_csv # Plain Ruby Class Post.to_xlsx(instances: posts_array) Post.to_ods(instances: posts_array) Post.to_csv(instances: posts_array) # One Time Usage headers = ['Col 1','Col 2','Col 3'] data = [[1,2,3], [4,5,6], [7,8,9]] SpreadsheetArchitect.to_xlsx(data: data, headers: headers) SpreadsheetArchitect.to_ods(data: data, headers: headers) SpreadsheetArchitect.to_csv(data: data, header: false) ``` # Install ```ruby gem install spreadsheet_architect ``` # Class/Model Setup ### Model ```ruby class Post < ActiveRecord::Base #activerecord not required include SpreadsheetArchitect belongs_to :author belongs_to :category has_many :tags #optional for activerecord classes, defaults to the models column_names def spreadsheet_columns #[[Label, Method/Statement to Call on each Instance, Cell Type(optional)]....] [ ['Title', :title], ['Content', content], ['Author', (author.name rescue nil)], ['Published?', (published ? 'Yes' : 'No')], ['Published At', :published_at], ['# of Views', :number_of_views], ['Rating', :rating], ['Category/Tags', "#{category.name} - #{tags.collect(&:name).join(', ')}"] ] # OR if you want to use the method or attribute name as a label it must be a symbol ex. "Title", "Content", "Published" [:title, :content, :published] # OR a Combination of Both ex. "Title", "Content", "Author Name", "Published" [:title, :content, ['Author Name',(author.name rescue nil)], :published] end end ``` # Usage ### Method 1: Controller (for Rails) ```ruby class PostsController < ActionController::Base respond_to :html, :xlsx, :ods, :csv # Using respond_with def index @posts = Post.order(published_at: :asc) respond_with @posts end # Using respond_with with custom options def index @posts = Post.order(published_at: :asc) if ['xlsx','ods','csv'].include?(request.format) respond_with @posts.to_xlsx(row_style: {bold: true}), filename: 'Posts' else respond_with @posts end end # Using responders def index @posts = Post.order(published_at: :asc) respond_to do |format| format.html format.xlsx { render xlsx: @posts } format.ods { render ods: @posts } format.csv{ render csv: @posts } end end # Using responders with custom options def index @posts = Post.order(published_at: :asc) respond_to do |format| format.html format.xlsx { render xlsx: @posts.to_xlsx(headers: false) } format.ods { render ods: Post.to_odf(instances: @posts) } format.csv{ render csv: @posts.to_csv(headers: false), file_name: 'articles' } end end end ``` ### Method 2: Save to a file manually ```ruby # Ex. with ActiveRecord realtion File.open('path/to/file.xlsx') do |f| f.write{ Post.order(published_at: :asc).to_xlsx } end File.open('path/to/file.ods') do |f| f.write{ Post.order(published_at: :asc).to_ods } end File.open('path/to/file.csv') do |f| f.write{ Post.order(published_at: :asc).to_csv } end # Ex. with plain ruby class File.open('path/to/file.xlsx') do |f| f.write{ Post.to_xlsx(instances: posts_array) } end # Ex. One time Usage File.open('path/to/file.xlsx') do |f| headers = ['Col 1','Col 2','Col 3'] data = [[1,2,3], [4,5,6], [7,8,9]] f.write{ SpreadsheetArchitect::to_xlsx(data: data, headers: headers) } end ``` # Method & Options
#### `.to_xlsx` - (on custom class/model) |Option|Type|Default|Notes| |---|---|---|---| |**spreadsheet_columns**|Array| AR Model column_names | Required if `spreadsheet_columns` not defined on class except with ActiveRecord models which default to the `column_names` method. Will override models `spreadsheet_columns` method | |**instances**|Array| |**Required for Non-ActiveRecord classes** Array of class/model instances.| |**headers**|Boolean|`true`|Pass false to skip the header row.| |**sheet_name**|String|Class name|| |**header_style**|Hash|`{background_color: "AAAAAA", color: "FFFFFF", align: :center, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false}`|| |**row_style**|Hash|`{background_color: nil, color: "FFFFFF", align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false}`|Styles for non-header rows.|
#### `.to_ods` - (on custom class/model) |Option|Type|Default|Notes| |---|---|---|---| |**spreadsheet_columns**|Array| AR Model column_names | Required if `spreadsheet_columns` not defined on class except with ActiveRecord models which default to the `column_names` method. Will override models `spreadsheet_columns` method | |**instances**|Array| |**Required for Non-ActiveRecord classes** Array of class/model instances.| |**headers**|Boolean|`true`|Pass false to skip the header row.| |**sheet_name**|String|Class name|| |**header_style**|Hash|`{color: "000000", align: :center, font_size: 10, bold: true}`|Note: Currently only supports these options (values can be changed though)| |**row_style**|Hash|`{color: "000000", align: :left, font_size: 10, bold: false}`|Styles for non-header rows. Currently only supports these options (values can be changed though)|
#### `.to_csv` - (on custom class/model) |Option|Type|Default|Notes| |---|---|---|---| |**spreadsheet_columns**|Array| AR Model column_names | Required if `spreadsheet_columns` not defined on class except with ActiveRecord models which default to the `column_names` method. Will override models `spreadsheet_columns` method | |**instances**|Array| |**Required for Non-ActiveRecord classes** Array of class/model instances.| |**headers**|Boolean|`true`|Pass false to skip the header row.|
#### `SpreadsheetArchitect.to_xlsx` |Option|Type|Default|Notes| |---|---|---|---| |**data**|Array| |**Required** 2D Array of data for the non-header row cells. | |**headers**|Array|`false`|2D Array of data for the header rows cells. Pass false to skip the header row.| |**sheet_name**|String|`SpreadsheetArchitect`|| |**header_style**|Hash|`{background_color: "AAAAAA", color: "FFFFFF", align: :center, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false}`|| |**row_style**|Hash|`{background_color: nil, color: "FFFFFF", align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false}`|Styles for non-header rows.|
#### `SpreadsheetArchitect.to_ods` |Option|Type|Default|Notes| |---|---|---|---| |**data**|Array| |**Required** 2D Array of data for the non-header row cells.| |**headers**|Array|`false`|2D Array of data for the header rows cells. Pass false to skip the header row.| |**sheet_name**|String|`SpreadsheetArchitect`|| |**header_style**|Hash|`{color: "000000", align: :center, font_size: 10, bold: true}`|Note: Currently only supports these options (values can be changed though)| |**row_style**|Hash|`{color: "000000", align: :left, font_size: 10, bold: false}`|Styles for non-header rows. Currently only supports these options (values can be changed though)|
#### `SpreadsheetArchitect.to_csv` |Option|Type|Default|Notes| |---|---|---|---| |**data**|Array| |**Required** 2D Array of data for the non-header row cells.| |**headers**|Array|`false`|2D Array of data for the header rows cells. Pass false to skip the header row.| # Change model default method options ```ruby class Post include SpreadsheetArchitect def spreadsheet_columns [:name, :content] end SPREADSHEET_OPTIONS = { headers: true, header_style: {background_color: "AAAAAA", color: "FFFFFF", align: :center, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false}, row_style: {background_color: nil, color: "FFFFFF", align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false}, sheet_name: self.name } end ``` # Change project wide default method options ```ruby # config/initializers/spreadsheet_architect.rb SpreadsheetArchitect.module_eval do set_const('SPREADSHEET_OPTIONS, { headers: true, header_style: {background_color: "AAAAAA", color: "FFFFFF", align: :center, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false}, row_style: {background_color: nil, color: "FFFFFF", align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false}, sheet_name: 'My Project Export' }) end ``` # Credits Created by Weston Ganger - @westonganger Heavily influenced by the dead gem `acts_as_xlsx` by @randym but adapted to work for more spreadsheet types and plain ruby models. Donate