[RUBY] Implementieren Sie die CSV-Download-Funktion in Rails

Hintergrund

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

Erklärung 1: bom

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.

Erläuterung 2: self.response_body

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.

Kommentar 3: Enumerator.new

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

Erläuterung 4: to_csv

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"]

Erläuterung 5: Schlüsselwortargumente

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.

Kommentar 6: self.response.headers

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,

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

Zusammenfassung

... 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: Image from Gyazo

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

Implementieren Sie die CSV-Download-Funktion in Rails
Implementieren Sie die Anwendungsfunktion in Rails
Markdown in Rails implementiert
[Schienen] Implementieren Sie die Benutzersuchfunktion
Implementieren Sie die LTI-Authentifizierung in Rails
[Rails] Implementieren Sie die Image-Posting-Funktion
Implementieren Sie die Nachsuchfunktion in der Rails-Anwendung (where-Methode).
[Rails] Implementieren Sie die Registrierungs- / Löschfunktion für Kreditkarten in PAY.JP
[Rails] Implementierung der CSV-Importfunktion
Fügen Sie eine Suchfunktion in Rails hinzu.
[Rails] Implementierung der CSV-Exportfunktion
Implementieren Sie die Anmeldefunktion in Rails einfach mit Name und Passwort (1)
Implementieren Sie die Anmeldefunktion in Rails einfach mit nur einem Namen und einem Passwort (2).
[Ruby on Rails] CSV-Ausgabefunktion
Implementieren Sie die PHP-Implodierungsfunktion in Java
Implementieren Sie ein Kontaktformular in Rails
Implementieren Sie die Anmeldefunktion in Rails einfach mit Name und Passwort (3).
Implementieren Sie die Benutzerregistrierungsfunktion und die Unternehmensregistrierungsfunktion separat in Rails devise
[Rails] Eine einfache Möglichkeit, eine Selbsteinführungsfunktion in Ihrem Profil zu implementieren
Ich habe versucht, die Ajax-Verarbeitung der ähnlichen Funktion in Rails zu implementieren
Rails 6 (standardmäßig mit Webpacker) implementiert die Sternebewertungsfunktion
So implementieren Sie Suchfunktionen in Rails
[Rails] Funktionseinschränkungen im Gerät (Login / Logout)
So implementieren Sie Ranking-Funktionen in Rails
Implementieren Sie Schaltflächenübergänge mit link_to in Rails
Schienen CSV Basic
Implementieren Sie die Rails-Paginierung
[Schienen] Kategoriefunktion
Group_by in Rails
[Rails] Benachrichtigungsfunktion
Erstellen Sie die Authentifizierungsfunktion in der Rails-Anwendung mit devise
Implementieren Sie eine Freigabeschaltfläche in Rails 6, ohne Gem zu verwenden
Passen Sie die Ausgabe mit Wagbys CSV-Download-Funktion an
So implementieren Sie eine ähnliche Funktion in Rails
Implementieren Sie Iterationen in View, indem Sie eine Sammlung rendern [Rails]
Einfache Benachrichtigungsfunktion in Rails (nur wenn befolgt)
So implementieren Sie eine nette Funktion in Ajax mit Rails
Modellassoziation in Rails
Hinzufügen von Spalten in Rails
Führen Sie devise with Rails ein, um Benutzerverwaltungsfunktionen zu implementieren
Deaktivieren Sie Turbolinks in Schienen
[Rails] Tag-Ranking-Funktion
Rails-Konto-BAN implementieren
[Ruby on Rails] Post-Bildvorschau-Funktion in Refile
Ich möchte eine Funktion in der Rails Console definieren
^, $ im regulären Ausdruck von Rails