xlsx

作者: 次序 | 来源:发表于2020-07-19 11:23 被阅读0次
    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()
    }
    

    相关文章

      网友评论

          本文标题:xlsx

          本文链接:https://www.haomeiwen.com/subject/xaylkktx.html