评卷系统 (golang 实现)

基于字符比对的评卷系统

功能:

实现了批量评卷,逐个评卷,批量回滚,逐个回滚的功能

操作Eccel答题卡,在相应位置用红色标记评阅成绩

导出成绩单到Excel表格

 

 

使用说明

一.使用方法点击当前程序所在文件夹StarCMD.bat 打开CMD

  1.打开CMD,CD到该程序所在目录,或在该程序所在目录中打开cmd
  2.在CMD中输入mark 可以查看相关提示信息
  3.批卷及生成成绩单:
    在CMD中输入 mark  mark  -src  含标准答案的成绩单文件所在的路径和文件名  -tar  目标答题卡所在目录的路径或路径\文件名
    E.g 批量评卷  mark mark -src C:\答题卡.xlsx  -tar  C:\答题卡
        逐个评卷  mark mark -src C:\答题卡.xlsx  -tar  C:\答题卡\2018022001_张三.xlsx

    推荐把含有标准答案的答题卡文件 及其含有 待评测答题卡的文件夹放在该程序所在目录
    假如含有标准答案的答题卡文件名为 A.xlsx  待评测答题卡的'文件夹'名为 AllFile 则操作更清晰一些
    E.g 批量评卷  mark mark -src A.xlsx  -tar  AllFile
        逐个评卷  mark mark -src A.xlsx  -tar  AllFile\2018022001_张三.xlsx
        
  4.回滚成绩单(清空成绩单中的批阅痕迹,还原成绩单最初模样)
    命令行输入 mark rollback 目标答题卡所在目录的路径或路径\文件名(操作方式同上)

    E.g 批量回滚   mark rollback  C:\答题卡
        在当前目录 mark rollback  AllFile
    E.g 逐个回滚   mark  rollback  C:\答题卡\2018022001_张三.xlsx
        在当前目录 mark  rollback  AllFile\2018022001_张三.xlsx

  5.提醒
    路径中不要包含空格

命令参数:
        mark -src  path\XXX.xlsx  or  XXX.xlsx  -tar  path  or  path\XXX.xlsx
        rollback   path  or  path\XXX.xlsx

二.约束

1.程序根据配置文件H3 与 答题卡文件 A1 单元格中的文字判断是否为同一类试卷

   如果配置文件中H3单元格和答题卡(含标准答题卡)的内容不一致,程序不会

   正常执行。程序配置文件请勿轻易修改,配置文件标记红色的行为数据定位行

 

  1. 答题卡请按照标准答题卡模板文件名的格式,命名
  2. 批量评卷的成绩单生成位置:学生的答题卡目录
  3. 单个评卷的成绩单生成位置:当前程序目录 A_成绩单文件夹
  4. 该程序可以通过修改配置文件,达到适配并批阅不同卷面的目的

 

 

三.截图:

 

命令行

评卷系统 (golang 实现)_第1张图片

 

单个批阅

评卷系统 (golang 实现)_第2张图片

 

批量批阅

评卷系统 (golang 实现)_第3张图片

评卷系统 (golang 实现)_第4张图片

 

 

由于控制台输出,导致程序运行效率降低(单线程很健康)

单个回滚

 

评卷系统 (golang 实现)_第5张图片

批量回滚

 

评卷系统 (golang 实现)_第6张图片

 

实现:

答题卡标准文件  姓名_学号.xlsx

 

XXXXX  
             
题号 总分  
得分            
             
             
一、选择题(请用大写字母答题)(每小题2分,共20小题40分)            
1            
2            
3            
4            
5            
6            
7            
8            
9            
10            
11            
12            
13            
14            
15            
16            
17            
18            
19            
20            
             
             
二、判断题,对的填T,错的填F (大写)(每小题1分,共20小题20分)            
21            
22            
23            
24            
25            
26            
27            
28            
29            
30            
31            
32            
33            
34            
35            
36            
37            
38            
39            
40            
             
             
三、填空题(每小题10分,共10小题20分)            
41            
42            
43            
44            
45            
46            
47            
48            
49            
50            
             
             
四、程序填空题(每空2分,共10空20分)            
51            
52            
53            
54            
55            
56            
57            
58            
59            
60            
             

 

