128 lines
1.9 KiB
Go
128 lines
1.9 KiB
Go
package export
|
|
|
|
import (
|
|
"bufio"
|
|
"encoding/csv"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"reflect"
|
|
)
|
|
|
|
type Csv struct {
|
|
fc *os.File
|
|
csv *csv.Writer
|
|
f *File
|
|
isNew bool
|
|
titles []string
|
|
}
|
|
|
|
func NewCsv(fileName string, param map[string]string) *Csv {
|
|
return &Csv{
|
|
f: NewFile(fileName, 100000000, param),
|
|
}
|
|
}
|
|
|
|
func (e *Csv) slice() {
|
|
if e.f.slice() {
|
|
e.reset()
|
|
}
|
|
}
|
|
|
|
func (e *Csv) SetParam(param map[string]string) {
|
|
e.f.param = param
|
|
}
|
|
|
|
func (e *Csv) reset() {
|
|
e.save()
|
|
e.f.NextFile()
|
|
e.Open()
|
|
e.WriteTitle(nil)
|
|
e.slice()
|
|
}
|
|
|
|
func (e *Csv) Open() error {
|
|
var err error
|
|
if e.f.IsFileExist() {
|
|
e.fc, err = os.OpenFile(e.f.FileName(), os.O_APPEND|os.O_WRONLY, 0644)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
e.f.SetRow(e.getLineCount(e.fc))
|
|
} else {
|
|
e.isNew = true
|
|
e.fc, err = os.Create(e.f.FileName())
|
|
}
|
|
|
|
if err == nil {
|
|
e.csv = csv.NewWriter(e.fc)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (e *Csv) getLineCount(file io.Reader) (line int) {
|
|
reader := bufio.NewReader(file)
|
|
line = 0
|
|
for {
|
|
_, isPrefix, err := reader.ReadLine()
|
|
if err != nil {
|
|
break
|
|
}
|
|
if !isPrefix {
|
|
line++
|
|
}
|
|
}
|
|
return line
|
|
}
|
|
|
|
func (e *Csv) save() error {
|
|
e.csv.Flush()
|
|
e.fc.Close()
|
|
return nil
|
|
}
|
|
|
|
func (e *Csv) WriteTitle(titles []string) error {
|
|
|
|
if titles != nil {
|
|
e.titles = titles
|
|
}
|
|
|
|
if e.titles != nil && e.isNew {
|
|
e.Write(e.titles)
|
|
e.isNew = false
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (e *Csv) Write(data interface{}) error {
|
|
if e.f.slice() {
|
|
e.reset()
|
|
}
|
|
|
|
v := reflect.ValueOf(data)
|
|
if v.Kind() == reflect.Ptr {
|
|
v = v.Elem()
|
|
}
|
|
if v.Kind() != reflect.Slice {
|
|
return errors.New("数据无效,不是切片类型")
|
|
}
|
|
|
|
switch val := data.(type) {
|
|
case []string:
|
|
return e.csv.Write(val)
|
|
case []interface{}:
|
|
strs := make([]string, len(val))
|
|
for i, v := range val {
|
|
strs[i] = fmt.Sprintf("%v", v)
|
|
}
|
|
return e.csv.Write(strs)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (e *Csv) Close() error {
|
|
return e.save()
|
|
}
|