encoding/csv.Writer în Go

Scrie fișiere CSV: Write adaugă un rând (cu ghilimele unde e nevoie), Flush trimite datele din buffer la destinație.

Sintaxă
func NewWriter(w io.Writer) *Writer
func (w *Writer) Write(record []string) error
func (w *Writer) Flush()
func (w *Writer) Error() error

// câmpuri: Comma, UseCRLF

Ce face encoding/csv.Writer

csv.NewWriter(w) creează un scriitor CSV peste un io.Writer. cw.Write(rand) scrie un rând: pune ghilimele în jurul câmpurilor care conțin separatorul, ghilimele sau rânduri noi și dublează ghilimelele din interior. Comma schimbă separatorul, iar UseCRLF folosește sfârșitul de rând Windows (\r\n).

Scriitorul ține datele într-un buffer: cw.Flush() le trimite efectiv la destinație. Fără Flush la final, ultimele rânduri (sau toate) lipsesc din fișier. Flush nu returnează eroare; verifică după el cw.Error().

Parametri

Parametru Descriere
w Destinația: fișier, os.Stdout, http.ResponseWriter.

Ce returnează

Write: o eroare. Flush: nimic. Error: eroarea de la ultima scriere sau Flush.

Exemple

Exemplul 1: Export de comenzi pe ecran

Câmpurile cu virgulă și cu ghilimele sunt puse automat între ghilimele.

package main

import (
	"encoding/csv"
	"fmt"
	"os"
)

func main() {
	cw := csv.NewWriter(os.Stdout)
	cw.Write([]string{"nr", "client", "produs", "total"})
	cw.Write([]string{"1001", "Popescu, Ana", "Cafea \"Premium\"", "89.90"})
	cw.Write([]string{"1002", "Ion Rusu", "Ceai\nverde", "14.50"})
	cw.Flush()
	if err := cw.Error(); err != nil {
		fmt.Println("eroare:", err)
	}
}

Rezultat

nr,client,produs,total
1001,"Popescu, Ana","Cafea ""Premium""",89.90
1002,Ion Rusu,"Ceai
verde",14.50

Exemplul 2: Fișier pentru Excel cu separator ;

package main

import (
	"encoding/csv"
	"fmt"
	"os"
)

type Produs struct {
	Cod  int
	Nume string
	Pret float64
}

func main() {
	produse := []Produs{{101, "Cafea boabe", 89.9}, {102, "Ceai verde", 14.5}}

	f, err := os.Create("produse.csv")
	if err != nil {
		fmt.Println(err)
		return
	}
	cw := csv.NewWriter(f)
	cw.Comma = ';'
	cw.Write([]string{"cod", "produs", "pret"})
	for _, p := range produse {
		cw.Write([]string{fmt.Sprint(p.Cod), p.Nume, fmt.Sprintf("%.2f", p.Pret)})
	}
	cw.Flush()
	f.Close()
	if err := cw.Error(); err != nil {
		fmt.Println(err)
		return
	}
	continut, _ := os.ReadFile("produse.csv")
	fmt.Print(string(continut))
}

Rezultat

cod;produs;pret
101;Cafea boabe;89.90
102;Ceai verde;14.50

Greșeli frecvente

  • Uiți Flush(): fișierul rămâne gol sau incomplet, fără nicio eroare.
  • Închizi fișierul înainte de Flush: datele din buffer nu mai au unde să ajungă.
  • Construiești rândurile cu strings.Join(campuri, ","): un nume ca „Popescu, Ana” strică coloanele.

Comenzi înrudite

  • encoding/csv.Writer.WriteAll: Scrie toate rândurile date deodată și apelează singur Flush; returnează eroarea, dacă apare.
  • encoding/csv.Reader: Citește fișiere CSV rând cu rând: NewReader creează cititorul, Read returnează următorul rând ca []string.