config.xlsx

程序配置信息                  
                   
大题总数: 4 评分表位于Sheet: Sheet1 卷面总分单元格: F4 答题卡名: XXXXX    
大题题目 小题第一个答案
起始位置列(如:A)
小题第一个答案
起始位置行(如:10)
该大题中
小题总数
每小题分数 小题评分单元列
(如:C)
大题总分单元
一(题目左上角)
大题总分单元
二(评分表)
大题位于Sheet  
第一大题 B 8 20 2 C A6 B4 Sheet1  
第四大题 B 67 10 2 C A65 E4 Sheet1  
第二大题 B 31 20 1 C A29 C4 Sheet1  
第三大题 B 54 10 2 C A52 D4 Sheet1  
                   
                   
                   
                   
                   
                   
                   
                   
                   
                   
                   
纵向回滚条数: 13                
回滚单元列 回滚单元行 回滚个数 回滚后单元格样式 位于哪个Sheet表          
C 8 20 2 Sheet1          
C 31 20 1 Sheet1          
C 54 10 1 Sheet1          
C 67 10 1 Sheet1          
A 6 1 1 Sheet1          
A 29 1 1 Sheet1          
A 52 1 1 Sheet1          
A 65 1 1 Sheet1          
B 4 1 3 Sheet1          
C 4 1 3 Sheet1          
D 4 1 3 Sheet1          
E 4 1 3 Sheet1          
F 4 1 3 Sheet1          
                   

话不多说上代码

package mark
type RowLinAndValSheet struct {
	Row    int       //row
	Lin    string
	Val    string    //row:val
	Sheet  string
}

type  Key struct {
	K []RowLinAndValSheet
}

type Answers struct {
	Ans []Key
}
package mark

import (
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	"strconv"
	"strings"
	"time"
)





func main0(){
	start:=time.Now().Unix()
	var c=new(Configer)
	err11:= c.ReadConfig("./configer.xlsx")
	if err11!=nil {
		fmt.Println(err11)
	}



   srcSet,err:= ReadAnsFromFileToArray(c.Titles,"./Book.xlsx")
    if err!=nil {
  	  fmt.Println(err)
    }

	//srcSet1,err:=ReadAnsFromFileToArray(c.titles,"./Book5.xlsx")



	sss,e:= HandleMore(c.Titles,"C:/book",".xlsx",*srcSet)

	if e !=nil{
		fmt.Println(e)
	}
	//fmt.Println(sss)

	WriteStudentScoreToFile("./Score.xlsx",*sss,c.Titles)
    //fmt.Println(err)
  // fmt.Println(srcSet)

	//wrinf:=MarkOnePeople(&c.titles,srcSet,srcSet1)



	//fmt.Println()
	//
	//f,_:=excelize.OpenFile("./Book5.xlsx")
	//vv,_:=f.GetCellStyle("Sheet1","A5")
	//fmt.Println(vv)

	//err=WriteScoreToFile("./Book5.xlsx",*wrinf,c.titles)
	//if err!=nil{
	//	fmt.Println("写入失败")
	//}

   //fmt.Println("Mark:",wrinf)
   //
	//fmt.Println(c.rollback)
	//fmt.Println(c.titles)
	end:=time.Now().Unix()
	fmt.Println("用时:",end-start,"处理文件", TotalFile,"个")

	RollbackMore("C:/book",".xlsx",c.Rollback)
}



type Cell struct {
	Cel   string
	Sty   int
	Sheet string
}

type RollBack struct{
  Cell []Cell
  ExamName string
  Sheet    string
}

type Configer struct {
	Titles   Titles
	Rollback RollBack
}

