csv

package module
v2.24.3 Latest Latest
Warning

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

Go to latest
Published: Jul 8, 2024 License: MIT Imports: 4 Imported by: 0

README

csv GoDoc Go Report Card Coverage Status

Go CSV reader like Python's DictReader.

go get github.com/earthboundkid/csv/v2

Example

Source CSV

first_name,last_name,username
"Rob","Pike",rob
Ken,Thompson,ken
"Robert","Griesemer","gri"

User type

type User struct {
    Username string `csv:"username"`
    First    string `csv:"first_name"`
    Last     string `csv:"last_name"`
}

Scanning file

var user User
for err := range csv.Scan(csv.Options{Reader: src}, &user) {
    if err != nil {
        // Do something
    }
    fmt.Println(user.Username)
}
// Output:
// rob
// ken
// gri

Documentation

Overview

Package csv is a wrapper around encoding/csv that makes it more convenient to work with named fields of CSV tables.

Example
in := `first_name,last_name,username
"Rob","Pike",rob
Ken,Thompson,ken
"Robert","Griesemer","gri"
`
csvopt := csv.Options{
	Reader: strings.NewReader(in),
}

var user struct {
	Username string `csv:"username"`
	First    string `csv:"first_name"`
	Last     string `csv:"last_name"`
}
for err := range csv.Scan(csvopt, &user) {
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%q %s, %s\n", user.Username, user.Last, user.First)
}
Output:

"rob" Pike, Rob
"ken" Thompson, Ken
"gri" Griesemer, Robert

Index

Examples

Constants

View Source
const NULL = -1

NULL is used to override the default separator of ',' and use 0x00 as the field separator.

Variables

This section is empty.

Functions

func Scan added in v2.24.2

func Scan[T any](o Options, v *T) iter.Seq[error]

Scan returns an iterator reading from o. On each iteration it scans the row into v. See Row.Scan.

func ScanAll added in v2.24.3

func ScanAll[T any](o Options) ([]T, error)

ScanAll returns a slice of all objects read from o or an error. See Row.Scan.

Example
in := `first_name,last_name,username
"Rob","Pike",rob
Ken,Thompson,ken
"Robert","Griesemer","gri"
`
csvopt := csv.Options{
	Reader: strings.NewReader(in),
}

type user struct {
	Username string `csv:"username"`
	First    string `csv:"first_name"`
	Last     string `csv:"last_name"`
}
users, err := csv.ScanAll[user](csvopt)
if err != nil {
	log.Fatal(err)
}
fmt.Println(users)
Output:

[{rob Rob Pike} {ken Ken Thompson} {gri Robert Griesemer}]

Types

type Options

type Options struct {
	// Reader must be set
	Reader io.Reader

	// Comma is the field delimiter.
	// It is set to comma (',') by default.
	// To use 0x00 as the field separator, set it to -1
	Comma rune
	// Comment, if not 0, is the comment character. Lines beginning with the
	// Comment character without preceding whitespace are ignored.
	// With leading whitespace the Comment character becomes part of the
	// field, even if TrimLeadingSpace is true.
	Comment rune
	// If LazyQuotes is true, a quote may appear in an unquoted field and a
	// non-doubled quote may appear in a quoted field.
	LazyQuotes bool
	// If TrimLeadingSpace is true, leading white space in a field is ignored.
	// This is done even if the field delimiter, Comma, is white space.
	TrimLeadingSpace bool
	// FieldNames are the names for the fields on each row. If FieldNames is
	// left nil, it will be set to the first row read.
	FieldNames []string
}

Options is a wrapper around encoding/csv.Reader that allows look up of columns in a CSV source by field name.

Example

This example shows how csv.FieldReader can be configured to handle other types of CSV files.

in := `"Rob";"Pike";rob
# lines beginning with a # character are ignored
Ken;Thompson;ken
"Robert";"Griesemer";"gri"
`
csvopt := csv.Options{
	Reader:     strings.NewReader(in),
	Comma:      ';',
	Comment:    '#',
	FieldNames: []string{"first_name", "last_name", "username"},
}

for row, err := range csvopt.Rows() {
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(row.Field("username"))
}
Output:

rob
ken
gri

func (*Options) ReadAll

func (o *Options) ReadAll() ([]map[string]string, error)

ReadAll consumes o.Reader and returns a slice of maps for each row.

Example
in := `first_name,last_name,username
"Rob","Pike",rob
Ken,Thompson,ken
"Robert","Griesemer","gri"
`
csvopt := csv.Options{
	Reader: strings.NewReader(in),
}
rows, err := csvopt.ReadAll()
if err != nil {
	log.Fatal(err)
}
fmt.Println(rows)
Output:

[map[first_name:Rob last_name:Pike username:rob] map[first_name:Ken last_name:Thompson username:ken] map[first_name:Robert last_name:Griesemer username:gri]]

func (*Options) Rows

func (o *Options) Rows() iter.Seq2[*Row, error]

Rows returns a sequence yielding a Row for each row parsed from o.Reader. If o.Reader returns an error other than io.EOF, it will be yielded to the caller.

type Row

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

Row represents one scanned row of a CSV file. It is only valid during the current iteration.

func (*Row) Field

func (r *Row) Field(fieldname string) string

Field returns the value in the currently loaded row of the column corresponding to fieldname.

func (*Row) Fields

func (r *Row) Fields() map[string]string

Fields returns a map from fieldnames to values for the current row.

func (*Row) Scan added in v2.24.2

func (r *Row) Scan(v any)

Scan reflects on the row and sets the appropriate fields of s. If v is not a pointer to a struct, Scan will panic. The struct fields to be scanned into must be exported, of type string, and have a csv field tag with the name of the field to copy.

Jump to

Keyboard shortcuts

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