gocsv

package
v0.1.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 12, 2023 License: MIT, MIT Imports: 13 Imported by: 2

README

Go CSV

The GoCSV package aims to provide easy serialization and deserialization functions to use CSV in Golang

API and techniques inspired from https://godoc.org/gopkg.in/mgo.v2

GoDoc Build Status

Installation

go get -u github.com/gocarina/gocsv

Full example

Consider the following CSV file


client_id,client_name,client_age
1,Jose,42
2,Daniel,26
3,Vincent,32

Easy binding in Go!


package main

import (
	"fmt"
	"os"

	"github.com/gocarina/gocsv"
)

type NotUsed struct {
	Name string
}

type Client struct { // Our example struct, you can use "-" to ignore a field
	Id            string  `csv:"client_id"`
	Name          string  `csv:"client_name"`
	Age           string  `csv:"client_age"`
	NotUsedString string  `csv:"-"`
	NotUsedStruct NotUsed `csv:"-"`
}

func main() {
	clientsFile, err := os.OpenFile("clients.csv", os.O_RDWR|os.O_CREATE, os.ModePerm)
	if err != nil {
		panic(err)
	}
	defer clientsFile.Close()

	clients := []*Client{}

	if err := gocsv.UnmarshalFile(clientsFile, &clients); err != nil { // Load clients from file
		panic(err)
	}
	for _, client := range clients {
		fmt.Println("Hello", client.Name)
	}

	if _, err := clientsFile.Seek(0, 0); err != nil { // Go to the start of the file
		panic(err)
	}

	clients = append(clients, &Client{Id: "12", Name: "John", Age: "21"}) // Add clients
	clients = append(clients, &Client{Id: "13", Name: "Fred"})
	clients = append(clients, &Client{Id: "14", Name: "James", Age: "32"})
	clients = append(clients, &Client{Id: "15", Name: "Danny"})
	csvContent, err := gocsv.MarshalString(&clients) // Get all clients as CSV string
	//err = gocsv.MarshalFile(&clients, clientsFile) // Use this to save the CSV back to the file
	if err != nil {
		panic(err)
	}
	fmt.Println(csvContent) // Display all clients as CSV string

}

Customizable Converters


type DateTime struct {
time.Time
}

// Convert the internal date as CSV string
func (date *DateTime) MarshalCSV() (string, error) {
return date.Time.Format("20060201"), nil
}

// You could also use the standard Stringer interface 
func (date *DateTime) String() (string) {
return date.String() // Redundant, just for example
}

// Convert the CSV string as internal date
func (date *DateTime) UnmarshalCSV(csv string) (err error) {
date.Time, err = time.Parse("20060201", csv)
return err
}

type Client struct { // Our example struct with a custom type (DateTime)
Id       string   `csv:"id"`
Name     string   `csv:"name"`
Employed DateTime `csv:"employed"`
}

Customizable CSV Reader / Writer


func main() {
...

gocsv.SetCSVReader(func (in io.Reader) gocsv.CSVReader {
r := csv.NewReader(in)
r.Comma = '|'
return r // Allows use pipe as delimiter
})

...

gocsv.SetCSVReader(func (in io.Reader) gocsv.CSVReader {
r := csv.NewReader(in)
r.LazyQuotes = true
r.Comma = '.'
return r // Allows use dot as delimiter and use quotes in CSV
})

...

gocsv.SetCSVReader(func (in io.Reader) gocsv.CSVReader {
//return csv.NewReader(in)
return gocsv.LazyCSVReader(in) // Allows use of quotes in CSV
})

...

gocsv.UnmarshalFile(file, &clients)

...

gocsv.SetCSVWriter(func (out io.Writer) *gocsv.SafeCSVWriter {
writer := csv.NewWriter(out)
writer.Comma = '|'
return gocsv.NewSafeCSVWriter(writer)
})

...

gocsv.MarshalFile(&clients, file)

...
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrUnmatchedStructTags = errors.New("unmatched struct tags")
	ErrDoubleHeaderNames   = errors.New("double header names")
)
View Source
var (
	ErrEmptyCSVFile = errors.New("empty csv file given")
	ErrNoStructTags = errors.New("no csv struct tags found")
)
View Source
var (
	ErrChannelIsClosed = errors.New("channel is closed")
)
View Source
var FailIfDoubleHeaderNames = false

FailIfDoubleHeaderNames indicates whether it is considered an error when a header name is repeated in the csv header.

View Source
var FailIfUnmatchedStructTags = false