func (this *Configer)ReadConfig(filename string) error {

	f,_:=excelize.OpenFile(filename)
	//读取大题总数
	cell,err:=f.GetCellValue("Sheet1","B3")
	if err!=nil {
		return err
	}
	TopicNum , err:=strconv.Atoi(cell)
	if err!=nil {
		return err
	}

	this.Titles.Tit=make([]Info,TopicNum)
	cell,err=f.GetCellValue("Sheet1","B20")
	if err!=nil {
		return err
	}
	RollBackNum , err0:=strconv.Atoi(cell)
	if err0!=nil {
		return err
	}

	this.Rollback.Cell=make([]Cell,0)


	Index:=0
	rows, err := f.GetRows("Sheet1")
	for k, row := range rows {
       if k==2{
		   this.Titles.Sheet=row[3]
       	   this.Titles.TotalScoreCell=row[5]
       	   this.Titles.ExamName=row[7]
	   }

		if k>=4 && k<4+TopicNum{

			this.Titles.Tit[Index].LinChar=row[1]
			this.Titles.Tit[Index].RowNum,err=strconv.Atoi(row[2])

			if err!=nil {
				return  err
			}

			this.Titles.Tit[Index].Total,err=strconv.Atoi(row[3])

			n,err1:=strconv.Atoi(row[4])
			if err1!=nil {
				return  err
			}
			this.Titles.Tit[Index].Reduce=-n

			this.Titles.Tit[Index].RedWriteTo=row[5]

			this.Titles.Tit[Index].Sheet=row[8]
			if err!=nil {
				return err
			}
			this.Titles.Tit[Index].TotalItemCell=[]string{row[6],row[7]}

			Index++
		}

		if k>20 && k<=20+RollBackNum {
			prevNum,err:=strconv.Atoi(row[1])
			if err!=nil {return err}

			num,err:=strconv.Atoi(row[2])
			if err!=nil {return  err}

			style,err:=strconv.Atoi(row[3])
			if err!=nil {return err}

			for n:=prevNum;n
package mark

var TotalFile=0
var Configpath="./configer/Config.xlsx"
package mark

import (
	"os"
	"strings"
)

func getStudent(file os.FileInfo,targetsuffix string)*Student{

	var student=new(Student)
	str:=file.Name()
	str=strings.ReplaceAll(str,targetsuffix,"")
	str=strings.ReplaceAll(str," ","")
	str=strings.ReplaceAll(str," ","")
	infs:=strings.Split(str,"_")
	if len(infs)!=2{
		student.Name=str
		student.Number=str
	}else{
		name:=infs[1]
		number:=infs[0]
		student.Number=number
		student.Name=name
	}
	return  student
}

package mark

import (
	"fmt"
	"strings"
)

func GetWrongAns(pinfo PaperInfo,titles Titles) string {
	str:=""
	for K,V:=range pinfo.WrInf{
		if V.WA!=nil{
			str+=fmt.Sprintf("   第%d大题 ",K+1)
		}else{
			continue
		}
		for _,v:=range V.WA{
			i:=v.Row-titles.Tit[K].RowNum
			str+=fmt.Sprintf("%d,",i+1)
		}
		str+="小题\t"
	}
	if strings.Compare(str,"")==0 {
		return ""
	}
	str+="有错误"
	return str
}
package mark

import (
	"fmt"
	"os"
	"strings"
)

func HandleMore(titles Titles,path ,targetsuffix string,src Answers) (*StudentsScore,error) {
	TotalFile=0
	f,err:=os.OpenFile(path,os.O_RDONLY,os.ModeDir)
	if err!=nil{
		return nil,err
	}
	defer f.Close()

	fileInfo,err:=f.Readdir(-1)
	if err!=nil {
		return nil,err
	}
	separator:=string(os.PathSeparator)


	//for _,file:=range fileInfo {
	//	newpath:=path+separator+file.Name()
	//	if !file.IsDir() && strings.HasSuffix(newpath,targetsuffix) {
	//		TotalFile++
	//	}
	//}


	var sss =new(StudentsScore)
	sss.ScoresInf=make([]StudentScore,0)


	Index:=1
	for _,file:=range fileInfo{
		newpath:=path+separator+file.Name()

		if !file.IsDir(){
			if strings.HasSuffix(newpath,targetsuffix) {
				targetSet,err:= ReadAnsFromFileToArray(titles,newpath)
				if err!=nil {
					return nil,err
				}
				if targetSet==nil {
					continue
				}

				wrinf:=MarkOnePeople(&titles,&src,targetSet)
				err=WriteScoreToFile(newpath,*wrinf,titles)
				if err!=nil{
					// fmt.Println("写入失败")
				}else{

				 	student:=getStudent(file,targetsuffix)
					var ss =new(StudentScore)
					ss.StudentInfo=*student
					fmt.Printf("%d\t已批阅完:%s\t%s的试卷\n",Index,student.Number,student.Name)
					ss.WrongAnswer=GetWrongAns(*wrinf,titles)
					for _,v:=range wrinf.WrInf{
						ss.Score=append(ss.Score,v.ItemScore)
					}
					ss.TotalScore=wrinf.TotalScore
					sss.ScoresInf=append(sss.ScoresInf,*ss)
					TotalFile++
					Index++
				}
			}
		}
	}

	return sss,nil
}
package mark


import "strings"

func MarkOnePeople(titles *Titles,srcAns,tarAns *Answers) *PaperInfo{
	var winf=new(PaperInfo)
	winf.WrInf=make([]WrongInfo,len(srcAns.Ans))

	for Index,Value:=range srcAns.Ans{
		for index,value:=range Value.K{
			//fmt.Println("Index:",Index,"  index:",index," val:",value)
			if strings.Compare( Clear( value.Val ) ,Clear(tarAns.Ans[Index].K[index].Val))!=0{
				winf.WrInf[Index].WA=append(
					winf.WrInf[Index].WA,
					WrongAns{Row:value.Row,Linchar:value.Lin,Reduce:titles.Tit[Index].Reduce},
				)
				winf.WrInf[Index].ItemScore+=titles.Tit[Index].Reduce
			}
		}
		winf.WrInf[Index].ItemScore=titles.Tit[Index].Total*(-titles.Tit[Index].Reduce)+winf.WrInf[Index].ItemScore
		winf.TotalScore+=winf.WrInf[Index].ItemScore

	}

	//winf.TotalScore+=titles.FullMarks
	return  winf
}
package mark

type WrongAns struct {
	Row     int
	Linchar string
	Reduce  int
}

type WrongInfo struct{
	WA    []WrongAns
	ItemScore   int
}

type PaperInfo struct {
	WrInf  []WrongInfo
	TotalScore int
}
package mark

import (
	"github.com/360EntSecGroup-Skylar/excelize"
	"strconv"
	"strings"
)

func ReadAnsFromFileToArray(titles Titles,filename string)(*Answers ,error){
	troubles:=len(titles.Tit)
	var answers *Answers=new(Answers)
	answers.Ans=make([]Key,troubles)


	f, err := excelize.OpenFile(filename)
	if err != nil {
		return nil ,err
	}

	cell,e:=f.GetCellValue(titles.Sheet,"A1")
	if e!=nil {
		return nil ,e
	}
	cell=strings.ReplaceAll(cell," ","")
	cell=strings.ReplaceAll(cell,"\t","")
	if  strings.Compare(cell,titles.ExamName)!=0{
		return nil,nil
	}

	for Index,Value:=range titles.Tit{
		for index:=Value.RowNum;index
package mark

import (
	"os"
	"strings"
)

func RollbackMore(path ,targetsuffix string,backset RollBack) error {
	TotalFile=0
	f,err:=os.OpenFile(path,os.O_RDONLY,os.ModeDir)
	if err!=nil{
		return err
	}
	defer f.Close()

	fileInfo,err:=f.Readdir(-1)
	if err!=nil {
		return err
	}
	separator:=string(os.PathSeparator)


	for _,file:=range fileInfo {
		newpath:=path+separator+file.Name()
		if !file.IsDir() && strings.HasSuffix(newpath,targetsuffix) {

			err:=RollBackOne(newpath,backset)
			if err==nil{
				TotalFile++
			}else{
				//fmt.Println(err)
				//return err
			}
		}
	}
	return nil
}
package mark

import (
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	"strings"
)

func RollBackOne(filename string,backset RollBack) error {
	fmt.Println("正在回滚:",filename)
	f, err := excelize.OpenFile(filename)
	if err != nil {
		return err
	}


	//fmt.Println(backset.Sheet)
	cell,e:=f.GetCellValue(backset.Sheet,"A1")
	if e!=nil {
		return e
	}
	cell=strings.ReplaceAll(cell," ","")
	cell=strings.ReplaceAll(cell,"\t","")
	//fmt.Println(cell,backset.ExamName)
	if  strings.Compare(cell,backset.ExamName)!=0{
		return fmt.Errorf("操作非法文件!")
	}


	for _,v:=range backset.Cell{
		//fmt.Println(v.Cel)
		f.SetCellValue(v.Sheet,v.Cel ,"")
		f.SetCellStyle(v.Sheet, v.Cel, v.Cel, v.Sty)
	}

	//fmt.Println(f.GetCellStyle("Sheet1","A3"))
	if err := f.SaveAs(filename); err != nil {
		return  err
	}

	return nil
}
package mark

type Student struct{
	Name   string
	Number string
}

type StudentScore struct{
	StudentInfo   Student
	Score         []int
	TotalScore    int
	WrongAnswer   string
}

type StudentsScore struct{
	ScoresInf  []StudentScore
}
package mark
type Info struct {
	LinChar    string  //A
	RowNum     int     //0
	Total      int     //len
	Sheet      string
	Reduce     int    //减分
	RedWriteTo     string
	TotalItemCell  []string
}

type Titles struct {
	Tit []Info
	TotalScoreCell string
	//FullMarks      int
	Sheet          string
	ExamName       string
}
package mark

import (
	"github.com/360EntSecGroup-Skylar/excelize"
	"strconv"
)

func WriteScoreToFile(filepath string , wrinf PaperInfo, titles Titles) error {
	f, err := excelize.OpenFile(filepath)
	if err != nil {
		return err
	}

	//写入扣分
	for K,V:=range wrinf.WrInf{
		for _,v:=range V.WA{
			f.SetCellValue(titles.Tit[K].Sheet,titles.Tit[K].RedWriteTo+strconv.Itoa(v.Row) ,strconv.Itoa(v.Reduce))
			if err != nil {
				//fmt.Println(err)
			}
			st,_:=f.NewStyle(`{"font":{"size":11,"color":"#FF0000"}}`)
			//fmt.Println(st)

			f.SetCellStyle(
				titles.Tit[K].Sheet,
				titles.Tit[K].RedWriteTo+strconv.Itoa(v.Row),
				titles.Tit[K].RedWriteTo+strconv.Itoa(v.Row),
				st,
			)
		}
		//写入每题总分
		for k,v:=range titles.Tit[K].TotalItemCell{
			if k==0{
				st,_:=f.NewStyle(`{"font":{"size":11,"color":"#FF0000"}}`)
				f.SetCellValue(titles.Tit[K].Sheet,v,strconv.Itoa(V.ItemScore))
				f.SetCellStyle(titles.Tit[K].Sheet,v,v, st,)
				continue
			}

			st,_:=f.NewStyle(`{"font":{"size":11,"color":"#FF0000"} ,"border":[{"type":"left","color":"#000000","style":1},{"type":"top","color":"#000000","style":1},{"type":"bottom","color":"#000000","style":1},{"type":"right","color":"#000000","style":1}]}`)

			f.SetCellValue(titles.Tit[K].Sheet,v,strconv.Itoa(V.ItemScore))
			f.SetCellStyle(
				titles.Tit[K].Sheet, v, v, st,)//4
		}
	}

	st,_:=f.NewStyle(`{"font":{"size":11,"color":"#FF0000"} ,"border":[{"type":"left","color":"#000000","style":1},{"type":"top","color":"#000000","style":1},{"type":"bottom","color":"#000000","style":1},{"type":"right","color":"#000000","style":1}]}`)

	//写入卷面总分
	f.SetCellValue(titles.Sheet,titles.TotalScoreCell,strconv.Itoa(wrinf.TotalScore))
	f.SetCellStyle(
		titles.Sheet,
		titles.TotalScoreCell,
		titles.TotalScoreCell,
		st,//4
	)

	if err := f.SaveAs(filepath); err != nil {
		return  err
	}
	return nil
}
package mark

import (
	"github.com/360EntSecGroup-Skylar/excelize"
	"strconv"
)

func WriteStudentScoreToFile(filename string,sss StudentsScore, titles Titles) error{

	f := excelize.NewFile()
	// Create a new sheet.
	index := f.NewSheet("Sheet1")
	Set:=[26]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"}


	var Map=map[int]string{1:"一", 2:"二", 3:"三", 4:"四",5:"五",6:"六",7:"七",8:"八",9:"九",10:"十",11:"十一",12:"十二",13:"十三",14:"十四",15:"十五",16:"十六",}



	ItemNum:=len(titles.Tit)
	// Set value of a cell.
	f.SetCellValue("Sheet1", "A1", "成绩单")
	f.SetCellValue("Sheet1", "A2", "学号")
	f.SetCellValue("Sheet1", "B2", "姓名")
	//f.SetCellValue("Sheet1", "D2", "第一大题")
	//f.SetCellValue("Sheet1", "E2", "第二大题")
	//f.SetCellValue("Sheet1", "F2", "第三大题")
	//f.SetCellValue("Sheet1", "G2", "第四大题")
	//f.SetCellValue("Sheet1", "H2", "总分")
	//f.SetCellValue("Sheet1", "I2", "错误题目")



	i,j:=2,1
	for ;i

主文件 

package main

import (
	"Marking/mark"
	"flag"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
	"time"
)


type CLI struct {}


func printUsage()  {

	fmt.Println(`
使用方法:
  1.打开CMD,CD到该程序所在目录,或在该程序所在目录中打开cmd
  2.在CMD中输入mark 可以查看相关提示信息
  3.批卷及生成成绩单: 
    在CMD中输入 mark  mark  -src  含标准答案的成绩单文件所在的路径和文件名  -tar  目标答题卡所在目录的路径或路径\文件名
    E.g 批量评卷  mark mark -src C:\答题卡.xlsx  -tar  C:\答题卡
        逐个评卷  mark mark -src C:\答题卡.xlsx  -tar  C:\答题卡\2018022001_张三.xlsx

    推荐把含有标准答案的答题卡文件 及其含有 待评测答题卡的文件夹放在该程序所在目录
    假如含有标准答案的答题卡文件名为 A.xlsx  待评测答题卡的'文件夹'名为 AllFile 则操作更清晰一些
    E.g 批量评卷  mark mark -src A.xlsx  -tar  AllFile
        逐个评卷  mark mark -src A.xlsx  -tar  AllFile\2018022001_张三.xlsx
        
  4.回滚成绩单(清空成绩单中的批阅痕迹,还原成绩单最初模样)
    命令行输入 mark rollback 目标答题卡所在目录的路径或路径\文件名(操作方式同上)

    E.g 批量回滚   mark rollback  C:\答题卡
        在当前目录 mark rollback  AllFile
    E.g 逐个回滚   mark  rollback  C:\答题卡\2018022001_张三.xlsx
        在当前目录 mark  rollback  AllFile\2018022001_张三.xlsx

  5.提醒
    路径中不要包含空格

命令参数:
	     mark -src  path\XXX.xlsx  or  XXX.xlsx  -tar  path  or  path\XXX.xlsx
	     rollback   path  or  path\XXX.xlsx
`)

}

func main(){
	CLI{}.Run()
}



func isValidArgs()  {
	if len(os.Args) < 2 {
		printUsage()
		os.Exit(1)
	}
}

func (cli CLI)Run(){

	isValidArgs()
	markCmd := flag.NewFlagSet("mark",flag.ExitOnError)
	rollcmd := flag.NewFlagSet("rollback",flag.ExitOnError)
	flagSrc := markCmd.String("src","","含标准答案的答题卡所在 路径\\文件名.xlsx")
	flagTar :=  markCmd.String("tar","", "待批阅的答题卡目录 或 目录\\文件名.xlsx")

	switch os.Args[1] {
	case "mark":
		err := markCmd.Parse(os.Args[2:])
		if err != nil {
			log.Panic(err)
		}
	case "rollback":
		err := rollcmd.Parse(os.Args[2:])
		if err != nil {
			log.Panic(err)
		}
	default:
		printUsage()
		os.Exit(1)
	}




	if markCmd.Parsed() {

		if *flagSrc == "" || *flagTar==""  {
			fmt.Println("-src 参数非法!")
			return
		}
		if  *flagTar==""  {
			fmt.Println("-tar 参数非法!")
			return
		}
		fmt.Println("源文件:  ",*flagSrc)
		fmt.Println("目标文件:",*flagTar)

    	handleMark(*flagSrc,*flagTar)
	}

	if rollcmd.Parsed() {

		fmt.Println(os.Args[2])
	   handleRollback(os.Args[2])
	}
}


func handleRollback(filename string){
	t:=strings.Split(filename,"\\")
	if strings.Contains(t[len(t)-1],".xlsx"){
		RollbackOne(filename)
		return
	}
	RollBackMore(filename)
}

func RollbackOne(filename string){
	fmt.Println("批量回滚\n\n")
	fmt.Println("正在回滚......")
	start:=time.Now().Unix()

	var c=new(mark.Configer)
	err11:= c.ReadConfig(mark.Configpath)
	if err11!=nil {
	fmt.Println(err11)
		return
	}

	err:= mark.RollBackOne(filename,c.Rollback)
	if err!=nil{
		fmt.Println(err)
		return
	}



	end:=time.Now().Unix()
	mg:="已经回滚试卷  1  份!!!"+"\n"+

		"用时"+fmt.Sprintf("%d ",end-start)+"秒。"

	fmt.Println(mg)
}

func RollBackMore(fileload string){
	fmt.Println("正在回滚......")
	start:=time.Now().Unix()

	var c=new(mark.Configer)
	err11:= c.ReadConfig(mark.Configpath)
	if err11!=nil {
		fmt.Println(err11)
	}

	err:= mark.RollbackMore(fileload,".xlsx",c.Rollback)
	if err!=nil{
		fmt.Println(err)
		return
	}

	if mark.TotalFile ==0{
		fmt.Println( "未发现可回滚文件!")
		return
	}

	end:=time.Now().Unix()
	mg:="已经回滚试卷"+strconv.Itoa(mark.TotalFile) + "份!!!"+"\n"+

		"用时"+fmt.Sprintf("%d ",end-start)+"秒。"

	fmt.Println(mg)
	mark.TotalFile = 0
}






func handleMark(src,tar string){
	start:=time.Now().Unix()
	t:=strings.Split(tar,"\\")
	if strings.Contains(t[len(t)-1],".xlsx"){
		DoOne(src,tar)
	}

	FileName,err := DoMore(src, tar)
	if err != nil {
		return
	}
	if mark.TotalFile ==0{
		fmt.Println("未发现合法文件!")
		return
	}

	end:=time.Now().Unix()
	mg := "\n已批阅试卷:" + strconv.Itoa(mark.TotalFile) + "份!!!"+"\n"+
		"用时"+fmt.Sprintf("%d ",end-start)+"秒"+
		"\n已生成成绩单,位于:"+FileName+"\n"

	fmt.Println(mg)

	mark.TotalFile = 0
}










func DoOne(srcfile,tarfile string){
	fmt.Println("正在批阅......")

	start:=time.Now().Unix()

	var c=new(mark.Configer)
	err11:= c.ReadConfig(mark.Configpath)
	if err11!=nil {
		fmt.Println(err11)
		return
	}

	srcSet,err:= mark.ReadAnsFromFileToArray(c.Titles,srcfile)
	if err!=nil {
	    fmt.Println(err)
		return
	}
	tarSet,err1:= mark.ReadAnsFromFileToArray(c.Titles,tarfile)
	if err1!=nil {
		fmt.Println(err)
		return
	}

	if srcSet!=nil && tarSet!=nil{
		mark.TotalFile++
	}else{
		fmt.Println( "请选择正确的试卷进行评阅!")
		return
	}


	wrinf:= mark.MarkOnePeople(&c.Titles,tarSet,srcSet)
	err= mark.WriteScoreToFile(tarfile,*wrinf,c.Titles)
	if err!=nil{
		fmt.Println(err)
		return
		//fmt.Println("写入失败")
	}


	var sss =new(mark.StudentsScore)
	sss.ScoresInf=make([]mark.StudentScore,0)
	var ss =new(mark.StudentScore)
	var st =new(mark.Student)
	tar:=strings.Split(tarfile,"\\")
	str:=tar[len(tar)-1]
	if strings.Compare(str,"") ==0 {
		st.Name=tarfile
		st.Number=tarfile
	}else {
		set:=strings.Split(str,"_")
		if len(set)==2{
			st.Number=set[0]
			st.Name=set[1]
		}else{
			st.Name=str
			st.Number=str
		}

		//student:=getStudent(tarfile,".xlsx")

		ss.StudentInfo=*st
		ss.WrongAnswer= mark.GetWrongAns(*wrinf,c.Titles)
		for _,v:=range wrinf.WrInf{
			ss.Score=append(ss.Score,v.ItemScore)
		}
		ss.TotalScore=wrinf.TotalScore
		sss.ScoresInf=append(sss.ScoresInf,*ss)
	}

	_,err111:=os.Stat("./A_成绩单/")
	if os.IsNotExist(err111){
		os.Mkdir("./A_成绩单/",0666)
	}


	FileName:="./A_成绩单/A_成绩单_"+fmt.Sprintf("%d",time.Now().Unix())+"_Score.xlsx"
	//fmt.Println(FileName)
	erro:= mark.WriteStudentScoreToFile(FileName,*sss,c.Titles)
	if erro!=nil {
		fmt.Println(err)
		return
	}

	end:=time.Now().Unix()
	mg := "已经批阅试卷:" + strconv.Itoa(mark.TotalFile) + "份!!!"+"\n"+
		"用时"+fmt.Sprintf("%d ",end-start)+"秒"+
		"\n已经生成成绩单,位于当前目录,注意当前目录:\n"+FileName
	fmt.Println(mg)
	mark.TotalFile = 0
}






func DoMore(srcfile,tarfile string) (string,error) {
	fmt.Println("正在批阅......")
	var c=new(mark.Configer)
	err11:= c.ReadConfig(mark.Configpath)
	if err11!=nil {
		//fmt.Println(err11)
		return "",err11
	}

	srcSet,err:= mark.ReadAnsFromFileToArray(c.Titles,srcfile)
	if err!=nil {
		return "",err
	}
	sss,e:= mark.HandleMore(c.Titles,tarfile,".xlsx",*srcSet)

	if e !=nil{
		return "",e
	}

    FileName:=""
	t:=[]byte(tarfile)
	if t[len(t)-1] == byte('\\'){
		FileName=tarfile+"A_成绩单_"+fmt.Sprintf("%d",time.Now().Unix())+"_Score.xlsx"
	}

	FileName=tarfile+"\\"+"A_成绩单_"+fmt.Sprintf("%d",time.Now().Unix())+"_Score.xlsx"
	//fmt.Println(FileName)
	erro:= mark.WriteStudentScoreToFile(FileName,*sss,c.Titles)
	if erro!=nil {return "", err}
	return FileName,nil
}

 

你可能感兴趣的:(go语言,golang,自动评卷)