package utils import ( "encoding/csv" "os" "strings" ) // ReadCSV reads a CSV file and returns its contents as a slice of string slices func ReadCSV(filename string) ([][]string, error) { file, err := os.Open(filename) if err != nil { return nil, err } defer file.Close() reader := csv.NewReader(file) return reader.ReadAll() } // WriteCSV writes a slice of string slices to a CSV file func WriteCSV(filename string, data [][]string) error { file, err := os.Create(filename) if err != nil { return err } defer file.Close() writer := csv.NewWriter(file) defer writer.Flush() return writer.WriteAll(data) } // ReadCSVFromBytes reads CSV data from a byte slice func ReadCSVFromBytes(data []byte) ([][]string, error) { reader := csv.NewReader(strings.NewReader(string(data))) return reader.ReadAll() } // CSVToMap converts CSV data to a map of maps for easier access // The first row is assumed to be headers func CSVToMap(data [][]string) ([]map[string]string, error) { if len(data) < 2 { return nil, nil // No data or just headers } headers := data[0] result := make([]map[string]string, 0, len(data)-1) for i := 1; i < len(data); i++ { row := data[i] if len(row) == 0 { continue // Skip empty rows } rowMap := make(map[string]string) for j, value := range row { if j < len(headers) { rowMap[headers[j]] = value } } result = append(result, rowMap) } return result, nil }