xlsx_creator.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import xlsxwriter
  2. from xlsxwriter.utility import xl_range
  3. from datetime import datetime, timedelta
  4. class xlsx_creator():
  5. style_header = {
  6. 'bold': True,
  7. 'border': 1,
  8. 'align': 'center',
  9. 'valign': 'vcenter'
  10. }
  11. def __init__(self, DATA, path='/tmp/'):
  12. self.FileName= F"employee-attendance-{str(datetime.now())}.xlsx"
  13. self.path = path+self.FileName
  14. self.DATA = DATA
  15. self.workbook = xlsxwriter.Workbook(self.path)
  16. self.worksheet = self.workbook.add_worksheet()
  17. def cook_xlsx(self):
  18. self.create_header()
  19. self.create_diff_date_and_hours()
  20. self.create_sub_head()
  21. self.create_body_data()
  22. self.workbook.close()
  23. return self.path
  24. def create_header(self):
  25. self.worksheet.set_row(0, 70)
  26. style_header = self.workbook.add_format(self.style_header)
  27. style_header.set_text_wrap()
  28. colum = 0
  29. for data in self.DATA:
  30. text_header = F"{data['FIO']} \n посещаемость с {data['STARTDATE']}г. по {data['ENDDATE']}г."
  31. self.worksheet.merge_range(self.get_column_range(0, colum, 0, colum+4), text_header, style_header)
  32. colum += 6
  33. def convert_str_to_datetime(self, date_string):
  34. (h,m,s) = date_string.split(':')
  35. return timedelta(hours=int(h), minutes=int(m), seconds=int(s))
  36. def get_count_work_hours(self, DateAttendance):
  37. count_work_hours = timedelta()
  38. for x in DateAttendance:
  39. count_work_hours += self.convert_str_to_datetime(self.return_correct_value(x["diffTime"]))
  40. hours, remainder = divmod(count_work_hours.total_seconds(), 3600)
  41. minutes, seconds = divmod(remainder, 60)
  42. print(count_work_hours)
  43. return F"{int(hours)}:{int(minutes)}:{int(seconds)}"
  44. def create_diff_date_and_hours(self):
  45. style_body = self.workbook.add_format({
  46. 'border': 1,
  47. 'align': 'center',
  48. })
  49. style_header = self.workbook.add_format(self.style_header)
  50. col_work_day_text = "Количество рабочих дней"
  51. col_calendar_day = "Количество календарных дней"
  52. col_work_hours = "Количество рабочих часов"
  53. column = 0
  54. for data in self.DATA:
  55. self.worksheet.merge_range(self.get_column_range(1, column, 1, column+3),
  56. col_work_day_text, style_header)
  57. self.worksheet.write(1, column+4, len(data['DateAttendance']), style_body)
  58. self.worksheet.merge_range(self.get_column_range(2, column, 2, column+3),
  59. col_calendar_day, style_header)
  60. self.worksheet.write(2, column+4, len(data['EmptyDatesAttendance']+data['DateAttendance']), style_body)
  61. self.worksheet.merge_range(self.get_column_range(3, column, 3, column+3),
  62. col_work_hours, style_header)
  63. self.worksheet.write(3, column+4, self.get_count_work_hours(data['DateAttendance']), style_body)
  64. column += 6
  65. def create_sub_head(self):
  66. colum = 0
  67. style_header = self.workbook.add_format(self.style_header)
  68. style_header.set_text_wrap()
  69. self.worksheet.set_row(4, 30)
  70. for data in self.DATA:
  71. self.worksheet.write(4, colum, 'Д/н', style_header)
  72. self.worksheet.write(4, colum+1, 'Дата', style_header)
  73. self.worksheet.write(4, colum+2, 'Вход', style_header)
  74. self.worksheet.write(4, colum+3, 'Выход', style_header)
  75. self.worksheet.set_column(4, colum+4, 15)
  76. self.worksheet.write(4, colum+4, 'Время пребывания', style_header)
  77. colum += 6
  78. def get_column_range(self, srow, scolumn, erow, ecolumn):
  79. return xl_range(srow, scolumn, erow, ecolumn)
  80. def sort_attendance(self, arr):
  81. return sorted(arr, key=lambda x : datetime.strptime(self.return_correct_value(x['date']), '%d.%m.%Y'))
  82. def is_bold_diff_time(self, val, s, b):
  83. val = self.return_correct_value(val)
  84. if len(val) > 0:
  85. if int(val.split(':')[0]) > 7:
  86. return b
  87. return s
  88. def is_bold_entrance(self, val, s, b):
  89. val = self.return_correct_value(val)
  90. if len(val) > 0:
  91. hours = val.split(':')[0]
  92. if int(hours) >= 9 and int(hours) <= 18:
  93. return b
  94. return s
  95. def create_body_data(self):
  96. colum = 0
  97. style_body = self.workbook.add_format({
  98. 'border': 1,
  99. 'align': 'center',
  100. })
  101. style_body_with_bold = self.workbook.add_format({
  102. 'border': 1,
  103. 'align': 'center',
  104. 'bold': True
  105. })
  106. for data in self.DATA:
  107. body_data = (data['EmptyDatesAttendance']+data['DateAttendance'])
  108. row = 5
  109. for attendance in self.sort_attendance(body_data):
  110. self.worksheet.write(row, colum, self.return_correct_value(attendance['wd']), style_body_with_bold)
  111. self.worksheet.write(row, colum+1, self.return_correct_value(attendance['date']), style_body)
  112. body_entrance_style = self.is_bold_entrance(attendance['entrance'], style_body, style_body_with_bold)
  113. self.worksheet.write(row, colum+2, self.return_correct_value(attendance['entrance']), body_entrance_style)
  114. self.worksheet.write(row, colum+3, self.return_correct_value(attendance['exit']), style_body)
  115. body_diff_time = self.is_bold_diff_time(attendance['diffTime'], style_body, style_body_with_bold)
  116. self.worksheet.write(row, colum+4, self.return_correct_value(attendance['diffTime']), body_diff_time)
  117. row += 1
  118. colum += 6
  119. def return_correct_value(self, val):
  120. if type(val).__name__ == 'list':
  121. return val[0]
  122. else:
  123. return val