Python Copy entire sheet using openpyxl

  • 2021-10-13 07:55:34
  • OfStack

Through the incompetent baidu, I found that there are two or three pieces of code that can be used, but under reference, I found that there are still shortcomings:

You can't copy sheet with merged format, and you can't copy parameters such as related format (padding, border, alignment) of cell

So continue to explore through bing, and finally synthesize the following code:


from copy import copy
from openpyxl import load_workbook, Workbook
 
def replace_xls(src_file,tag_file,sheet_name):
 
#    src_file Is the source xlsx Documents, tag_file Is the target xlsx Documents, sheet_name Is the target xlsx New in sheet Name 
 
 print("Start sheet %s copy from %s to %s"%(sheet_name,src_file,tag_file))
 wb = load_workbook(src_file)
 wb2 = load_workbook(tag_file)
 
 ws = wb.get_sheet_by_name(wb.get_sheet_names()[0])
 ws2 = wb2.create_sheet(sheet_name.decode('utf-8'))
 
 max_row=ws.max_row  # Maximum number of rows 
 max_column=ws.max_column  # Maximum number of columns 
 
 wm=zip(ws.merged_cells) # Start working on merged cells 
 if len(wm)>0 :
 for i in range(0,len(wm)):
  cell2=str(wm[i]).replace('(<MergeCell ','').replace('>,)','')
  print("MergeCell : %s" % cell2)
  ws2.merge_cells(cell2)
 
 for m in range(1,max_row + 1):
 ws2.row_dimensions[m].height = ws.row_dimensions[m].height 
 for n in range(1,1 + max_column):
  if n<27 :
  c=chr(n+64).upper() #ASCII Character ,chr(65)='A'
  else:
  if n < 677 :
   c=chr(divmod(n,26)[0]+64)+chr(divmod(n,26)[1]+64)
  else:
   c=chr(divmod(n,676)[0]+64) + chr(divmod(divmod(n,676)[1],26)[0]+64) + chr(divmod(divmod(n,676)[1],26)[1]+64)
  i='%s%d'%(c,m) # Cell number 
  if m == 1 :
#   print("Modify column %s width from %d to %d" % (n, ws2.column_dimensions[c].width ,ws.column_dimensions[c].width))
   ws2.column_dimensions[c].width = ws.column_dimensions[c].width
  try:
  getattr(ws.cell(row=m, column=c), "value" )
  cell1=ws[i]  # Get data Cell data 
  ws2[i].value=cell1.value  # Assign a value to ws2 Cell 
  if cell1.has_style: # Copy format 
   ws2[i].font = copy(cell1.font)
   ws2[i].border = copy(cell1.border)
   ws2[i].fill = copy(cell1.fill)
   ws2[i].number_format = copy(cell1.number_format)
   ws2[i].protection = copy(cell1.protection)
   ws2[i].alignment = copy(cell1.alignment)
  except AttributeError as e:
  print("cell(%s) is %s" % (i,e))
  continue
 
 wb2.save(tag_file)
 
 wb2.close()
 wb.close()

Related articles: