Wir haben uns entschlossen, die CSV-Download-Funktion in Rails zu implementieren. Es gibt bereits viele einfache und hervorragende Beispiele für Qiita, und wenn Sie sich die Artikel hier ansehen, können Sie sie leicht implementieren.
Die CSV-Ausgabefunktion, die ich bei der Arbeit gefunden habe, war viel komplizierter als diese. Deshalb habe ich beschlossen, sie zu implementieren, während ich untersuchte, was ich dachte: "Was ist dieser Mechanismus?" .. Grundsätzlich ist es in der Nähe des zweiten oben eingeführten Artikels.
Die Rails-Version ist 5.2.4.2
.
controller
Die Steuerung entspricht fast dem oben vorgestellten Artikel. Das Format ist in HTML und CSV unterteilt. Wenn eine Anforderung im CSV-Format vorliegt, wird die Methode aufgerufen, mit der CSV erstellt wird.
controllers/somethings_controller.rb
class SomethingsController < ApplicationController
include SomeCsvModule #Ich werde es definieren
def index
@somethings = Something.all
respond_to do |format|
format.html
format.csv do
generate_csv(@somethings) #Ich werde es definieren
end
end
end
end
view
Die Ansicht ist sehr einfach, installieren Sie einfach eine Schaltfläche mit format :: csv
^^.
ruby:views/somethings/index.html.haml
= link_to "CSV herunterladen", somethings_path(format: :csv)
module Das Geheimnis dieser einfachen Ansicht und Steuerung lag im Modul. Da es sich um eine gemeinsame Methode für verschiedene Controller handelt, haben wir in "controller / concerts /" ein gemeinsames Modul definiert.
/controllers/concerns/some_csv_module.rb
module SomeCsvModule
extend ActiveSupport::Concern
def generate_csv(somethings)
filename = "Informationsliste_#{Date.today}.csv"
set_csv_request_headers(filename)
bom = "\uFEFF" #Ich werde erklären(1)
self.response_body = Enumerator.new do |csv_data| #Ich werde erklären(2.3)
csv_data << bom
header = %i(ID Name Inhalt)
csv_data << header.to_csv #Ich werde erklären(4)
somethings.each do |some|
body = [
some.id,
some.name,
some.content
]
csv_data << body.to_csv
end
end
end
def set_csv_request_headers(filename, charset: 'UTF-8') #Ich werde erklären(5)
#↓ Ich werde erklären(6)
self.response.headers['Content-Type'] ||= "text/csv; charset=#{charset}"
self.response.headers['Content-Disposition'] = "attachment;filename=#{ERB::Util.url_encode(filename)}"
self.response.headers['Content-Transfer-Encoding'] = 'binary'
end
end
Stückliste ist eine Abkürzung für "Byte Order Mark", eine kurze Zeichenfolge am Anfang eines in "Unicode" geschriebenen Dokuments. Diese Zeichenfolge beschreibt die Codierungsmethode des Dokuments.
Der Standardzeichencode von Excel ist "Shift-JIS" und die Welt von WEB ist "UTF-8". Wenn Sie also versuchen, die CSV-Ausgabedaten mit der WEB-Anwendung in Excel zu öffnen, werden die Zeichen definitiv verstümmelt.
Sie können verstümmelte Zeichen verhindern, indem Sie am Anfang des Dokuments "bom" mitteilen, dass der Zeichencode dieses Dokuments "UTF-8" lautet.
In diesem Modul definieren wir "bom =" \ uFEFF "" und fügen "bom" am Anfang der Daten zu Beginn des nachfolgenden Prozesses zur Erstellung von CSV-Daten hinzu.
Darüber hinaus wird die Erläuterung dieses Teils unter Bezugnahme auf diese beiden Artikel erstellt.
Ich habe den Teil "self.response_body" überprüft, aber ich habe ihn nicht gut verstanden ... Es tut uns leid. Wenn Sie jedoch aus den Artikeln hier raten ...
Der Teil, der die Ansicht definiert, die Rails rendert, scheint "self.response_body" zu sein. Der Standardwert ist "Null". Sie können eine Ansicht zum Rendern erstellen, indem Sie "self.response_body" einen Wert zuweisen.
Enumerator.new
scheint eine " Array-Element erstellen " -Methode zu sein, soweit ich dies anhand des folgenden Artikels überprüft habe.
▼ Referenz
Dieser Teil des obigen Codes
self.response_body = Enumerator.new do |csv_data|
csv_data << bom
header = %i(ID Name Inhalt)
csv_data << header.to_csv
somethings.each do |some|
body = [
#Unterlassung
]
csv_data << body.to_csv
end
end
Es war das gleiche wie dieses.
csv_data = []
csv_data << bom
header = %i(ID Name Inhalt)
csv_data << header.to_csv
somethings.each do |some|
body = [
#Unterlassung
]
csv_data << body.to_csv
end
self.response_body = csv_data
to_csv
ist eine Methode der CSV-Bibliothek, die ein Array in das CSV-Format zu konvertieren scheint. Unten finden Sie den aus diesem Dokument zitierten Code.
require 'csv'
csv_string = ["CSV", "data"].to_csv # => "CSV,data"
csv_array = "CSV,String".parse_csv # => ["CSV", "String"]
Der Teil charset: 'UTF-8'
dieser Methode heißt ** Schlüsselwortargument **. Dies ist eine Möglichkeit, einen Schlüssel als Argument wie einen Hash anzugeben.
python
def set_csv_request_headers(filename, charset: 'UTF-8')
▼ Klicken Sie hier für Details
Wenn Sie es so angeben, können Sie den Wert "UTF-8" mit dem Schlüsselwort "charset" in der Methode aufrufen.
Zum Schluss hier der Teil
python
self.response.headers['Content-Type'] ||= "text/csv; charset=#{charset}"
self.response.headers['Content-Disposition'] = "attachment;filename=#{ERB::Util.url_encode(filename)}"
self.response.headers['Content-Transfer-Encoding'] = 'binary'
Gibt eine Reihe von Optionen an, die dem Antwortheader hinzugefügt werden sollen, wenn die Antwort zurückgegeben wird. Klicken Sie hier für eine Liste der Optionen.
Um jeden kurz zu erklären,
Content-Type
** ... Geben Sie den MIME-Typ des Inhalts an.Content-Disposition
** ... Geben Sie an, ob der Inhalt HTML ( inline
) oder Anhang (Anhang
) ist. Mit der Option filename =" file name "
können Sie ein Fenster zum Speichern unter (*) aufrufen.Content-Transfer-Encoding
** ... beschreibt, wie die Anforderungszeichenfolge codiert wird (Einzelheiten finden Sie hier (https: //wa3.i-). 3-i.info/word11117.html)))... es scheint. Der (*) Teil ist im offiziellen Dokument geschrieben, aber im Moment bin ich es War in diesem Umfeld nicht erfolgreich. Es tut uns leid. .. ..
... das ist es! Es hat viel Lernen gekostet, um den Mechanismus zu verstehen, aber ich habe es geschafft, die CSV-Ausgabefunktion zu implementieren ^^
▼ CSV-Ausgabetaste erstellt: sonnig:
Der Code, den ich bei der Arbeit sah, hatte noch verschiedene Optionen im Antwortheader, organisierte die Prozesse, die in einer verallgemeinerten Form geteilt werden können, und war voller Handwerkskunst, aber vor allem dies Ich werde die Form lernen und verschiedene Optionen beherrschen.
(Zunächst möchte ich einen Test dafür schreiben können ...) Ich werde mich weiterhin widmen ♪
Recommended Posts