2008-09-18 11 views
52

मैं "प्रविष्टियां" कहा जाता है एक साधारण डेटाबेस तालिका है के रूप में रिकॉर्ड वापस जाने के लिए फ़ाइल (आदर्श रूप से इस तरह से यह एक्सेल में स्वचालित रूप से खुल जाएगा)?रेल में, कैसे एक csv फ़ाइल

class EntriesController < ApplicationController 

    def getcsv 
    @entries = Entry.find(:all) 

    # ??? NOW WHAT ???? 

    end 

end 
+0

कम से कम रेल के नवीनतम संस्करण में, आप भी उपयोग कर सकते हैं 'प्रविष्टि में ऐसा कर सकते हैं। इसके बजाय सभी '। –

उत्तर

22

FasterCSV नामक एक प्लगइन है जो इस अद्भुत तरीके से संभालती है।

+29

ध्यान दें कि रूबी> = 1.9, FasterCSV अब मानक सीएसवी लाइब्रेरी है, और इसे केवल सीएसवी कहा जाता है। – kdt

+0

कुंजी 'csv' की आवश्यकता है, https://ruby-doc.org/stdlib/libdoc/csv/rdoc/CSV.html – mb21

7

FasterCSV मणि में एक नज़र डालें।

यदि आपको केवल एक्सेल समर्थन की आवश्यकता है, तो आप सीधे एक एक्सएलएस उत्पन्न करने में भी देख सकते हैं। (स्प्रेडशीट :: एक्सेल देखें)

gem install fastercsv 
gem install spreadsheet-excel 

मैं इन विकल्पों Windows Excel में csv फ़ाइल को खोलने के लिए अच्छा लगता है:

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 
2

आपको अपनी प्रतिक्रिया में सामग्री-प्रकार शीर्षलेख सेट करने की आवश्यकता है, फिर डेटा भेजें। Content_Type: एप्लिकेशन/vnd.ms-excel चाल करना चाहिए।

आप सामग्री-वितरण शीर्षलेख भी सेट करना चाहते हैं ताकि यह एक्सेल दस्तावेज़ की तरह दिख सके, और ब्राउज़र उचित डिफ़ॉल्ट फ़ाइल नाम चुनता है; यह सामग्री-विस्थापन की तरह कुछ है: लगाव; filename = "# {suggest_name} .xls"

मैं आपके सीएसवी उत्पन्न करने के लिए fastcsv ruby ​​मणि का उपयोग करने का सुझाव देता हूं, लेकिन एक अंतर्निहित सीएसवी भी है। (मणि के दस्तावेज़ से) fastercsv नमूना कोड इस तरह दिखता है:

csv_string = FasterCSV.generate do |csv| 
    csv << ["row", "of", "CSV", "data"] 
    csv << ["another", "row"] 
# ... 
end 
+0

उस अस्पष्ट सामग्री-प्रकार के लिए धन्यवाद! मुझे वास्तव में यकीन नहीं है कि यह अंत में एक्सेल होने जा रहा है, लेकिन यह जानना अच्छा है। – Eric

87

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 %> 
+0

हम्म, मैंने सोचा कि जब तक मैंने आपका जवाब नहीं देखा तब तक मैं किया गया था! हेडर विवरण के लिए धन्यवाद, मैं उन लोगों को याद रखूंगा जो मुझे अब तक उपयोग में आने वाली परेशानी में पड़ते हैं। – Eric

+8

जैसा ऊपर बताया गया है, FasterCSV रूबी 1.9 और ऊपर में केवल सीएसवी है। Gererate_csv विधि अब CSV.generate है। –

+4

gener_csv/CSV.generate ब्लॉक के अंत में .html_safe जोड़ना इसे बनाएगा ताकि डेटा में किसी भी कॉमा को सही ढंग से संभाला जा सके। इस कॉल के बिना मेरी सीएसवी फाइल में " " का गुच्छा था। – stcorbett

24

मैंने ब्रायन के जवाब को स्वीकार कर लिया (और वोट दिया!), पहले मुझे FasterCSV पर इंगित करने के लिए। फिर जब मैंने मणि खोजने के लिए गुगल किया, तो मुझे this wiki page पर एक बिल्कुल पूरा उदाहरण मिला। उन्हें एक साथ रखकर, मैं निम्नलिखित कोड पर बस गया।

वैसे, आदेश मणि स्थापित करने के लिए है: 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 
+5

