Cześć,
Wczoraj musiałem do aplikacji Rails 2.3.15 dołożyć eksport danych do Excel’a. Chwilę zajęło (głównie polskie znaki oraz prawidłowe otwieranie w Excelu) ale udało mi się osiągnąć cel.
Oczywiście rozwiązanie jest sumą tego co znalazłem (łatwo wygooglować biorąć kawałki kodu) + tego co wymyśliłem.
Korzystałem między innymi z
- http://railscasts.com/episodes/362-exporting-csv-and-excel (nie działa w 2.x oraz nie do końca w 3.x ale w komentarzach sporo pomysłów jak to poprawić)
- http://stackoverflow.com/questions/451636/whats-the-best-way-to-export-utf8-data-into-excel
Opis przykładu:
- mam model Participant (np. uczestnik szkolenia). Chcę obsłużyć pobierania w CSV z otwarciem Excel’a i jednoczesną translacją atrybutów na takie nad którymi mam kontrolę i mogę pokazać użytkownikowi (np. po polsku ze spacjami pomiędzy słowami).
Przepis
- Lokalizacja
- w config/initializers/locale.rb
[code]
I18n.load_path += Dir[Rails.root.join(‘lib’, ‘locales’, ‘*.{rb,yml}’)]
I18n.default_locale = :pl[/code]
- w lib/locales/pl.yml w gałęzi pl/attributtes/participant/ ustawione tłumaczenia atrybutów na takie jakie chcemy prezentować użytkownikom
przykładowo:
pl:
attributes:
participant:
first_name: "Imię"
2. Widok index.html.erb w app/views/participant (fragment z linkiem do pobierania). Rails zareaguje na url w postaci …/participants.csv
[code]
Pobierz:
<%= link_to “CSV”, participants_path(:format => “csv”) %>
@participants = Participant.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @participants }
format.csv { send_data \
Iconv.conv("utf-16le", "utf-8", "\xEF\xBB\xBF") \
+ Iconv.conv("utf-16le", "utf-8", \
Participant.to_csv(@participants, :col_sep => "\t")), :type => 'text/csv; charset=iso-8859-1; header=present'}
end
4. Model
- dodaje metodę klasową to_csv w której skleja się CSV (przy okazji zamieniając oryginalne nazwy atrybutów na czytelne dla użytkownika)
def self.to_csv(all_participants, options = {})
FasterCSV.generate(options) do |csv|
csv << column_names.collect {|col_name| Participant.human_attribute_name(col_name)}
all_participants.each do |participant|
csv << participant.attributes.values_at(*column_names)
end
end
end
5. FasterCSV
- zainstalować gem’a (np. sudo gem install fastercsv)
w config/environment.erb
require 'fastercsv'
Mam nadzieję że nie porobiłem literówek i zadziała od razu jak ktoś będzie chciał tego użyć.
Jakby coś nie było jasne lub nie działało, dajcie znać.
Pozdrawiam
Artur