Регулярная задача — экспорт данных (профили пользователей, заказы, товары) из вашего приложения. В большинстве случаев для этого используется как “носитель” формат CSV.
Если задача требует формата с большими возможностями, чем CSV, а кроме того, чтобы файл открывался как “родной” в Microsoft Excel, можно использовать файл формата XML, со специальной разметкой.
Рассмотрим задачу: в панели управления, менеджер имеет кнопку “Экспортировать все заказы”. При нажатии на эту кнопку он должен получить файл со всеми заказами, сделанными в элекронном магазине. Файл должен легко открываться в Microsoft Excel.
И так, алгоритм генерации CSV понятен и прост:
При генерации требуемого XML изменяется второй этап. Рассмотрим примеры кода.
Контроллер orders_controller.rb
def report
headers['Content-Type'] = "application/vnd.ms-excel"
headers['Content-Disposition'] = "attachment; filename=\"export.xls\""
headers['Cache-Control'] = ''
@columns = ["Дата", "Время", "Товар", "Количество", "Покупатель"]
@orders = Order.find :all
render :layout => false
end
Представление report.xml.builder
xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
xml.Workbook({
'xmlns' => "urn:schemas-microsoft-com:office:spreadsheet",
'xmlns:o' => "urn:schemas-microsoft-com:office:office",
'xmlns:x' => "urn:schemas-microsoft-com:office:excel",
'xmlns:html' => "http://www.w3.org/TR/REC-html40",
'xmlns:ss' => "urn:schemas-microsoft-com:office:spreadsheet"
}) do
xml.Styles do
xml.Style 'ss:ID' => 'Default', 'ss:Name' => 'Normal' do
xml.Alignment 'ss:Vertical' => 'Bottom'
xml.Borders
xml.Font 'ss:FontName' => 'Verdana'
xml.Interior
xml.NumberFormat
xml.Protection
end
xml.Style 'ss:ID' => 's22' do
xml.NumberFormat 'ss:Format' => 'General Date'
end
end
xml.Worksheet 'ss:Name' => "Orders" do
xml.Table do
# Header
xml.Row do
for column in @columns do
xml.Cell do
xml.Data column, 'ss:Type' => 'String'
end
end
end
# Rows
for order in @orders
xml.Row do
xml.Cell do xml.Data order.visit.strftime('%d.%m.%Y'), 'ss:Type' => 'String' end
xml.Cell do xml.Data order.visit.strftime('%H:%M'), 'ss:Type' => 'String' end
xml.Cell do xml.Data order.offer, 'ss:Type' => 'String' end
xml.Cell do xml.Data order.quantity, 'ss:Type' => 'String' end
xml.Cell do xml.Data order.customer, 'ss:Type' => 'String' end
end
end
end
end
end
Теперь, если вызвать orders/report браузер предложит сохранить сгенерированный файл.
Расширение .xls, у получаемого файла, позволит без проблем открыть его в Microsoft Excel (протестировано в версиях XP и 2007)
Такой метод генерации позволяет не только получать файл с данными, но и применять некоторое форматирование эти данных.
Статья основана на опыте применения метода из материалов wiki.rubyonrails.org
Приятной работы вам!
Есть еще удобная библиотека http://rubyforge.org/projects/ru-excel/ Поддержка русского языка "из-коробки". ru-excel основан на пинотовской библиотеке pyExcelerator. К тому же "xml-based" .xls-файлы открываются только новыми версиями Excel и часто глючат в OpenOffice.org. ru-excel генерирует бинарные файлы в формате Excel 97.
— 16.09.2008 в 17:45
Попробовал способ. Не знаю почему, но: 1) у меня заработало только как описано в англоязычной вики(кстати, не забудьте про render :layout => false) 2) созданный файл не открывается в опенофисе в ubuntu
— 16.09.2008 в 18:12
Кстати... У кого-нибудь получалось экспортировать данные в Excel, а потом их оттуда импортировать? если можно, дайте ссылку плиз
— 16.09.2008 в 19:30
Аноним, спасибо за ссылку на "ru-excel". Андрей, вам спасибо за "render :layout => false"
— 18.09.2008 в 09:01
Читать Excel можно этим модулем: http://rubyforge.org/projects/spreadsheet/
— 19.09.2008 в 11:47