मैं सीएसवी पीढ़ी को एक दृश्य में ले जाने का सुझाव दूंगा: यह अधिक प्रस्तुति तर्क है जो आप आमतौर पर नियंत्रक में चाहते हैं। –

+0

आप टाइप को 'टेक्स्ट/सीएसवी' पर सेट करना चाहते हैं। अन्यथा, सफारी इसे 'प्रविष्टियों.csv.txt' के रूप में सहेज लेगा – silasjmatson

24

FasterCSV का उपयोग किए बिना यह करने के लिए एक और तरीका है:

माणिक के सीएसवी आवश्यकता होती है प्रारंभिक फ़ाइल में लाइब्रेरी जैसे कॉन्फ़िगर/प्रारंभकर्ता/निर्भरता.आरबी

require "csv" 

कुछ पृष्ठभूमि के रूप में निम्न कोड है Ryan Bate's Advanced Search Form के आधार पर जो एक खोज संसाधन बनाता है। मेरे मामले में खोज संसाधन की शो विधि पहले से सहेजी गई खोज के परिणामों को वापस कर देगी। यह सीएसवी का भी जवाब देता है, और वांछित आउटपुट को प्रारूपित करने के लिए एक दृश्य टेम्पलेट का उपयोग करता है। रिपोर्ट पेज मैं रिपोर्ट है कि उपयोगकर्ता द्वारा देखे जा निर्यात करने के लिए एक कड़ी के HTML संस्करण पर

<%- 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 -%> 

:

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 फ़ाइल निम्न तरह दिखता है। निम्नलिखित LINK_TO उस रिपोर्ट का csv संस्करण रिटर्न है:

<%= link_to "Export Report", formatted_advertiser_search_path(@advertiser_search, :csv) %> 
+5

'<% = CSV.generate_line (पंक्ति) .html_safe%> 'यदि आप अक्षरों से बचने से बचने के लिए रेल 3 का उपयोग कर रहे हैं, तो इसका उपयोग करना न भूलें। – dombesz

+6

यह समाधान ठीक काम करता है लेकिन मुझे CSV.generate_line कॉल सेटिंग बदलना पड़ा: row_sep से nil। यह परिवर्तन प्रतिक्रिया से अवांछित खाली रेखाओं को हटा देता है। कोड: '<% = CSV.generate_line पंक्ति, {: row_sep => nil}%>' –

+2

विल्सन की टिप्पणी में जोड़ने के लिए, हेरोकू (देवदार स्टैक-बीटा) सीएसवी फाइलों में रिक्त रेखाएं डालेगा जबतक कि आप इसे स्पष्ट रूप से नहीं बताते ': row_sep => nil' के साथ। – nslocum

2

निम्नलिखित मेरे मामले के लिए अच्छी तरह से काम से संपर्क किया और डाउनलोड करने के बाद सीएसवी प्रकार के लिए उपयुक्त आवेदन खोलने के लिए ब्राउज़र का कारण बनता है।

def index 
    respond_to do |format| 
    format.csv { return index_csv } 
    end 
end 

def index_csv 
    send_data(
    method_that_returns_csv_data(...), 
    :type => 'text/csv', 
    :filename => 'export.csv', 
    :disposition => 'attachment' 
) 
end 
1
+1

अच्छा जवाब लेकिन इसे महान बनाने के लिए, शायद आप यह समझा सकते हैं कि यह मणि क्यों है (दूसरों के विपरीत) –

0

से CSV उत्पन्न करने के लिए एक अच्छा मणि कोशिश सीएसवी शेपर मणि पर एक नजर डालें।

https://github.com/paulspringett/csv_shaper

एक अच्छा डीएसएल है और रेल मॉडल के साथ बहुत अच्छी तरह से काम करता है। यह प्रतिक्रिया शीर्षकों को भी संभालता है और फ़ाइल नाम अनुकूलन की अनुमति देता है।

0

आप बस कंसोल से सीएसवी डेटाबेस खुद को पाने के लिए चाहते हैं, तो आप कुछ लाइनें

tags = [Model.column_names] 
rows = tags + Model.all.map(&:attributes).map(&:to_a).map { |m| m.inject([]) { |data, pair| data << pair.last } } 
File.open("ss.csv", "w") {|f| f.write(rows.inject([]) { |csv, row| csv << CSV.generate_line(row) }.join(""))} 
संबंधित मुद्दे