So here's what I started with, after reading the docs for the spreadsheet library. Basically this is the creation of one report:
require 'spreadsheet'
class Reporter
public
class << self
def report_all_transactions(district)
book = Spreadsheet::Workbook.new
sheet = book.create_worksheet
sheet.row(1).concat ["ALL TRANSACTIONS BY THERAPIST"]
index = 2
district.therapists.each do |t|
sheet.row(index).concat [t.full_name]
index += 1
sheet.row(index).concat ["ID","Date","Start",
"Stop","Status","Location"]
index += 1
district.transactions.each do |trans|
sheet.row(index).concat [trans.id,trans.date,
trans.start,trans.stop,
trans.status,trans.school.name]
index += 1
end
index += 2
end
book.write "#{RAILS_ROOT}/public/data/all_transactions_report.xls"
end
end
end
It's not bad on the whole, but it's a little wordy, and the one thing that REALLY bothered me about it was that index tracking I was having to do and the repetitive nature of the whole "add some data, increment the index" thing.
So, in order to make this spreadsheet library more pleasant to work with, I created the class below:
class SheetWrapper
attr_accessor :index
def initialize(worksheet)
@sheet = worksheet
@index = 0
end
def add_row(array)
@sheet.row(@index).concat array
@index += 1
end
def add_lines(count)
@index += count
end
end
It's pretty simple, just a couple methods, but look what it does to that first code example I showed:
require 'spreadsheet'
class Reporter
public
class << self
def report_all_transactions_by_date(district)
book = Spreadsheet::Workbook.new
sheet = SheetWrapper.new(book.create_worksheet)
sheet.add_row ["ALL TRANSACTIONS BY THERAPIST"]
sheet.add_lines(1)
district.therapists.each do |t|
sheet.add_row [t.full_name]
sheet.add_row ["ID","Date","Start",
"Stop","Status","Location"]
district.transactions.each do |trans|
sheet.add_row [trans.id,trans.date,
trans.start,trans.stop,
trans.status,trans.school.name]
end
sheet.add_lines(2)
end
book.write "#{RAILS_ROOT}/public/data/all_transactions_report.xls"
end
end
end
Better already. One more problem that I had, though, was that all my report methods were kind of following the same pattern of opening a work book, adding some data, and then writing it out to the data directory. In order to reduce that pattern down to one chunk of reusable code, I extracted the "run_report" method as follows:
require 'spreadsheet'
class Reporter
public
class << self
def report_all_transactions_by_date(district)
filename = "all_transactions"
self.run_report(filename,"ALL TRANSACTIONS") do |sheet|
district.therapists.each do |t|
sheet.add_row [t.full_name]
sheet.add_row ["ID","Date","Start","Stop","Status","Location"]
district.transactions.each do |trans|
sheet.add_row [trans.id,trans.date,
trans.start,trans.stop,
trans.status,trans.school.name]
end
sheet.add_lines 2
end
end
end
end
protected
class << self
def run_report(file_name,title,header_row = nil)
name = "#{file_name}.xls"
book = Spreadsheet::Workbook.new
sheet = SheetWrapper.new(book.create_worksheet)
sheet.add_row [title]
sheet.index = 2
sheet.add_row header_row if header_row
yield(sheet)
book.write "#{RAILS_ROOT}/public/data/#{name}"
end
end
end
And that's pretty much it. Now all the large reports can be generated as Excel files, and the users are happy because they can play with that data anyway they need to in order to extract the information they're looking for (and we didn't have to spend a month writing features that spreadsheet programs already have into our web app).

4 comments:
yup... never forget the power of offering your users an excel file of their data. It's quite easy to make the mistake of generating graphs of the data each time they ask instead of just giving them an excel file and doing it themselves. ;)
Great post. This is definitely on our todo list for our project. Thanks for the recipe.
For executes this action I usually use next program-Excel 2007 file repair,why? because software helped me in different serious situation,also it has free status as how as I remember,utiltiy can try Excel repairs manually, by retyping all documents, but it is time consuming, you can spend many days for this purpose, when Excel file has corrupted,tool for Excel repairing is very easy to use, when Excel file corrupted, it has only several buttons and functions for Excel document repair: open file, start its analysis, preview of recovered contents and export of recovered data into a new document in Microsoft Excel format,allows to perform all steps and take a look into recovered contents of this file.
Some time ago one human said about nice tool-repair Excel file error message,which helped near 100 people,as he said it is free and has many features,furtherover it is used to process important information, such as graphics, diagrams, commercial and statistical data,recover *.xlsx, *.xlsm, *.xltm, *.xltx or *.xlam formats,tool will help you if you have to repair Excel file error message: Excel error the file is not in a recognizable format,allows choosing a file, that shown an error like: Excel error message this file is not in a recognizable format, then, you should fix Excel file for errors and proceed with its analysis,attempts to recover your document with this message: Excel error and this file is not in a recognizable format and shows a preview window.
Post a Comment