FailIfUnmatchedStructTags indicates whether it is considered an error when there is an unmatched struct tag.

View Source
var FieldsCombiner = "."

FieldSeperator defines how to combine parent struct with child struct

View Source
var ShouldAlignDuplicateHeadersWithStructFieldOrder = false

ShouldAlignDuplicateHeadersWithStructFieldOrder indicates whether we should align duplicate CSV headers per their alignment in the struct definition.

View Source
var TagName = "csv"

TagName defines key in the struct field's tag to scan

View Source
var TagSeparator = ","

TagSeparator defines seperator string for multiple csv tags in struct fields

Functions

func CSVToChanMaps

func CSVToChanMaps(reader io.Reader, c chan<- map[string]string) error

CSVToChanMaps parses the CSV from the reader and send a dictionary in the chan c, using the header row as the keys.

func CSVToMap

func CSVToMap(in io.Reader) (map[string]string, error)

CSVToMap creates a simple map from a CSV of 2 columns.

func CSVToMaps

func CSVToMaps(reader io.Reader) ([]map[string]string, error)

CSVToMaps takes a reader and returns an array of dictionaries, using the header row as the keys

func Marshal

func Marshal(in interface{}, out io.Writer) (err error)

Marshal returns the CSV in writer from the interface.

func MarshalBytes

func MarshalBytes(in interface{}) (out []byte, err error)

MarshalBytes returns the CSV bytes from the interface.

func MarshalCSV

func MarshalCSV(in interface{}, out CSVWriter) (err error)

MarshalCSV returns the CSV in writer from the interface.

func MarshalCSVWithoutHeaders

func MarshalCSVWithoutHeaders(in interface{}, out CSVWriter) (err error)

MarshalCSVWithoutHeaders returns the CSV in writer from the interface.

func MarshalChan

func MarshalChan(c <-chan interface{}, out CSVWriter) error

MarshalChan returns the CSV read from the channel.

func MarshalChanWithoutHeaders

func MarshalChanWithoutHeaders(c <-chan interface{}, out CSVWriter) error

MarshalChanWithoutHeaders returns the CSV read from the channel.

func MarshalFile

func MarshalFile(in interface{}, file *os.File) (err error)

MarshalFile saves the interface as CSV in the file.

func MarshalString

func MarshalString(in interface{}) (out string, err error)

MarshalString returns the CSV string from the interface.

func MarshalStringWithoutHeaders

func MarshalStringWithoutHeaders(in interface{}) (out string, err error)

MarshalStringWithoutHeaders returns the CSV string from the interface.

func MarshalWithoutHeaders

func MarshalWithoutHeaders(in interface{}, out io.Writer) (err error)

MarshalWithoutHeaders returns the CSV in writer from the interface.

func SetCSVReader

func SetCSVReader(csvReader func(io.Reader) CSVReader)

SetCSVReader sets the CSV reader used to parse CSV.

func SetCSVWriter

func SetCSVWriter(csvWriter func(io.Writer) *SafeCSVWriter)

SetCSVWriter sets the SafeCSVWriter used to format CSV.

func SetHeaderNormalizer

func SetHeaderNormalizer(f Normalizer)

SetHeaderNormalizer sets the normalizer used to normalize struct and header field names.

func Unmarshal

func Unmarshal(in io.Reader, out interface{}) error

Unmarshal parses the CSV from the reader in the interface.

func UnmarshalBytes

func UnmarshalBytes(in []byte, out interface{}) error

UnmarshalBytes parses the CSV from the bytes in the interface.

func UnmarshalBytesToCallback

func UnmarshalBytesToCallback(in []byte, f interface{}) error

UnmarshalBytesToCallback parses the CSV from the bytes and send each value to the given func f. The func must look like func(Struct).

func UnmarshalBytesToCallbackWithError

func UnmarshalBytesToCallbackWithError(in []byte, f interface{}) error

UnmarshalBytesToCallbackWithError parses the CSV from the bytes and send each value to the given func f.

If func returns error, it will stop processing, drain the parser and propagate the error to caller.

The func must look like func(Struct) error.

func UnmarshalBytesToChan

func UnmarshalBytesToChan(in []byte, c interface{}) error

UnmarshalBytesToChan parses the CSV from the bytes and send each value in the chan c. The channel must have a concrete type.

func UnmarshalCSV

func UnmarshalCSV(in CSVReader, out interface{}) error

UnmarshalCSV parses the CSV from the reader in the interface.

