package main
import (
"encoding/json"
"log"
"os"
"path"
"path/filepath"
"sync"
"github.com/tealeg/xlsx"
)
///////////////////////////////////////////////////////
var conf Conf
type Conf struct {
SrcDir string `json:"src"`
DstDir string `json:"dst"`
SrcG int `json:"srcg"`
DstG int `json:"dstg"`
}
///////////////////////////////////////////////////////
func Walk(p string) []string {
l := []string{}
if err := filepath.Walk(p, func(p string, f os.FileInfo, err error) error {
if f != nil && !f.IsDir() && path.Ext(p) == ".xlsx" {
l = append(l, f.Name())
}
return nil
}); err != nil {
panic(err)
}
return l
}
///////////////////////////////////////////////////////
type DictInfo struct {
Src string
Dst string
Dict map[string][]*xlsx.Cell
Excel *xlsx.File
}
var (
makeG = 1
makeC = make(chan *DictInfo, 1000)
makeWG = sync.WaitGroup{}
mergeG = 1
mergeC = make(chan *DictInfo, 1000)
mergeWG = sync.WaitGroup{}
saveG = 1
saveC = make(chan *DictInfo, 1000)
saveWG = sync.WaitGroup{}
defaultStyle = xlsx.NewStyle()
)
func Merge(f string) {
log.Println("merge file:", f)
info := &DictInfo{
Src: conf.SrcDir + f,
Dst: conf.DstDir + f,
Dict: make(map[string][]*xlsx.Cell, 32),
}
makeC <- info
}
func MakeDict() {
makeWG.Add(1)
go func() {
defer func() {
makeWG.Done()
}()
for info := range makeC {
excel, err := xlsx.OpenFile(info.Src)
if err != nil {
panic(err)
}
for _, sheet := range excel.Sheets {
for _, row := range sheet.Rows {
if len(row.Cells) > 1 {
v := []*xlsx.Cell{}
for _, c := range row.Cells[1:] {
if c.String() != "" {
v = append(v, c)
}
}
info.Dict[row.Cells[0].String()] = v
//info.Dict[row.Cells[0].String()] = row.Cells[1:]
}
}
}
mergeC <- info
}
}()
}
func MergeDict() {
mergeWG.Add(1)
go func() {
defer mergeWG.Done()
for info := range mergeC {
excel, err := xlsx.OpenFile(info.Dst)
if err != nil {
panic(err)
}
change := false
for _, sheet := range excel.Sheets {
for _, row := range sheet.Rows {
if cells, ok := info.Dict[row.Cells[0].String()]; ok {
// just copy new cell
for i := 0; i < len(cells); i++ {
if len(row.Cells)-1 > i && row.Cells[i+1].String() == "" {
*row.Cells[i+1] = *cells[i]
change = true
} else if len(row.Cells)-1 <= i {
cell := row.AddCell()
*cell = *cells[i]
change = true
}
}
}
}
}
if change {
info.Excel = excel
saveC <- info
}
}
}()
}
func SaveDict() {
saveWG.Add(1)
go func() {
defer saveWG.Done()
for info := range saveC {
// clear style
for _, sheet := range info.Excel.Sheets {
for _, row := range sheet.Rows {
for _, cell := range row.Cells {
cell.SetStyle(defaultStyle)
}
}
for _, col := range sheet.Cols {
col.SetStyle(defaultStyle)
}
}
x := &xlsx.File{
Sheet: info.Excel.Sheet,
Sheets: info.Excel.Sheets,
}
x.Save(info.Dst)
}
}()
}
func init() {
f, err := os.Open("./conf.json")
if err != nil {
panic(err)
}
err = json.NewDecoder(f).Decode(&conf)
if err != nil {
panic(err)
}
}
func main() {
for i := 0; i < makeG; i++ {
MakeDict()
}
for i := 0; i < mergeG; i++ {
MergeDict()
}
for i := 0; i < saveG; i++ {
SaveDict()
}
lf := Walk(conf.SrcDir)
for _, f := range lf {
Merge(f)
}
close(makeC)
makeWG.Wait()
close(mergeC)
mergeWG.Wait()
close(saveC)
saveWG.Wait()
}
网友评论