openpyxl을 사용하여 워크시트를 한 워크북에서 다른 워크북으로 복사하는 방법은 무엇입니까?
EXCEL 파일(예: 200개)을 대량으로 가지고 있습니다. 특정 워크시트를 워크북에서 다른 워크시트로 복사하려고 합니다.저는 몇 가지 조사를 해봤지만 Openpyxl로 할 수 있는 방법을 찾을 수 없었습니다.
이것은 제가 지금까지 개발한 코드입니다.
def copy_sheet_to_different_EXCEL(path_EXCEL_read,Sheet_name_to_copy,path_EXCEL_Save,Sheet_new_name):
''' Function used to copy one EXCEL sheet into another file.
def path_EXCEL_read,Sheet_name_to_copy,path_EXCEL_Save,Sheet_new_name
Input data:
1.) path_EXCEL_read: the location of the EXCEL file along with the name where the information is going to be saved
2.) Sheet_name_to_copy= The name of the EXCEL sheet to copy
3.) path_EXCEL_Save: The path of the EXCEL file where the sheet is going to be copied
3.) Sheet_new_name: The name of the new EXCEL sheet
Output data:
1.) Status= If 0, everything went OK. If 1, one error occurred.
Version History:
1.0 (2017-02-20): Initial version.
'''
status=0
if(path_EXCEL_read.endswith('.xls')==1):
print('ERROR - EXCEL xls file format is not supported by openpyxl. Please, convert the file to an XLSX format')
status=1
return status
try:
wb = openpyxl.load_workbook(path_EXCEL_read,read_only=True)
except:
print('ERROR - EXCEL file does not exist in the following location:\n {0}'.format(path_EXCEL_read))
status=1
return status
Sheet_names=wb.get_sheet_names() # We copare against the sheet name we would like to cpy
if ((Sheet_name_to_copy in Sheet_names)==0):
print('ERROR - EXCEL sheet does not exist'.format(Sheet_name_to_copy))
status=1
return status
# We checking if the destination file exists
if (os.path.exists(path_EXCEL_Save)==1):
#If true, file exist so we open it
if(path_EXCEL_Save.endswith('.xls')==1):
print('ERROR - Destination EXCEL xls file format is not supported by openpyxl. Please, convert the file to an XLSX format')
status=1
return status
try:
wdestiny = openpyxl.load_workbook(path_EXCEL_Save)
except:
print('ERROR - Destination EXCEL file does not exist in the following location:\n {0}'.format(path_EXCEL_read))
status=1
return status
#we check if the destination sheet exists. If so, we will delete it
destination_list_sheets = wdestiny.get_sheet_names()
if((Sheet_new_name in destination_list_sheets) ==True):
print('WARNING - Sheet "{0}" exists in: {1}. It will be deleted!'.format(Sheet_new_name,path_EXCEL_Save))
wdestiny.remove_sheet(Sheet_new_name)
else:
wdestiny=openpyxl.Workbook()
# We copy the Excel sheet
try:
sheet_to_copy = wb.get_sheet_by_name(Sheet_name_to_copy)
target = wdestiny.copy_worksheet(sheet_to_copy)
target.title=Sheet_new_name
except:
print('ERROR - Could not copy the EXCEL sheet. Check the file')
status=1
return status
try:
wdestiny.save(path_EXCEL_Save)
except:
print('ERROR - Could not save the EXCEL sheet. Check the file permissions')
status=1
return status
#Program finishes
return status
저도 같은 문제가 있었습니다.저에게 스타일, 형식, 레이아웃은 매우 중요했습니다.게다가 저는 공식을 복사하는 것이 아니라 (공식의) 값만 복사하고 싶었습니다.많은 추적, 오류 및 스택 오버플로 후에 다음과 같은 기능을 생각해냈습니다.약간 위협적으로 보일 수 있지만 코드는 다음을 유지하면서 한 Excel 파일에서 다른 파일(아마도 기존 파일)로 시트를 복사합니다.
- 텍스트 글꼴 및 색상
- 세포의 충만한 색
- 병합된 세포
- 주석 및 하이퍼링크
- 셀 값의 형식
- 모든 행과 열의 너비
- 행 및 열 숨김 여부
- 얼어붙은 행
많은 워크북에서 시트를 수집하여 하나의 워크북에 바인딩하려는 경우 유용합니다.대부분의 속성을 복사했지만 몇 개 더 있을 수 있습니다.이 경우 이 스크립트를 출발점으로 사용하여 추가할 수 있습니다.
###############
## Copy a sheet with style, format, layout, ect. from one Excel file to another Excel file
## Please add the ..path\\+\\file.. and ..sheet_name.. according to your desire.
import openpyxl
from copy import copy
def copy_sheet(source_sheet, target_sheet):
copy_cells(source_sheet, target_sheet) # copy all the cel values and styles
copy_sheet_attributes(source_sheet, target_sheet)
def copy_sheet_attributes(source_sheet, target_sheet):
target_sheet.sheet_format = copy(source_sheet.sheet_format)
target_sheet.sheet_properties = copy(source_sheet.sheet_properties)
target_sheet.merged_cells = copy(source_sheet.merged_cells)
target_sheet.page_margins = copy(source_sheet.page_margins)
target_sheet.freeze_panes = copy(source_sheet.freeze_panes)
# set row dimensions
# So you cannot copy the row_dimensions attribute. Does not work (because of meta data in the attribute I think). So we copy every row's row_dimensions. That seems to work.
for rn in range(len(source_sheet.row_dimensions)):
target_sheet.row_dimensions[rn] = copy(source_sheet.row_dimensions[rn])
if source_sheet.sheet_format.defaultColWidth is None:
print('Unable to copy default column wide')
else:
target_sheet.sheet_format.defaultColWidth = copy(source_sheet.sheet_format.defaultColWidth)
# set specific column width and hidden property
# we cannot copy the entire column_dimensions attribute so we copy selected attributes
for key, value in source_sheet.column_dimensions.items():
target_sheet.column_dimensions[key].min = copy(source_sheet.column_dimensions[key].min) # Excel actually groups multiple columns under 1 key. Use the min max attribute to also group the columns in the targetSheet
target_sheet.column_dimensions[key].max = copy(source_sheet.column_dimensions[key].max) # https://stackoverflow.com/questions/36417278/openpyxl-can-not-read-consecutive-hidden-columns discussed the issue. Note that this is also the case for the width, not onl;y the hidden property
target_sheet.column_dimensions[key].width = copy(source_sheet.column_dimensions[key].width) # set width for every column
target_sheet.column_dimensions[key].hidden = copy(source_sheet.column_dimensions[key].hidden)
def copy_cells(source_sheet, target_sheet):
for (row, col), source_cell in source_sheet._cells.items():
target_cell = target_sheet.cell(column=col, row=row)
target_cell._value = source_cell._value
target_cell.data_type = source_cell.data_type
if source_cell.has_style:
target_cell.font = copy(source_cell.font)
target_cell.border = copy(source_cell.border)
target_cell.fill = copy(source_cell.fill)
target_cell.number_format = copy(source_cell.number_format)
target_cell.protection = copy(source_cell.protection)
target_cell.alignment = copy(source_cell.alignment)
if source_cell.hyperlink:
target_cell._hyperlink = copy(source_cell.hyperlink)
if source_cell.comment:
target_cell.comment = copy(source_cell.comment)
wb_target = openpyxl.Workbook()
target_sheet = wb_target.create_sheet(..sheet_name..)
wb_source = openpyxl.load_workbook(..path\\+\\file_name.., data_only=True)
source_sheet = wb_source[..sheet_name..]
copy_sheet(source_sheet, target_sheet)
if 'Sheet' in wb_target.sheetnames: # remove default sheet
wb_target.remove(wb_target['Sheet'])
wb_target.save('out.xlsx')
나는 그것을 가지고 노는 방법을 찾았습니다.
import openpyxl
xl1 = openpyxl.load_workbook('workbook1.xlsx')
# sheet you want to copy
s = openpyxl.load_workbook('workbook2.xlsx').active
s._parent = xl1
xl1._add_sheet(s)
xl1.save('some_path/name.xlsx')
사용할 수 없습니다.copy_worksheet()워크북마다 다를 수 있는 전역 상수에 따라 다르기 때문에 워크북 간에 복사할 수 있습니다.안전하고 신뢰할 수 있는 유일한 방법은 행 단위로 셀 단위로 이동하는 것입니다.
내가 사용하는 속도data_only그리고.read_only워크북을 열 때 속성을 표시합니다.또한.iter_rows()정말 빠르네요.
@Oscar의 훌륭한 답변은 ReadOnly 워크시트 및 EmptyCell을 지원하기 위해 몇 가지 변경이 필요합니다.
# Copy a sheet with style, format, layout, ect. from one Excel file to another Excel file
# Please add the ..path\\+\\file.. and ..sheet_name.. according to your desire.
import openpyxl
from copy import copy
def copy_sheet(source_sheet, target_sheet):
copy_cells(source_sheet, target_sheet) # copy all the cel values and styles
copy_sheet_attributes(source_sheet, target_sheet)
def copy_sheet_attributes(source_sheet, target_sheet):
if isinstance(source_sheet, openpyxl.worksheet._read_only.ReadOnlyWorksheet):
return
target_sheet.sheet_format = copy(source_sheet.sheet_format)
target_sheet.sheet_properties = copy(source_sheet.sheet_properties)
target_sheet.merged_cells = copy(source_sheet.merged_cells)
target_sheet.page_margins = copy(source_sheet.page_margins)
target_sheet.freeze_panes = copy(source_sheet.freeze_panes)
# set row dimensions
# So you cannot copy the row_dimensions attribute. Does not work (because of meta data in the attribute I think). So we copy every row's row_dimensions. That seems to work.
for rn in range(len(source_sheet.row_dimensions)):
target_sheet.row_dimensions[rn] = copy(source_sheet.row_dimensions[rn])
if source_sheet.sheet_format.defaultColWidth is None:
print('Unable to copy default column wide')
else:
target_sheet.sheet_format.defaultColWidth = copy(source_sheet.sheet_format.defaultColWidth)
# set specific column width and hidden property
# we cannot copy the entire column_dimensions attribute so we copy selected attributes
for key, value in source_sheet.column_dimensions.items():
target_sheet.column_dimensions[key].min = copy(source_sheet.column_dimensions[key].min) # Excel actually groups multiple columns under 1 key. Use the min max attribute to also group the columns in the targetSheet
target_sheet.column_dimensions[key].max = copy(source_sheet.column_dimensions[key].max) # https://stackoverflow.com/questions/36417278/openpyxl-can-not-read-consecutive-hidden-columns discussed the issue. Note that this is also the case for the width, not onl;y the hidden property
target_sheet.column_dimensions[key].width = copy(source_sheet.column_dimensions[key].width) # set width for every column
target_sheet.column_dimensions[key].hidden = copy(source_sheet.column_dimensions[key].hidden)
def copy_cells(source_sheet, target_sheet):
for r, row in enumerate(source_sheet.iter_rows()):
for c, cell in enumerate(row):
source_cell = cell
if isinstance(source_cell, openpyxl.cell.read_only.EmptyCell):
continue
target_cell = target_sheet.cell(column=c+1, row=r+1)
target_cell._value = source_cell._value
target_cell.data_type = source_cell.data_type
if source_cell.has_style:
target_cell.font = copy(source_cell.font)
target_cell.border = copy(source_cell.border)
target_cell.fill = copy(source_cell.fill)
target_cell.number_format = copy(source_cell.number_format)
target_cell.protection = copy(source_cell.protection)
target_cell.alignment = copy(source_cell.alignment)
if not isinstance(source_cell, openpyxl.cell.ReadOnlyCell) and source_cell.hyperlink:
target_cell._hyperlink = copy(source_cell.hyperlink)
if not isinstance(source_cell, openpyxl.cell.ReadOnlyCell) and source_cell.comment:
target_cell.comment = copy(source_cell.comment)
다음과 같은 용도로 사용됩니다.
wb = Workbook()
wb_source = load_workbook(filename, data_only=True, read_only=True)
for sheetname in wb_source.sheetnames:
source_sheet = wb_source[sheetname]
ws = wb.create_sheet("Orig_" + sheetname)
copy_sheet(source_sheet, ws)
wb.save(new_filename)
여러 워크북의 데이터를 하나의 워크북으로 수집해야 하는 유사한 요구사항이 있었습니다.openpyxl에는 내장된 메서드가 없기 때문입니다.
나는 나를 위해 그 일을 하기 위해 아래의 스크립트를 만들었습니다.
참고: 제 사용 사례에서는 모든 워크북에 동일한 형식의 데이터가 포함되어 있습니다.
from openpyxl import load_workbook
import os
# The below method is used to read data from an active worksheet and store it in memory.
def reader(file):
global path
abs_file = os.path.join(path, file)
wb_sheet = load_workbook(abs_file).active
rows = []
# min_row is set to 2, to ignore the first row which contains the headers
for row in wb_sheet.iter_rows(min_row=2):
row_data = []
for cell in row:
row_data.append(cell.value)
# custom column data I am adding, not needed for typical use cases
row_data.append(file[17:-6])
# Creating a list of lists, where each list contain a typical row's data
rows.append(row_data)
return rows
if __name__ == '__main__':
# Folder in which my source excel sheets are present
path = r'C:\Users\tom\Desktop\Qt'
# To get the list of excel files
files = os.listdir(path)
for file in files:
rows = reader(file)
# below mentioned file name should be already created
book = load_workbook('new.xlsx')
sheet = book.active
for row in rows:
sheet.append(row)
book.save('new.xlsx')
해결 방법은 다음과 같습니다.
템플릿 파일이 있는 경우 "template.xlsx"라고 가정합니다.파일을 열고 필요에 따라 변경한 후 새 파일로 저장한 후 파일을 닫습니다.필요에 따라 반복합니다.테스트/메시징을 수행하는 동안 원본 템플릿의 복사본을 보관하십시오.
저는 방금 이 질문을 발견했습니다.여기서 언급한 바와 같이, 좋은 해결책은 원본을 수정하는 것으로 구성될 수 있습니다.wb다른 이름으로 저장할 수 있습니다.예:
import openpyxl
# your starting wb with 2 Sheets: Sheet1 and Sheet2
wb = openpyxl.load_workbook('old.xlsx')
sheets = wb.sheetnames # ['Sheet1', 'Sheet2']
for s in sheets:
if s != 'Sheet2':
sheet_name = wb.get_sheet_by_name(s)
wb.remove_sheet(sheet_name)
# your final wb with just Sheet1
wb.save('new.xlsx')
제가 사용하는 해결 방법은 현재 시트를 판다 데이터 프레임으로 저장하고 필요한 Excel 워크북에 로드하는 것입니다.
그것은 실제로 매우 간단한 방법으로 이루어질 수 있습니다!3단계만 수행하면 됩니다.
load_workbook을 사용하여 파일 열기
wb = load_workbook('File_1.xlsx')
복사할 시트 선택
ws = wb.active
새 파일의 이름을 사용하여 파일을 저장합니다.
wb.save('New_file.xlsx')
이 코드는 첫 번째 파일(File_1.xlsx)의 시트를 두 번째 사운드 파일(New_file.xlsx)에 저장합니다.
openpyxl을 사용함으로써 - 테두리 복사가 성공하지 못했습니다.저의 경우 - xlwings를 사용하여 성공했습니다.OS에서 엑셀을 열고, 탭을 다른 엑셀로 복사하고, 저장하고, 이름을 바꾸고, 닫습니다.
import openpyxl, os
import xlwings as xw
def copy_tab(file_old, tab_source, file_new, tab_destination):
delete_tab = False
if not os.path.exists(file_new):
wb_target = openpyxl.Workbook()
wb_target.save(file_new)
delete_tab = True
wb = xw.Book(file_old)
app = wb.app
app.visible = False
sht = wb.sheets[tab_source]
new_wb = xw.Book(file_new)
new_app = new_wb.app
new_app.visible = False
sht.api.Copy(None, After=new_wb.sheets[-1].api)
if delete_tab:
new_wb.sheets['Sheet'].delete()
wb.close()
for sheet in new_wb.sheets:
if tab_destination in sheet.name:
sheet.delete()
new_wb.sheets[tab_source].name = tab_destination
new_wb.save()
new_wb.close()
if __name__ == "__main__":
file_old = r"C:\file_old.xlsx"
file_new = r"C:\file_new.xlsx"
copy_tab(file_old, "sheet_old", file_new, "sheet_new")
언급URL : https://stackoverflow.com/questions/42344041/how-to-copy-worksheet-from-one-workbook-to-another-one-using-openpyxl
'programing' 카테고리의 다른 글
| Python에서 반복기의 요소 수 가져오기 (0) | 2023.06.13 |
|---|---|
| 루비-oci8을 설치하는 방법은? (0) | 2023.06.13 |
| 이벤트 이미터와 이벤트 이미터의 차이점은 무엇입니까? (0) | 2023.06.13 |
| rbenv install 명령이 누락되었습니다. (0) | 2023.06.13 |
| C++ 애플리케이션에서 Java 메서드에 액세스하는 방법 (0) | 2023.06.08 |