ReadCSV reads a table from a comma-separated-values (CSV) file (where comma = any delimiter, specified in the delim arg), using the Go standard encoding/csv reader conforming to the official CSV standard. If the table does not currently have any columns, the first row of the file is assumed to be he
(r io.Reader, delim Delims)
| 158 | // If the table DOES have existing columns, then those are used robustly |
| 159 | // for whatever information fits from each row of the file. |
| 160 | func (dt *Table) ReadCSV(r io.Reader, delim Delims) error { |
| 161 | cr := csv.NewReader(r) |
| 162 | cr.Comma = delim.Rune() |
| 163 | rec, err := cr.ReadAll() // todo: lazy, avoid resizing |
| 164 | if err != nil || len(rec) == 0 { |
| 165 | return err |
| 166 | } |
| 167 | rows := len(rec) |
| 168 | // cols := len(rec[0]) |
| 169 | strow := 0 |
| 170 | if dt.NumColumns() == 0 || DetectTableHeaders(rec[0]) { |
| 171 | dt.DeleteAll() |
| 172 | err := ConfigFromHeaders(dt, rec[0], rec) |
| 173 | if err != nil { |
| 174 | log.Println(err.Error()) |
| 175 | return err |
| 176 | } |
| 177 | strow++ |
| 178 | rows-- |
| 179 | } |
| 180 | dt.SetNumRows(rows) |
| 181 | for ri := 0; ri < rows; ri++ { |
| 182 | dt.ReadCSVRow(rec[ri+strow], ri) |
| 183 | } |
| 184 | return nil |
| 185 | } |
| 186 | |
| 187 | // ReadCSVRow reads a record of CSV data into given row in table |
| 188 | func (dt *Table) ReadCSVRow(rec []string, row int) { |