سؤال

لدي جدول قاعدة بيانات بسيط يسمى "الإدخالات":

class CreateEntries < ActiveRecord::Migration
  def self.up
    create_table :entries do |t|
      t.string :firstName
      t.string :lastName
      #etc.
      t.timestamps
    end
  end

  def self.down
    drop_table :entries
  end
end

كيف أكتب معالجًا يقوم بإرجاع محتويات جدول الإدخالات كملف CSV (من الأفضل أن يتم فتحه تلقائيًا في Excel)؟

class EntriesController < ApplicationController

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

    # ??? NOW WHAT ????

  end

end
هل كانت مفيدة؟

المحلول

يوجد مكون إضافي يسمى FasterCSV يتعامل مع هذا الأمر بشكل رائع.

نصائح أخرى

أسرعCSV هو بالتأكيد الطريق الصحيح، ولكن إذا كنت تريد تقديمه مباشرة من تطبيق Rails الخاص بك، فستحتاج إلى إعداد بعض رؤوس الاستجابة أيضًا.

أحتفظ بطريقة لإعداد اسم الملف والرؤوس الضرورية:

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.ثم عندما بحثت في Google للعثور على الجوهرة، وجدت أيضًا مثالًا كاملاً إلى حد ما على صفحة الويكي هذه.بتجميعهم معًا، استقريت على الكود التالي.

بالمناسبة، أمر تثبيت الجوهرة هو:Sudo GEM تثبيت 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:

اطلب مكتبة روبي CSV في ملف مُهيئ مثل config/initializers/dependeency.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) %>

نلقي نظرة على أسرعCSV جوهرة.

إذا كان كل ما تحتاجه هو دعم 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

تحتاج إلى تعيين رأس نوع المحتوى في إجابتك، ثم إرسال البيانات.نوع المحتوى:يجب أن يقوم application/vnd.ms-excel بالمهمة.

قد ترغب أيضًا في تعيين رأس ترتيب المحتوى بحيث يبدو كمستند Excel، ويختار المتصفح اسم ملف افتراضيًا معقولًا؛هذا شيء مثل التصرف في المحتوى:مرفق؛اسم الملف = "#{suggested_name}.xls"

أقترح استخدام Fastcsv Ruby Gem لإنشاء ملف CSV الخاص بك، ولكن هناك أيضًا ملف CSV مدمج.يبدو نموذج التعليمات البرمجية Fastcsv (من وثائق الجوهرة) كما يلي:

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

لقد نجح الأسلوب التالي بشكل جيد في حالتي وتسبب في قيام المتصفح بفتح التطبيق المناسب لنوع CSV بعد التنزيل.

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

جرب جوهرة جميلة لإنشاء ملف CSV من Railshttps://github.com/crafterm/comma

ألق نظرة على جوهرة CSV Shaper.

https://github.com/paulspringett/csv_shaper

إنه يحتوي على DSL رائع ويعمل بشكل جيد مع موديلات Rails.كما أنه يتعامل مع رؤوس الاستجابة ويسمح بتخصيص اسم الملف.

إذا كنت تريد ببساطة الحصول على قاعدة بيانات CSV بنفسك من وحدة التحكم، فيمكنك القيام بذلك في بضعة أسطر

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(""))}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top