func UnmarshalCSVToMap

func UnmarshalCSVToMap(in CSVReader, out interface{}) error

UnmarshalCSVToMap parses a CSV of 2 columns into a map.

func UnmarshalCSVWithoutHeaders

func UnmarshalCSVWithoutHeaders(in CSVReader, out interface{}) error

UnmarshalCSVWithoutHeaders parses a headerless CSV with passed in CSV reader

func UnmarshalDecoder

func UnmarshalDecoder(in Decoder, out interface{}) error

UnmarshalDecoder parses the CSV from the decoder in the interface

func UnmarshalDecoderToCallback

func UnmarshalDecoderToCallback(in SimpleDecoder, f interface{}) error

UnmarshalDecoderToCallback parses the CSV from the decoder and send each value to the given func f. The func must look like func(Struct).

func UnmarshalDecoderToChan

func UnmarshalDecoderToChan(in SimpleDecoder, c interface{}) error

UnmarshalDecoderToChan parses the CSV from the decoder and send each value in the chan c. The channel must have a concrete type.

func UnmarshalFile

func UnmarshalFile(in *os.File, out interface{}) error

UnmarshalFile parses the CSV from the file in the interface.

func UnmarshalFileWithErrorHandler

func UnmarshalFileWithErrorHandler(in *os.File, errHandler ErrorHandler, out interface{}) error

UnmarshalFileWithErrorHandler parses the CSV from the file in the interface.

func UnmarshalMultipartFile

func UnmarshalMultipartFile(in *multipart.File, out interface{}) error

UnmarshalMultipartFile parses the CSV from the multipart file in the interface.

func UnmarshalString

func UnmarshalString(in string, out interface{}) error

UnmarshalString parses the CSV from the string in the interface.

func UnmarshalStringToCallback

func UnmarshalStringToCallback(in string, c interface{}) (err error)

UnmarshalStringToCallback parses the CSV from the string and send each value to the given func f. The func must look like func(Struct).

func UnmarshalStringToCallbackWithError

func UnmarshalStringToCallbackWithError(in string, c interface{}) (err error)

UnmarshalStringToCallbackWithError parses the CSV from the string and send each value to the given func f.

If func returns error, it will stop processing, drain the parser and propagate the error to caller.

The func must look like func(Struct) error.

func UnmarshalStringToChan

func UnmarshalStringToChan(in string, c interface{}) error

UnmarshalStringToChan parses the CSV from the string and send each value in the chan c. The channel must have a concrete type.

func UnmarshalToCallback

func UnmarshalToCallback(in io.Reader, f interface{}) error

UnmarshalToCallback parses the CSV from the reader and send each value to the given func f. The func must look like func(Struct).

func UnmarshalToCallbackWithError

func UnmarshalToCallbackWithError(in io.Reader, f interface{}) error

UnmarshalToCallbackWithError parses the CSV from the reader and send each value to the given func f.

If func returns error, it will stop processing, drain the parser and propagate the error to caller.

The func must look like func(Struct) error.

func UnmarshalToChan

func UnmarshalToChan(in io.Reader, c interface{}) error

UnmarshalToChan parses the CSV from the reader and send each value in the chan c. The channel must have a concrete type.

func UnmarshalToChanWithErrorHandler

func UnmarshalToChanWithErrorHandler(in io.Reader, errorHandler ErrorHandler, c interface{}) error

UnmarshalToChanWithErrorHandler parses the CSV from the reader in the interface.

func UnmarshalToChanWithoutHeaders

func UnmarshalToChanWithoutHeaders(in io.Reader, c interface{}) error

UnmarshalToChanWithoutHeaders parses the CSV from the reader and send each value in the chan c. The channel must have a concrete type.

func UnmarshalWithErrorHandler

func UnmarshalWithErrorHandler(in io.Reader, errHandle ErrorHandler, out interface{}) error

Unmarshal parses the CSV from the reader in the interface.

func UnmarshalWithoutHeaders

func UnmarshalWithoutHeaders(in io.Reader, out interface{}) error

UnmarshalWithoutHeaders parses the CSV from the reader in the interface.

Types

type CSVReader

type CSVReader interface {
	Read() ([]string, error)
	ReadAll() ([][]string, error)
}

func DefaultCSVReader

func DefaultCSVReader(in io.Reader) CSVReader

DefaultCSVReader is the default CSV reader used to parse CSV (cf. csv.NewReader)

func LazyCSVReader

func LazyCSVReader(in io.Reader) CSVReader

