用python连接中控考勤机。 下载并分析数据,把结果邮件给人事。


中控SDK包: x32地址 x64地址

SDK包建议用32位的,在win7 64位系统上用64位开发包不行,用32可以。


python还要pywin32 注意版本,我这用的 32位的python 2.7 然后下的这个pywin32


excel 用了 xlsxwriter 这个功能不错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#!/usr/bin/env python
#_*_ coding:gbk _*_
 
import win32com.client
import datetime
import xlsxwriter
import sys
import smtplib
from email.mime.multipart import MIMEMultipart  
from email.mime.text import MIMEText  
from email.mime.image import MIMEImage  
 
non = {21:"niu.niu", }  #非研发人员
no_checkin = [1,34,35,36,23,40]  #不计考勤人员
 
def send_mail(filename=[], picname=[], content_txt='', content_html=''): 
    smtpserver = 'smtp.163.com'  
    username = 'test@163.com'  
    password = '123123'  
     
    msg = MIMEMultipart()  
    msg['Subject'= 'Check_In %s' % today.strftime("%Y-%m-%d")   
    msg['From'= "test@163.com"
    msg['To'= "hr@163.com"
     
# attchment
    if len(filename) > 0:
        for in filename:
            att = MIMEText(open(i, 'rb').read(), 'base64''gb2312')  
            att["Content-Type"= 'application/octet-stream'  
            att["Content-Disposition"= 'attachment; filename="%s"' % i.split('\\')[-1]
            msg.attach(att)  
 
# attchment picture
    if len(picname) > 0 and content_html != '':
        for in range(0,len(picname)):
            #content_html = '<b>Some <i>HTML</i> text</b> and an image.<br><img src="cid:image%s"><br>good!' % i  
            msg_content_html = MIMEText(content_html,'html','gb2312')  
            msg.attach(msg_content_html)  
             
            with open(picname[i], 'rb') as f:
                msgImage = MIMEImage(f.read())  
             
            msgImage.add_header('Content-ID''<image%s>' % (i + 1))  
            msg.attach(msgImage)
     
# content text    
    if content_txt != '':
        msg_content_txt = MIMEText(content_txt,_subtype='plain',_charset='gb2312'
        msg.attach(msg_content_txt)
 
# content html  
    if content_html != '' and len(picname) == 0:
        msg_content_html = MIMEText(content_html,_subtype='html',_charset='gb2312'
        msg.attach(msg_content_html)
         
    smtp = smtplib.SMTP()  
    smtp.connect(smtpserver)  
    smtp.starttls()  
    smtp.login(username, password)  
    smtp.sendmail(msg['From'], msg['To'], msg.as_string())  
    smtp.quit()      
 
zk = win32com.client.Dispatch('zkemkeeper.ZKEM.1')
if not zk.Connect_Net('192.168.1.31'4370):
    print "Connect Error"
    sys.exit(1)
 
if len(sys.argv) == 2#如果以 ./script 2015-11-22 这样的方式运行,可以指定别的星期
    today = datetime.datetime.strptime( sys.argv[1+ " 11:22:33"'%Y-%m-%d %H:%M:%S')
else:
    today = datetime.datetime.now()
    zk.SetDeviceTime(1)     #set pc time  
    if datetime.datetime.now().weekday() != 0
        zk.Disconnect()
        sys.exit(1)
   
zk.ReadAllUserID(1)
uid = {}
while 1:
    exists, idNum, username, other, privilege, enable = zk.GetAllUserInfo(1)
    if not exists:
        break
    else:
        if enable:
            uid[idNum] = username.split(u'\x00')[0].encode('gbk')
 
checkin,uid_name  = {}, []
if len(sys.argv) == 1:
    log = open(today.strftime("D:\\CheckIn\\bak\\%Y-%m-%d.txt"), "w")
if zk.ReadGeneralLogData(1):  #read All checkin data
    while 1:
        exists, machNum, idNum, emachNum, verifyMode, outMode, year, month, day, hour, minute = zk.GetGeneralLogData(1#2   
        if year <= today.year:
            if 0 < (datetime.date(today.year,today.month,today.day) - datetime.date(year,month,day)).days < 8:
                if len(sys.argv) == 1:
                    log.write("%s-%s-%s %02d:%02d %s %s\n" % (year,month,day,hour,minute,uid.get(idNum,"ERROR"),idNum))   
                if idNum not in uid:
                    continue
                if day not in checkin:
                    checkin[day] = {}   
                try:
                    checkin[day][idNum].append(hour * 60 + minute)
                except:
                    checkin[day][idNum] = [hour * 60 + minute]
        else:
            break
if len(sys.argv) == 1:
    log.close()            
zk.Disconnect()
 
if len(sys.argv) == 1:  #自动运行保存指定位置
    workbook = xlsxwriter.Workbook(today.strftime("D:\\CheckIn\\xlsx\\%Y-%m-%d.xlsx"))
else:
    workbook = xlsxwriter.Workbook(today.strftime("%Y-%m-%d.xlsx"))
worksheet = workbook.add_worksheet("WeekAll")
worksheet.set_column(0010)
format1 = workbook.add_format({'bg_color''#FFC7CE'})
sheet = {}
uid_name = sorted(uid.keys())
 
for in range(8,0,-1):
    dayNum = (today - datetime.timedelta(days=i)).strftime("%Y-%m-%d")
    = 0
    if i < 8:
        worksheet.write(8-i, n, dayNum)
        sheet[8-i] = workbook.add_worksheet(dayNum)
        worksheet.write_url(row=8-i,col=0,url="internal:'%s'!A1" % dayNum, string=dayNum, tip=dayNum)
        sheet[8-i].write(0,0,"Name")
        sheet[8-i].write(0,1,"AM")
        sheet[8-i].write(0,2,"PM")
        sheet[8-i].write(0,3,"Time")
    dayNum = int(dayNum.split('-')[-1])
    for col in uid_name:
        work_time = 9
        if col in no_checkin:  #不需要统计考勤
            continue
        += 1
        if == 8:
            worksheet.write(8-i, n, uid[col].decode('gbk'))
            continue
        sheet[8-i].write(n, 0, uid[col].decode('gbk'))
        if dayNum not in checkin or col not in checkin[dayNum]:
            continue
        if len(checkin[dayNum][col]) < 2 and i > 2:
            sheet[8-i].write(n, 30, format1)
            worksheet.write(8-i, n, 0, format1)
            am = checkin[dayNum][col][0]
            pm = 0
        else:
            min_time = am = min(checkin[dayNum][col])
            max_time = pm = max(checkin[dayNum][col])
            if min_time < 510:   #最早从8:30 计考勤
                min_time = 510
            elif col not in non and 570 < min_time <= 600:  #研发9:30后,10:00以前,算两倍。
                if (min_time-570* 2 <= 30:
                    work_time += 0.5
                else:
                    work_time += 1
             
            dayTime = max_time - min_time  #当天工作时间
             
            if dayTime%60 >= 45:
                dayTime = dayTime//60 + 1
            elif 15 <= dayTime%60 45:
                dayTime = dayTime//60 + 0.5
            else:
                dayTime = dayTime//60
             
            if (col in non and min_time > 540and i > 2:  #非研发过 9 点算迟到
                sheet[8-i].write(n, 3, dayTime, format1)
                worksheet.write(8-i, n, dayTime, format1)
            elif (col not in non and min_time > 600and i > 2#研发过 10 点算迟到
                sheet[8-i].write(n, 3, dayTime, format1)
                worksheet.write(8-i, n, dayTime, format1)            
            elif dayTime < work_time and i > 2:  #时间不够未到工作时间
                sheet[8-i].write(n, 3, dayTime, format1)
                worksheet.write(8-i, n, dayTime, format1)                     
            else:
                worksheet.write(8-i, n, dayTime)
                sheet[8-i].write(n, 3, dayTime)
                             
       #添加批注
        if pm:
            worksheet.write_comment(8-i, n, 'AM  %02d:%02d\nPM  %02d:%02d' % (am//60, am%60,
                                        pm//60, pm%60))   
            sheet[8-i].write(n, 1'%02d:%02d' % (am//60, am%60)) 
            sheet[8-i].write(n, 2'%02d:%02d' % (pm//60, pm%60))
        else:                                        
            if am < 720:
                worksheet.write_comment(8-i, n, 'AM  %02d:%02d' % (am//60, am%60)) 
                sheet[8-i].write(n, 1'%02d:%02d' % (am//60, am%60))
            else:
                worksheet.write_comment(8-i, n, 'PM  %02d:%02d' % (am//60, am%60))    
                sheet[8-i].write(n, 2'%02d:%02d' % (am//60, am%60))                                        
 
workbook.close()
if len(sys.argv) == 1:
    send_mail(filename=[today.strftime("D:\\CheckIn\\xlsx\\%Y-%m-%d.xlsx")], content_txt='Check_In %s' % today.strftime("%Y-%m-%d"))