Тип csv.Writer

Тип csv.Writer используется для записи данных в формате CSV (Comma-Separated Values). Он принимает данные в виде слайса строк и записывает их в переданный объект io.Writer. При записи автоматически добавляются разделители полей, а при необходимости - экранирование специальных символов. Основные параметры: разделитель полей (по умолчанию запятая) и символ переноса строки.

Создание экземпляра

Для создания нового csv.Writer используется функция csv.NewWriter, которая принимает объект, реализующий интерфейс io.Writer.

gopackage main

import (
  "encoding/csv"
  "os"
)

func main() {
  file, err := os.Create("data.csv")
  if err != nil {
    panic(err)
  }
  defer file.Close()

  writer := csv.NewWriter(file)
  defer writer.Flush()
}

Настройка разделителя

По умолчанию csv.Writer использует запятую в качестве разделителя полей. Его можно изменить, установив поле Comma:

gopackage main

import (
  "encoding/csv"
  "os"
)

func main() {
  writer := csv.NewWriter(os.Stdout)
  writer.Comma = ';'
  defer writer.Flush()
}

Метод Write для записи одной строки

Метод Write записывает одну запись (строку) в виде слайса строк. Он возвращает ошибку, если запись не удалась:

gopackage main

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

func main() {
  writer := csv.NewWriter(os.Stdout)
  defer writer.Flush()

  record := []string{"John", "Doe", "30"}
  err := writer.Write(record)
  if err != nil {
    fmt.Println("Error writing record:", err)
  }
}

Результат выполнения кода:

goJohn,Doe,30

Метод WriteAll для записи нескольких строк

Метод WriteAll записывает сразу несколько записей. Он принимает слайс слайсов строк и автоматически вызывает Flush после записи:

gopackage main

import (
  "encoding/csv"
  "os"
)

func main() {
  writer := csv.NewWriter(os.Stdout)
  writer.Comma = ','

  records := [][]string{
    {"Name", "City", "Age"},
    {"Alice", "New York", "25"},
    {"Bob", "Los Angeles", "30"},
  }

  err := writer.WriteAll(records)
  if err != nil {
    panic(err)
  }
}

Результат выполнения кода:

goName,City,Age
Alice,New York,25
Bob,Los Angeles,30

Экранирование специальных символов

Если поле содержит разделитель, кавычки или символ новой строки, csv.Writer автоматически экранирует его, заключая в двойные кавычки:

gopackage main

import (
  "encoding/csv"
  "os"
)

func main() {
  writer := csv.NewWriter(os.Stdout)
  defer writer.Flush()

  record := []string{"Smith, John", `He said "Hello"`, "New\nLine"}
  err := writer.Write(record)
  if err != nil {
    panic(err)
  }
}

Результат выполнения кода:

go"Smith, John","He said ""Hello""","New
Line"

Принудительная запись буфера

Метод Flush принудительно записывает все данные из внутреннего буфера. Всегда вызывайте его после завершения записи, чтобы убедиться, что все данные были записаны в целевой поток:

gopackage main

import (
  "encoding/csv"
  "os"
)

func main() {
  writer := csv.NewWriter(os.Stdout)
  writer.Write([]string{"a", "b", "c"})
  writer.Write([]string{"1", "2", "3"})
  writer.Flush()

  err := writer.Error()
  if err != nil {
    panic(err)
  }
}

Результат выполнения кода:

goa,b,c
1,2,3

Обработка ошибок при записи

После вызова Flush можно проверить наличие ошибок с помощью метода Error. Он возвращает последнюю произошедшую ошибку:

gopackage main

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

func main() {
  writer := csv.NewWriter(os.Stdout)
  writer.Write([]string{"test"})
  writer.Flush()

  if err := writer.Error(); err != nil {
    fmt.Println("CSV error:", err)
  }
}

Смотрите также

  • тип csv.Reader,
    который используется для чтения CSV-данных
  • функцию csv.NewWriter,
    создающую новый экземпляр csv.Writer
  • метод csv.Writer.Write,
    записывающий одну CSV-запись
  • метод csv.Writer.WriteAll,
    записывающий все записи из переданного слайса