56 lines
1.3 KiB
Go
56 lines
1.3 KiB
Go
package csv
|
|
|
|
import (
|
|
"context"
|
|
"encoding/csv"
|
|
"fmt"
|
|
"io"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/evcc-io/evcc/util/export"
|
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
|
)
|
|
|
|
// rowWriter renders typed cells as locale-independent strings
|
|
type rowWriter struct {
|
|
*csv.Writer
|
|
localizer *i18n.Localizer
|
|
}
|
|
|
|
func (w rowWriter) Localizer() *i18n.Localizer { return w.localizer }
|
|
|
|
func (w rowWriter) Write(record []any) error {
|
|
row := make([]string, len(record))
|
|
for i, v := range record {
|
|
switch v := v.(type) {
|
|
case nil:
|
|
row[i] = ""
|
|
case float64:
|
|
row[i] = strconv.FormatFloat(v, 'f', -1, 64)
|
|
case time.Time:
|
|
row[i] = v.Format("2006-01-02 15:04:05")
|
|
default:
|
|
row[i] = fmt.Sprintf("%v", v)
|
|
}
|
|
}
|
|
return w.Writer.Write(row)
|
|
}
|
|
|
|
// New writes a UTF-8 BOM and returns a csv row writer. The context locale only affects header captions.
|
|
func New(ctx context.Context, w io.Writer) (export.RowWriter, error) {
|
|
if _, err := w.Write([]byte{0xEF, 0xBB, 0xBF}); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return rowWriter{csv.NewWriter(w), export.Localizer(ctx)}, nil
|
|
}
|
|
|
|
// WriteStructSlice writes a slice of structs to CSV with localized headers.
|
|
func WriteStructSlice(ctx context.Context, w io.Writer, slice any, cfg export.Config) error {
|
|
ww, err := New(ctx, w)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return export.WriteStructSlice(ww, slice, cfg)
|
|
}
|