LazyCSVReader returns a lazy CSV reader, with LazyQuotes and TrimLeadingSpace.

type CSVWriter

type CSVWriter interface {
	Write(row []string) error
	Flush()
	Error() error
}

type Decoder

type Decoder interface {
	GetCSVRows() ([][]string, error)
}

Decoder .

type ErrorHandler

type ErrorHandler func(*csv.ParseError) bool

type NoMarshalFuncError

type NoMarshalFuncError struct {
	// contains filtered or unexported fields
}

NoMarshalFuncError is the custom error type to be raised in case there is no marshal function defined on type

func (NoMarshalFuncError) Error

func (e NoMarshalFuncError) Error() string

type NoUnmarshalFuncError

type NoUnmarshalFuncError struct {
	// contains filtered or unexported fields
}

NoUnmarshalFuncError is the custom error type to be raised in case there is no unmarshal function defined on type

func (NoUnmarshalFuncError) Error

func (e NoUnmarshalFuncError) Error() string

type Normalizer

type Normalizer func(string) string

Normalizer is a function that takes and returns a string. It is applied to struct and header field values before they are compared. It can be used to alter names for comparison. For instance, you could allow case insensitive matching or convert '-' to '_'.

func DefaultNameNormalizer

func DefaultNameNormalizer() Normalizer

DefaultNameNormalizer is a nop Normalizer.

type SafeCSVWriter

type SafeCSVWriter struct {
	*csv.Writer
	// contains filtered or unexported fields
}

func DefaultCSVWriter

func DefaultCSVWriter(out io.Writer) *SafeCSVWriter

DefaultCSVWriter is the default SafeCSVWriter used to format CSV (cf. csv.NewWriter)

func NewSafeCSVWriter

func NewSafeCSVWriter(original *csv.Writer) *SafeCSVWriter

func (*SafeCSVWriter) Flush

func (w *SafeCSVWriter) Flush()

Override flush

func (*SafeCSVWriter) Write

func (w *SafeCSVWriter) Write(row []string) error

Override write

type SimpleDecoder

type SimpleDecoder interface {
	GetCSVRow() ([]string, error)
	GetCSVRows() ([][]string, error)
}

SimpleDecoder .

func NewSimpleDecoderFromCSVReader

func NewSimpleDecoderFromCSVReader(r CSVReader) SimpleDecoder

NewSimpleDecoderFromCSVReader creates a SimpleDecoder, which may be passed to the UnmarshalDecoder* family of functions, from a CSV reader. Note that encoding/csv.Reader implements CSVReader, so you can pass one of those directly here.

type TypeMarshaller

type TypeMarshaller interface {
	MarshalCSV() (string, error)
}

TypeMarshaller is implemented by any value that has a MarshalCSV method This converter is used to convert the value to it string representation

type TypeUnmarshalCSVWithFields

type TypeUnmarshalCSVWithFields interface {
	UnmarshalCSVWithFields(key, value string) error
}

TypeUnmarshalCSVWithFields can be implemented on whole structs to allow for whole structures to customized internal vs one off fields

type TypeUnmarshaller

type TypeUnmarshaller interface {
	UnmarshalCSV(string) error
}

TypeUnmarshaller is implemented by any value that has an UnmarshalCSV method This converter is used to convert a string to your value representation of that string

type Unmarshaller

type Unmarshaller struct {
	Headers []string

	MismatchedHeaders      []string
	MismatchedStructFields []string
	// contains filtered or unexported fields
}

Unmarshaller is a CSV to struct unmarshaller.

func NewUnmarshaller

func NewUnmarshaller(reader *csv.Reader, out interface{}) (*Unmarshaller, error)

NewUnmarshaller creates an unmarshaller from a csv.Reader and a struct.

func (*Unmarshaller) Read

func (um *Unmarshaller) Read() (interface{}, error)

Read returns an interface{} whose runtime type is the same as the struct that was used to create the Unmarshaller.

func (*Unmarshaller) ReadUnmatched

func (um *Unmarshaller) ReadUnmatched() (interface{}, map[string]string, error)

ReadUnmatched is same as Read(), but returns a map of the columns that didn't match a field in the struct

func (*Unmarshaller) RenormalizeHeaders

func (um *Unmarshaller) RenormalizeHeaders(headerNormalizer func([]string) []string) error

RenormalizeHeaders will remap the header names based on the headerNormalizer. This can be used to map a CSV to a struct where the CSV header names do not match in the file but a mapping is known

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL