免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3195 | 回复: 2

【分享】python之读写excel以及查找共同的行 [复制链接]

论坛徽章:
4
程序设计版块每日发帖之星
日期:2015-10-14 06:20:00每日论坛发贴之星
日期:2015-10-14 06:20:00程序设计版块每日发帖之星
日期:2016-05-02 06:20:00程序设计版块每日发帖之星
日期:2016-05-08 06:20:00
发表于 2016-04-19 09:11 |显示全部楼层
本帖最后由 mswsg 于 2016-04-19 09:12 编辑
  1. # ! /usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. '''
  4. python3 find_common_line_in_two_excels.py file1.xls file2.xls output.xls

  5. '''
  6. from xlrd import *
  7. import xlwt as ExcelWrite
  8. import os
  9. import sys
  10. input1 = os.path.abspath(sys.argv[1])
  11. input2 = os.path.abspath(sys.argv[2])
  12. output = os.path.abspath(sys.argv[3])

  13. def open_excel(excel):
  14.     try:
  15.         data = open_workbook(excel)
  16.         return data
  17.     except Exception as e:
  18.         print (str(e))
  19. def excel_table_byindex(excel,colnameindex=0,by_index=0):  #将文件按行放入列表 [[行],[行]]
  20.     data = open_excel(excel)
  21.     table = data.sheets()[by_index]
  22.     nrows = table.nrows
  23.     ncols = table.ncols
  24.     colnames =  table.row_values(colnameindex)
  25.     row_list = []
  26.     for rownum in range(nrows):
  27.         row = table.row_values(rownum)
  28.         row_list.append(row)
  29.     return row_list
  30. def main():
  31.     tables1 = excel_table_byindex(input1)
  32.     tables2 = excel_table_byindex(input2)
  33.     for i in range(len(tables1)):
  34.         if tables1[i] in tables2: #判断 文件一中的某一行是否在文件2中,是的话打印,否则打印 没有共有的行
  35.             return tables1[i]
  36. def writeXLS(file_name):
  37.     if main():
  38.         value = [main()]
  39.         #print (value)
  40.         xls = ExcelWrite.Workbook()
  41.         sheet = xls.add_sheet("Sheet1")
  42.         for i in range(len(value)):
  43.             for j in range(0,len(value[0])):
  44.                 sheet.write(i, j, value[i][j])
  45.         xls.save(file_name)
  46.     else:
  47.         print ("no common")

  48. if __name__=="__main__":
  49.     writeXLS(output);
复制代码

论坛徽章:
84
每日论坛发贴之星
日期:2015-12-29 06:20:00每日论坛发贴之星
日期:2016-01-16 06:20:00每周论坛发贴之星
日期:2016-01-17 22:22:00程序设计版块每日发帖之星
日期:2016-01-20 06:20:00每日论坛发贴之星
日期:2016-01-20 06:20:00程序设计版块每日发帖之星
日期:2016-01-21 06:20:00每日论坛发贴之星
日期:2016-01-21 06:20:00程序设计版块每日发帖之星
日期:2016-01-23 06:20:00程序设计版块每日发帖之星
日期:2016-01-31 06:20:00数据库技术版块每日发帖之星
日期:2016-01-16 06:20:00程序设计版块每日发帖之星
日期:2016-01-16 06:20:00程序设计版块每日发帖之星
日期:2016-01-14 06:20:00
发表于 2016-04-20 15:11 |显示全部楼层
谢谢分享,学习了

论坛徽章:
0
发表于 2016-04-26 09:21 |显示全部楼层
曾写过一个程序,类似的功能,支持多sheet比较,注释和颜色标记。也分享出来。
  1. __author__ = 'luhongc'

  2. import xlrd
  3. import xlwt
  4. import xlutils.copy


  5. def compare(oldFile,newFile,outputFile,comments=True,comment_pattern="DPL Comment",table_split="^Table\s*\d+$",max_columns=30):
  6.     """compare based on the directions, outputD for out put"""

  7.     oldwb = xlrd.open_workbook(oldFile)
  8.     newwb = xlrd.open_workbook(newFile, formatting_info=True)



  9.     yield "Pairing the files....\n"
  10.     paired, OldExtra, NewExtra = pairFiles(oldwb,newwb)

  11.     if (len(OldExtra)>0):
  12.         sheets = "\n".join (OldExtra)
  13.         yield "Warning: Sheet \n {}\nare only in Old File!\n".format(sheets)
  14.     if (len(NewExtra)>0):
  15.         sheets = "\n".join (NewExtra)
  16.         yield "Warning: Sheet \n {}\nare only in New File!\n".format(sheets)

  17.     yield "\nComparing the files....\n"

  18.     outwb = xlutils.copy.copy(newwb)
  19.     outwb.set_colour_RGB(0x2A,100,200,100)   # set light green color for output

  20.     def get_sheet_by_name(book, name):
  21.         """Get a sheet by name from xlwt.Workbook, a strangely missing method.
  22.         Returns None if no sheet with the given name is present.
  23.         """
  24.     # Note, we have to use exceptions for flow control because the
  25.     # xlwt API is broken and gives us no other choice.
  26.         import itertools
  27.         try:
  28.             for idx in itertools.count():
  29.                 sheet = book.get_sheet(idx)
  30.                 if sheet.name == name:
  31.                     return sheet
  32.         except IndexError:
  33.             return None

  34.     for k,v in paired.iteritems():
  35.         if v is not None:
  36.             sheetOld = oldwb.sheet_by_name(v)
  37.             sheetNew = newwb.sheet_by_name(k)
  38.             sheetOut = get_sheet_by_name(outwb,k)
  39.         else:
  40.             sheetOld = None
  41.             sheetNew = newwb.sheet_by_name(k)
  42.             sheetOut = get_sheet_by_name(outwb,k)


  43.         for txt in GDOcomMain(k,sheetOut,sheetNew,sheetOld,comments,comment_pattern,table_split,max_columns):
  44.             yield txt
  45.     outwb.save(outputFile)

  46. def GDOcomMain(sheetName,sheetOut,sheetNew,sheetOld,comments,comment_pattern,table_split,max_columns):
  47.     """ Main Comparison
  48.     """
  49.     yield "Comparing Sheet {}.".format(sheetName)
  50.     if sheetOld is None:                               # For a New Only Sheet
  51.         for txt in copyNew(sheetNew,sheetOut):
  52.             yield txt
  53.     else:
  54.         has_comment,datapool = readOld(sheetOld,comment_pattern,table_split,max_columns)  # Read Data Pool from Old Sheet.
  55.         nTable = len(datapool)
  56.         if nTable > 1:
  57.             nTable -= 1
  58.         yield sheetName + " has " +str(nTable) +" table(s)."

  59.         # Comparing file can read new sheet
  60.         for txt in typeCompare(sheetName,sheetOut,sheetNew,datapool,has_comment,table_split,comment_pattern,comments,max_columns):
  61.             yield txt

  62. def hash_key(thisrow,comment_column):
  63.     """ define hash key
  64.     """
  65.     return u"|".join(thisrow[:comment_column+1])


  66. def readOld(sheet,comment_pattern,table_split,max_columns):
  67.     """ readOld sheet
  68.     """
  69.     import re
  70.     p = re.compile(table_split,re.UNICODE)        # split pattern

  71.     datapool = []                # replied data pool
  72.     bufs = []                    # buffers to store rows

  73.     has_comment = False

  74.     buf = []
  75.     thispool = {}
  76.     commentTag = None
  77.     newpart = False
  78.     for row in xrange(sheet.nrows):
  79.         thisrow = [u'' for i in range(max_columns)]        # fill row with "" according to max_columns
  80.         for col in xrange(sheet.ncols):
  81.             cell = sheet.cell(row,col)
  82.             v = unicode(cell.value).strip()
  83.             if p.match(v):
  84.                 newpart = True                            # split flag
  85.             if v.upper() == comment_pattern.upper():      # detect comment_pattern
  86.                 if commentTag is not None:
  87.                     assert col == commentTag, "Comments should in the same column in old Sheet {}".format(sheet.name)
  88.                 commentTag = col
  89.                 has_comment = True
  90.             thisrow[col] = v

  91.         buf.append(thisrow)
  92.         if newpart:
  93.             datapool.append((thispool,commentTag))
  94.             bufs.append(buf)
  95.             thispool = {}
  96.             commentTag = None
  97.             buf = []
  98.             newpart = False

  99.     datapool.append((thispool,commentTag))         # The last part
  100.     bufs.append(buf)

  101.     for (pool,Tag),buf in zip(datapool,bufs):               # fill data pool
  102.         for thisrow in buf:
  103.             if Tag is None:                                 # if there is no comments
  104.                 key = hash_key(thisrow,len(thisrow)-1)
  105.                 pool[key] = ""
  106.             else:
  107.                 key = hash_key(thisrow,Tag-1)               # if there is comments
  108.                 pool[key] = thisrow[Tag]
  109.     return has_comment,datapool


  110. def copyNew(sheetNew,sheetOut,color='yellow'):
  111.     """Annotate a new sheet """
  112.     for row in range(sheetNew.nrows):
  113.         for col in range(sheetNew.ncols):
  114.             v = sheetNew.cell(row,col).value
  115.             style = xlwt.easyxf('pattern: pattern solid, fore_colour {}'.format(color))
  116.             if v == u"":                                     # only change the null cells
  117.                 sheetOut.write(row,col,v,style)
  118.     yield "Sheet {} is new one and annotated in YELLOW.\n".format(sheetOut.name)

  119. def typeCompare(sheetName,sheetOut,sheetNew,datapool,has_comment,table_split,comment_pattern,comments,max_columns,color='0x2A'):
  120.     """ Comparing sheets and output
  121.     """
  122.     import re
  123.     p = re.compile(table_split,re.UNICODE)       # table split pattern

  124.     recordpool = []
  125.     record = []
  126.     newpart = False
  127.     partid = 0
  128.     commentTag = datapool[partid][1]

  129.     # Check the tables in new sheet
  130.     for row in xrange(sheetNew.nrows):
  131.         for col in xrange(sheetNew.ncols):
  132.             cell = sheetNew.cell(row,col)
  133.             v = unicode(cell.value).strip()
  134.             if p.match(v):
  135.                 newpart = True
  136.             if v.upper() == comment_pattern.upper():
  137.                 assert col == commentTag, "Comments should in the same column in new Sheet {}".format(sheetNew.name)
  138.         record.append(row)
  139.         if newpart:
  140.             recordpool.append((record,commentTag))
  141.             record = []
  142.             partid += 1
  143.             try:
  144.                 commentTag = datapool[partid][1]
  145.             except:
  146.                 raise ValueError("Sheet {} has different number of tables".format(sheetName))
  147.             newpart = False

  148.     recordpool.append((record,commentTag))

  149.     assert len(recordpool) == len(datapool),"Sheet {} has different number of tables".format(sheetName)

  150.     for partid,(record,Tag) in enumerate(recordpool):
  151.         for row in record:
  152.             thisrow = [u'' for i in range(max_columns)]       # fill the this row with null according to max_columns
  153.             for col in xrange(sheetNew.ncols):
  154.                 cell = sheetNew.cell(row,col)
  155.                 v = unicode(cell.value).strip()
  156.                 thisrow[col] = v
  157.             if Tag is None:                                   # define key by commentTag
  158.                 key = hash_key(thisrow,len(thisrow)-1)
  159.             else:
  160.                 key = hash_key(thisrow,Tag-1)
  161.             if key in datapool[partid][0]:
  162.                 # old records
  163.                 oldTag = datapool[partid][1]
  164.                 if oldTag is not None and comments:
  165.                     sheetOut.write(row,oldTag,datapool[partid][0][key])
  166.             else:
  167.                 # new records
  168.                 for col in xrange(sheetNew.ncols):
  169.                     cell = sheetNew.cell(row,col)
  170.                     v = cell.value
  171.                     is_date = False
  172.                     try:                                        # detect if the format is possible date field
  173.                         date = float(v)
  174.                         if date > 10000.0 and date < 99999.0:
  175.                             is_date = True
  176.                     except:
  177.                         pass

  178.                     if not is_date:
  179.                         style = xlwt.easyxf('pattern: pattern solid, fore_colour {}; align: horiz center; border:top thin,bottom thin;'.format(color))
  180.                         sheetOut.write(row,col,v,style)
  181.     yield "Sheet {} is OK. New items are annotated in GREEN\n".format(sheetOut.name)

  182. def pairFiles(oldwb,newwb):
  183.     """paired the sheets based on format"""
  184.     newSheets = { k.strip():k for k in newwb.sheet_names()}          # paired by stripped names
  185.     oldSheets = { k.strip():k for k in oldwb.sheet_names()}

  186.     oldExtra = set(oldSheets.keys()) - set(newSheets.keys())
  187.     newExtra = set(newSheets.keys()) - set(oldSheets.keys())

  188.     paired = {}
  189.     for s,v in newSheets.iteritems():
  190.         if s in oldSheets:
  191.             paired[v] = oldSheets[s]
  192.         else:
  193.             paired[v] = None

  194.     return paired, oldExtra, newExtra

  195. if __name__ == "__main__":
  196.     import sys
  197.     oldD,newD,outputD = sys.argv[1:]
  198.     for txt in compare(oldD,newD,outputD):
  199.         print txt
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP