1. """
    2. 现在的需求变了。文件列表中的文件名,也就是项目名,统一放到第一列,
    3. 而且放到总表里的相同项目的行,第一列的项目名要合并单元格
    4. 需求又变了,因为合并单元格会干扰筛选,所以只能每一列都加名字
    5. """
    6. import os,glob
    7. import win32com.client
    8. import win32api
    9. import re,time
    10. import io
    11. import sys
    12. sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')
    13. #这三行为了让终端显示中文
    14. def getFilenameWithoutSuffix(path):
    15. filename = os.path.basename(path)
    16. filename = filename.split('.')[1] #文件名是22.xxxx.xlsx
    17. return filename
    18. def matchStr(input_str,ref_str):
    19. if type(input_str) == str:
    20. match = re.search(ref_str,input_str)
    21. if match:
    22. return True
    23. else:
    24. return False
    25. else:
    26. return False
    27. def checkNewTable(sheet,rowNum,colNum):
    28. for row in range(1,rowNum+1):
    29. for col in range(1,colNum+1):
    30. if matchStr(sheet.Cells(row,col).Value,'设备招标情况'):
    31. return [True,row,col]
    32. elif matchStr(sheet.Cells(row,col).Value,'采购状态'):
    33. return [False,row,col]
    34. print('\033[1;35m 查询不到表头! \033[0m')
    35. return [0,0,0]
    36. def strProcess(input_str):
    37. input_str = input_str.replace('$','')#去除$
    38. b=re.sub('[A-Za-z]','',input_str)#去除字母
    39. return b
    40. #从"2:4"这样的字符串中获取差值
    41. def getDifNumber(input_str):
    42. num_list = input_str.split(':')
    43. dif_num = int(num_list[1]) - int(num_list[0])
    44. return dif_num
    45. def pasteRows(sheet,row,paste):
    46. paste_range = 'B' + str(row)
    47. sheet.Range(paste_range).PasteSpecial(Paste=paste)#要带列宽的话需要多执行一遍Paste=8
    48. def getCellAddress(sheet,row,col):
    49. temp_address = sheet.Cells(row,col).Address
    50. cell_address = temp_address.replace('$','')
    51. return cell_address
    52. def clearCacheInFilelist(filelist): #去除glob查到的~前缀的缓存文件
    53. for i in range(len(filelist)-1,-1,-1):
    54. match = re.search('~',filelist[i])
    55. if match:
    56. print(filelist[i])
    57. filelist.remove(filelist[i])
    58. return filelist
    59. def excludeOtherValues(input_str):
    60. if type(input_str) == str:
    61. match = re.search('已签|已定标|现场零星采购',input_str)
    62. if match:
    63. return True
    64. else:
    65. return False
    66. else:
    67. return False
    68. filelist = glob.glob(r'文件夹\*.xlsx')
    69. file_dir = clearCacheInFilelist(filelist)
    70. pos_col = 3 #以经办人这一列来确定是否为有效行
    71. sht2_row = 4 #开始复制的行
    72. color = int('E8E8E8',16)
    73. list1 = []
    74. first_num = 0
    75. trigger = False
    76. try:
    77. xlApp = win32com.client.Dispatch('Excel.Application')
    78. xlApp.Visible = False
    79. xlBook2 = xlApp.Workbooks.Open(r'E:\测试\测试.xlsx')
    80. sht2 = xlBook2.Sheets(1)
    81. colNum2 = sht2.UsedRange.Columns.Count
    82. for i in range(len(file_dir)):
    83. xlBook1 = xlApp.Workbooks.Open(Filename=file_dir[i],ReadOnly=True)
    84. filenameWithoutSuffix = getFilenameWithoutSuffix(file_dir[i])
    85. print('\033[1;32;43m ',filenameWithoutSuffix,' \033[0m!')
    86. sht1 = xlBook1.Sheets(1) #默认选择第一张表
    87. rowNum = sht1.UsedRange.Rows.Count #返回文件1的行数
    88. colNum = sht1.UsedRange.Columns.Count #返回文件1的列数
    89. cell_state = checkNewTable(sht1,rowNum,colNum)
    90. header_row = cell_state[1] #如果表头是合并单元格,也没必要加一
    91. match_col = cell_state[2] #匹配列的列数
    92. if cell_state[0]==True:
    93. for row in range(header_row+1,rowNum+1):
    94. pos_cell = sht1.Cells(row,pos_col)
    95. cell = sht1.Cells(row,match_col)
    96. print('第',row,'行:',end=' ')
    97. sys.stdout.flush() #刷新缓存区
    98. if type(pos_cell.Value) == str:
    99. if pos_cell.MergeCells :
    100. temp_address = sht1.Cells(row,pos_col).MergeArea.Address#获取合并单元格的地址
    101. rows_range = strProcess(temp_address)#清洗得到的字符串
    102. print('合并单元格行数--',rows_range)
    103. sys.stdout.flush()
    104. temp_range = rows_range.split(':')
    105. copy_list = ['A',str(temp_range[0]),':','AJ',str(temp_range[1])]
    106. copy_area = ''.join(copy_list)
    107. dif_num = getDifNumber(rows_range)
    108. if excludeOtherValues(cell.Value) == False :
    109. if first_num == 0:
    110. first_num = sht2_row
    111. trigger = True
    112. print(cell.Value)
    113. sht1.Range(copy_area).Copy() #复制这几行
    114. pasteRows(sht2,sht2_row,14) #粘贴到总表
    115. cell_address = getCellAddress(sht2,sht2_row,1)
    116. #这两行在表末尾增加了一列,给单元格赋值,内容是表名称
    117. #last_cell = getCellAddress(sht2,sht2_row + dif_num,colNum+1)
    118. last_cell = getCellAddress(sht2,sht2_row + dif_num,1)
    119. #获取首末单元格地址
    120. merge_range = cell_address + ':' + last_cell
    121. sht2.Range(merge_range).Value = filenameWithoutSuffix
    122. print('复制到表2第',sht2_row,'行',end='***')
    123. sht2_row += dif_num + 1
    124. print('下次行数:',sht2_row)
    125. sys.stdout.flush()
    126. else:
    127. print('\033[1;35m 非空标准单元格! \033[0m',pos_cell.Value)
    128. if matchStr(cell.Value,'合同已签')==False :
    129. trigger = True
    130. sht1.Rows(row).Copy()#复制这几行
    131. pasteRows(sht2,sht2_row,14)
    132. sht2_row += 1
    133. sys.stdout.flush() #刷新缓存区
    134. if trigger == True:
    135. last_num = sht2_row - 1
    136. copy_rows = str(first_num) + ':' + str(last_num)
    137. first_num = last_num + 1
    138. list1.append(copy_rows)
    139. trigger = False
    140. sht2.Cells.FormatConditions.Delete()#清除条件格式,不然格子的颜色会乱掉
    141. for i in range(len(list1)):
    142. if i % 2 == 0:
    143. sht2.Range(list1[i]).Interior.Color = color
    144. xlApp.CutCopyMode = False
    145. xlBook1.Close(False)
    146. xlBook2.Save()
    147. sht2.PageSetup.PrintTitleRows = "$2:$3"#设置打印顶端标题(即每一页都要打印23行)
    148. # sht2.PageSetup.PrintTitleColumns = "$A:$B"#设置重复打印列
    149. # sht2.PageSetup.PrintTitleColumns = ""#取消设置
    150. # sht2.PageSetup.PrintTitleColumns = False #取消设置
    151. finally:
    152. # if xlApp.ClipboardFormats[0]:
    153. # xlApp.CutCopyMode = False#清空剪贴板
    154. xlApp.quit()
    155. print(list1)