Я написал решение, чтобы пройти через существующий ElementTree и использовать text / tail для отступов, как обычно ожидает.
def prettify(element, indent=' '):
queue = [(0, element)] # (level, element)
while queue:
level, element = queue.pop(0)
children = [(level + 1, child) for child in list(element)]
if children:
element.text = '\n' + indent * (level+1) # for child open
if queue:
element.tail = '\n' + indent * queue[0][0] # for sibling open
else:
element.tail = '\n' + indent * (level-1) # for parent close
queue[0:0] = children # prepend so children come before siblings
Существует плагин под названием FasterCSV, который обрабатывает это замечательно.
FasterCSV является определенно способом пойти, но если Вы захотите служить ему непосредственно из Вашего приложения для направляющих, Вы захотите настроить некоторые заголовки ответа, также.
я имею в наличии метод для установки имени файла и необходимых заголовков:
def render_csv(filename = nil)
filename ||= params[:action]
filename += '.csv'
if request.env['HTTP_USER_AGENT'] =~ /msie/i
headers['Pragma'] = 'public'
headers["Content-type"] = "text/plain"
headers['Cache-Control'] = 'no-cache, must-revalidate, post-check=0, pre-check=0'
headers['Content-Disposition'] = "attachment; filename=\"#{filename}\""
headers['Expires'] = "0"
else
headers["Content-Type"] ||= 'text/csv'
headers["Content-Disposition"] = "attachment; filename=\"#{filename}\""
end
render :layout => false
end
Используя это облегчает иметь что-то вроде этого в моем контроллере:
respond_to do |wants|
wants.csv do
render_csv("users-#{Time.now.strftime("%Y%m%d")}")
end
end
И имеют представление, которое похоже на это: (generate_csv
от FasterCSV)
UserID,Email,Password,ActivationURL,Messages
<%= generate_csv do |csv|
@users.each do |user|
csv << [ user[:id], user[:email], user[:password], user[:url], user[:message] ]
end
end %>
Я принял (и голосовал!) ответ @Brian, для первого указания на меня к FasterCSV. Тогда, когда я погуглил для нахождения драгоценного камня, я также нашел довольно полный пример в эта страница Wiki. Соединяя их, я обосновался на следующем коде.
Между прочим, команда для установки драгоценного камня: драгоценный камень sudo устанавливает fastercsv (весь нижний регистр)
require 'fastercsv'
class EntriesController < ApplicationController
def getcsv
entries = Entry.find(:all)
csv_string = FasterCSV.generate do |csv|
csv << ["first","last"]
entries.each do |e|
csv << [e.firstName,e.lastName]
end
end
send_data csv_string, :type => "text/plain",
:filename=>"entries.csv",
:disposition => 'attachment'
end
end
Смотрите в драгоценный камень FasterCSV .
, Если все Вам нужно, поддержка Excel, Вы могли бы также изучить генерацию xls непосредственно. (См. электронную таблицу:: Excel)
gem install fastercsv
gem install spreadsheet-excel
я нахожу эти опции хорошими для открытия файла CSV в Windows Excel:
FasterCSV.generate(:col_sep => ";", :row_sep => "\r\n") { |csv| ... }
Что касается части ActiveRecord, что-то вроде этого сделало бы:
CSV_FIELDS = %w[ title created_at etc ]
FasterCSV.generate do |csv|
Entry.all.map { |r| CSV_FIELDS.map { |m| r.send m } }.each { |row| csv << row }
end
Другой способ сделать это, не используя FasterCSV:
Требуют csv библиотеки рубина в файле инициализатора как config/initializers/dependencies.rb
require "csv"
Как некоторый фон, следующий код базируется прочь Форма Расширенного поиска Ryan Bate , который создает поисковый ресурс. В моем случае выставочный метод поискового ресурса возвратит результаты ранее сохраненного поиска. Это также отвечает на csv и использует шаблон представления для форматирования желаемого вывода.
def show
@advertiser_search = AdvertiserSearch.find(params[:id])
@advertisers = @advertiser_search.search(params[:page])
respond_to do |format|
format.html # show.html.erb
format.csv # show.csv.erb
end
end
show.csv.erb файл похож на следующее:
<%- headers = ["Id", "Name", "Account Number", "Publisher", "Product Name", "Status"] -%>
<%= CSV.generate_line headers %>
<%- @advertiser_search.advertisers.each do |advertiser| -%>
<%- advertiser.subscriptions.each do |subscription| -%>
<%- row = [ advertiser.id,
advertiser.name,
advertiser.external_id,
advertiser.publisher.name,
publisher_product_name(subscription),
subscription.state ] -%>
<%= CSV.generate_line row %>
<%- end -%>
<%- end -%>
На версии HTML страницы отчета у меня есть ссылка для экспорта отчета, что пользователь просматривает. Следующее является link_to, который возвращает csv версию отчета:
<%= link_to "Export Report", formatted_advertiser_search_path(@advertiser_search, :csv) %>
Необходимо установить заголовок Типа контента в ответе, затем отправить данные. Content_Type: application/vnd.ms-excel должен добиться цели.
можно также хотеть установить заголовок Довольного Расположения так, чтобы он был похож на документ Excel, и браузер выбирает разумное имя файла по умолчанию; это - что-то как Довольное Расположение: вложение; имя файла = "#{suggested_name}.xls"
я предлагаю использовать fastercsv рубиновый драгоценный камень для генерации CSV, но существует также встроенный csv. fastercsv пример кода (из документации драгоценного камня) похож на это:
csv_string = FasterCSV.generate do |csv|
csv << ["row", "of", "CSV", "data"]
csv << ["another", "row"]
# ...
end