优化结构
This commit is contained in:
@@ -1,163 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/xuri/excelize/v2"
|
||||
)
|
||||
|
||||
func templateColumns(raw string) ([]string, map[string]string, error) {
|
||||
labels := map[string]string{}
|
||||
decoder := json.NewDecoder(strings.NewReader(raw))
|
||||
token, err := decoder.Token()
|
||||
if err != nil || token != json.Delim('{') {
|
||||
return nil, nil, err
|
||||
}
|
||||
keys := make([]string, 0)
|
||||
for decoder.More() {
|
||||
keyToken, tokenErr := decoder.Token()
|
||||
if tokenErr != nil {
|
||||
return nil, nil, tokenErr
|
||||
}
|
||||
key := keyToken.(string)
|
||||
var label string
|
||||
if tokenErr = decoder.Decode(&label); tokenErr != nil {
|
||||
return nil, nil, tokenErr
|
||||
}
|
||||
keys = append(keys, key)
|
||||
labels[key] = label
|
||||
}
|
||||
if _, err = decoder.Token(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return keys, labels, nil
|
||||
}
|
||||
func (s *ExportService) Export(ctx context.Context, tid string, params map[string]string) ([]byte, string, error) {
|
||||
template, err := s.uc.FindExportTemplate(ctx, 0, tid)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
rows, _, err := s.uc.QueryExport(ctx, template, params)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
keys, labels, err := templateColumns(template.TemplateInfo)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
file := excelize.NewFile()
|
||||
sheet := file.GetSheetName(0)
|
||||
for column, key := range keys {
|
||||
cell, _ := excelize.CoordinatesToCellName(column+1, 1)
|
||||
_ = file.SetCellValue(sheet, cell, labels[key])
|
||||
}
|
||||
for rowIndex, row := range rows {
|
||||
for column, key := range keys {
|
||||
cell, _ := excelize.CoordinatesToCellName(column+1, rowIndex+2)
|
||||
lookup := strings.ReplaceAll(strings.ReplaceAll(key, `"`, ""), "`", "")
|
||||
if len(template.Joins) > 0 {
|
||||
if parts := strings.Split(lookup, " as "); len(parts) > 1 {
|
||||
lookup = strings.TrimSpace(parts[1])
|
||||
} else if parts = strings.Split(lookup, "."); len(parts) > 1 {
|
||||
lookup = parts[1]
|
||||
}
|
||||
}
|
||||
value := fmt.Sprintf("%v", row[lookup])
|
||||
if timestamp, ok := row[lookup].(time.Time); ok {
|
||||
value = timestamp.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
if number, parseErr := strconv.ParseFloat(value, 64); parseErr == nil {
|
||||
_ = file.SetCellValue(sheet, cell, number)
|
||||
} else {
|
||||
_ = file.SetCellValue(sheet, cell, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
buffer, err := file.WriteToBuffer()
|
||||
_ = file.Close()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return buffer.Bytes(), template.Name + ".xlsx", nil
|
||||
}
|
||||
func (s *ExportService) ExportBlankTemplate(ctx context.Context, tid string) ([]byte, string, error) {
|
||||
template, err := s.uc.FindExportTemplate(ctx, 0, tid)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
keys, labels, err := templateColumns(template.TemplateInfo)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
file := excelize.NewFile()
|
||||
sheet := file.GetSheetName(0)
|
||||
for column, key := range keys {
|
||||
cell, _ := excelize.CoordinatesToCellName(column+1, 1)
|
||||
_ = file.SetCellValue(sheet, cell, labels[key])
|
||||
}
|
||||
buffer, err := file.WriteToBuffer()
|
||||
_ = file.Close()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return buffer.Bytes(), template.Name + "_template.xlsx", nil
|
||||
}
|
||||
func (s *ExportService) Preview(ctx context.Context, tid string, params map[string]string) (string, error) {
|
||||
template, err := s.uc.FindExportTemplate(ctx, 0, tid)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return s.uc.PreviewExport(ctx, template, params)
|
||||
}
|
||||
func (s *ExportService) Import(ctx context.Context, tid string, reader io.Reader) error {
|
||||
template, err := s.uc.FindExportTemplate(ctx, 0, tid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
file, err := excelize.OpenReader(reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
rows, err := file.GetRows("Sheet1")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(rows) < 2 {
|
||||
return errors.New("Excel data is not enough.\nIt should contain title row and data")
|
||||
}
|
||||
keys, labels, err := templateColumns(template.TemplateInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reverse := map[string]string{}
|
||||
for _, key := range keys {
|
||||
reverse[labels[key]] = key
|
||||
}
|
||||
headers := rows[0]
|
||||
for index := range headers {
|
||||
headers[index] = strings.TrimSpace(headers[index])
|
||||
}
|
||||
items := make([]map[string]any, 0, len(rows)-1)
|
||||
for _, row := range rows[1:] {
|
||||
item := map[string]any{}
|
||||
for column, value := range row {
|
||||
if column >= len(headers) {
|
||||
continue
|
||||
}
|
||||
key := reverse[headers[column]]
|
||||
if key != "" {
|
||||
item[key] = value
|
||||
}
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
return s.uc.ImportExportRows(ctx, template, items)
|
||||
}
|
||||
Reference in New Issue
Block a user