Go excelize 根据模版生成excel

96 min read
package main
 
import (
	"bufio"
	"fmt"
	"io"
	"math"
	"os"
	"regexp"
 
	//"strconv"
	"strings"
	"time"
 
	"github.com/360EntSecGroup-Skylar/excelize"
)
 
var tmp string
 
func now() string {
	n := time.Now()
	return n.Format("2006-01-02 15:04:05") //go语言诞生的时间
}
 
func getAxisY(count int) string {
	arr := [27]string{"", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}
 
	mod := count % 26
	divisor := int(math.Floor(float64(count) / 26))
	if mod == 0 && divisor > 0 {
		mod = 26
		divisor -= 1
	}
 
	return arr[divisor] + arr[mod]
}
 
func isDir(path string) bool {
	s, err := os.Stat(path)
	if err != nil {
		return false
	}
	return s.IsDir()
}
 
//自己编写一个函数,接收两个文件路径
func CopyFile(dstFileName string, srcFileName string) (written int64, err error) {
	srcFile, err := os.Open(srcFileName)
	if err != nil {
		fmt.Printf("open file err=%v\n", err)
	}
	defer srcFile.Close()
 
	//通过srcfile,找到Reader
	reader := bufio.NewReader(srcFile)
	//打开dstFileName
	dstFile, err := os.OpenFile(dstFileName, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		fmt.Printf("open file err=%v\n", err)
		return
	}
	//通过dstFile,找到Writer
	writer := bufio.NewWriter(dstFile)
	defer dstFile.Close()
	return io.Copy(writer, reader)
}
 
func mission() bool {
	pwd, _ := os.Getwd()
	_, err := os.Stat(pwd + "\\模板.xlsx")
	if !os.IsNotExist(err) { //读取到模板
		fmt.Println("载入模板...")
 
		_, err := os.Stat(pwd + "\\数据.xlsx")
		if !os.IsNotExist(err) { //读取到数据
			fmt.Println("载入数据...")
			dataxlsx, err := excelize.OpenFile(pwd + "\\数据.xlsx")
			if err != nil {
				fmt.Println(err)
			}
			sheetname := dataxlsx.GetSheetName(dataxlsx.GetActiveSheetIndex())
			rows, _ := dataxlsx.GetRows(sheetname)
			positions := rows[0]
			// for k, v := range positions {
			// 	match, _ := regexp.MatchString("^[a-zA-Z]+[0-9]+$", v)
			// 	if !match {
			// 		fmt.Println("【数据.xlsx第一行中的第" + getAxisY(k+1) + "列位置填写格式错误,请重新检查】...")
			// 		return true
			// 	}
			// }
			reg := regexp.MustCompile(`[\/\\\:\*\?\"\<\>\|]`) //去掉不能用来作为文件或文件夹名的符号
			output := pwd + "\\output" + reg.ReplaceAllString(now(), "_")
			if !isDir(output) {
				err := os.Mkdir(output, os.ModePerm)
				if err != nil {
					fmt.Println(err)
				}
			}
			for row := 1; row < len(rows); row++ {
				if len(rows[row]) == 0 || reg.ReplaceAllString(rows[row][0], "_") == "" {
					continue
				}
				filename := output + "\\" + reg.ReplaceAllString(rows[row][0], "_") + ".xlsx"
				CopyFile(filename, pwd+"\\模板.xlsx")
				currentxlsx, err := excelize.OpenFile(filename)
				if err != nil {
					fmt.Println(err)
				}
				sheetname = currentxlsx.GetSheetName(currentxlsx.GetActiveSheetIndex())
 
				for col, value := range rows[row] {
					match, _ := regexp.MatchString("^[a-zA-Z]+[0-9]+$", positions[col])
					if match {
						currentxlsx.SetCellStr(sheetname, strings.ToUpper(positions[col]), value)
					}
 
				}
				currentxlsx.Save()
				//fmt.Println(now() + " 第" + strconv.Itoa(row) + "个表填写完成,共" + strconv.Itoa(len(rows)-1) + "个...")
			}
 
		} else {
			fmt.Println("读取不到数据,请将你要处理的excel数据命名为【数据.xlsx】并放到exe同路径下...")
			return true
		}
	} else {
		fmt.Println("读取不到模板,请将你要处理的excel模板命名为【模板.xlsx】并放到exe同路径下...")
		return true
	}
	return true
}
 
func main() {
	fmt.Println(now() + " 任务开始...")
	mission()
 
	fmt.Println(now() + " 任务完成,请按回车键退出...")
	fmt.Scanln(&tmp)
}