The goal is to copy paste multiple existing sheets out of a workbook into a new workbook using xlwings. I have:
app = xw.App(visible=False)
book = xw.Book(path)
sheet_1 = book.sheets["Sheet1"]
sheet_2 = book.sheets["Sheet2"]
wb_res = xw.Book()
sheet_active = wb_res.sheets.active
sheet_1.api.Copy(Before=sheet_active)
This throws:
TypeError: Objects for SAFEARRAYS must be sequences (of sequences), or a buffer object.
Bonus question for the brave:
- How can I replace all formulas on a sheet for its value?
Thanks
If you can use win32com, you can try this:
from win32com.client import Dispatch
path1 = 'workbook1.xlsx'
path2 = 'workbook2.xlsx'
xl = Dispatch("Excel.Application")
wb1 = xl.Workbooks.Open(Filename=path1)
wb2 = xl.Workbooks.Open(Filename=path2)
ws1 = wb1.Worksheets(1)
ws1.Copy(Before=wb2.Worksheets(1))
wb2.Close(SaveChanges=True)
xl.Quit()
Related
Code :
wb = Workbook()
sdwbb = load_workbook(sdpath)
filename = os.path.basename(sdpath)
bulan = "September"
try:
sdp = sdwbb[bulan]
except:
sdwbb.create_sheet(bulan)
wb.save(filename)
time.sleep(0.5)
sdp = sdwbb[bulan]
cell_one = sdp['F1']
cell_one.value = 'test'
sdwbb.save(filename)
for your information I doesn't get any error but its doesn't write anything cell f1 sheet September
what I trying to do is to write on specific workbook ,sheet ,and cell
This is my code to write "test" in cel F1 (in the current sheet) in the file test.xlxs in the same folder:
from openpyxl import Workbook, load_workbook
wb = load_workbook("test.xlsx")
ws = wb.active
ws["F1"] = "test"
wb.save("test.xlsx")
print("done")
It's as easy as that :).
Also, you should devenitly check out the documentation of openpyxl: https://openpyxl.readthedocs.io/en/stable/tutorial.html#create-a-workbook
wb_cover = xw.Book()
wb_table = xw.Book()
wb1 = xw.Book(path1)
ws1 = wb1.sheets("Table")
ws2 = wb1.sheets("Cover")
ws1.api.Copy(Before=wb_table.sheets(1).api)
ws2.api.Copy(Before=wb_cover.sheets(1).api)
When the sheet gets copied it keeps the same name also on the new file. Is there the possibility to rename the sheets?
All I want to do is copy a worksheet from an excel workbook to another excel workbook in Python.
I want to maintain all formatting (coloured cells, tables etc.)
I have a number of excel files and I want to copy the first sheet from all of them into one workbook. I also want to be able to update the main workbook if changes are made to any of the individual workbooks.
It's a code block that will run every few hours and update the master spreadsheet.
I've tried pandas, but it doesn't maintain formatting and tables.
I've tried openpyxl to no avail
I thought xlwings code below would work:
import xlwings as xw
wb = xw.Book('individual_files\\file1.xlsx')
sht = wb.sheets[0]
new_wb = xw.Book('Master Spreadsheet.xlsx')
new_wb.sheets["Sheet1"] = sht
But I just get the error:
----> 4 new_wb.sheets["Sheet1"] = sht
AttributeError: __setitem__
"file1.xlsx" above is an example first excel file.
"Master Spreadsheet.xlsx" is my master spreadsheet with all individual files.
In the end I did this:
def copyExcelSheet(sheetName):
read_from = load_workbook(item)
#open(destination, 'wb').write(open(source, 'rb').read())
read_sheet = read_from.active
write_to = load_workbook("Master file.xlsx")
write_sheet = write_to[sheetName]
for row in read_sheet.rows:
for cell in row:
new_cell = write_sheet.cell(row=cell.row, column=cell.column,
value= cell.value)
write_sheet.column_dimensions[get_column_letter(cell.column)].width = read_sheet.column_dimensions[get_column_letter(cell.column)].width
if cell.has_style:
new_cell.font = copy(cell.font)
new_cell.border = copy(cell.border)
new_cell.fill = copy(cell.fill)
new_cell.number_format = copy(cell.number_format)
new_cell.protection = copy(cell.protection)
new_cell.alignment = copy(cell.alignment)
write_sheet.merge_cells('C8:G8')
write_sheet.merge_cells('K8:P8')
write_sheet.merge_cells('R8:S8')
write_sheet.add_table(newTable("table1","C10:G76","TableStyleLight8"))
write_sheet.add_table(newTable("table2","K10:P59","TableStyleLight9"))
write_to.save('Master file.xlsx')
read_from.close
With this to check if the sheet already exists:
#checks if sheet already exists and updates sheet if it does.
def checkExists(sheetName):
book = load_workbook("Master file.xlsx") # open an Excel file and return a workbook
if sheetName in book.sheetnames:
print ("Removing sheet",sheetName)
del book[sheetName]
else:
print ("No sheet ",sheetName," found, will create sheet")
book.create_sheet(sheetName)
book.save('Master file.xlsx')
with this to create new tables:
def newTable(tableName,ref,styleName):
tableName = tableName + ''.join(random.choices(string.ascii_uppercase + string.digits + string.ascii_lowercase, k=15))
tab = Table(displayName=tableName, ref=ref)
# Add a default style with striped rows and banded columns
tab.tableStyleInfo = TableStyleInfo(name=styleName, showFirstColumn=False,showLastColumn=False, showRowStripes=True, showColumnStripes=True)
return tab
Adapted from this solution, but note that in my (limited) testing (and as observed in the other Q&A), this does not support the After parameter of the Copy method, only Before. If you try to use After, it creates a new workbook instead.
import xlwings as xw
wb = xw.Book('individual_files\\file1.xlsx')
sht = wb.sheets[0]
new_wb = xw.Book('Master Spreadsheet.xlsx')
# copy this sheet into the new_wb *before* Sheet1:
sht.api.Copy(Before=new_wb.sheets['Sheet1'].api)
# now, remove Sheet1 from new_wb
new_wb.sheets['Sheet1'].delete()
This can be done using pywin32 directly. The Before or After parameter needs to be provided (see the api docs), and the parameter needs to be a worksheet <object>, not simply a worksheet Name or index value. So, for example, to add it to the end of an existing workbook:
def copy_sheet_within_excel_file(excel_filename, sheet_name_or_number_to_copy):
excel_app = win32com_client.gencache.EnsureDispatch('Excel.Application')
wb = excel_app.Workbooks.Open(excel_filename)
wb.Worksheets[sheet_name_or_number_to_copy].Copy(After=wb.Worksheets[wb.Worksheets.Count])
new_ws = wb.ActiveSheet
return new_ws
As most of my code runs on end-user machines, I don't like to make assumptions whether Excel is open or not so my code determines if Excel is already open (see GetActiveObject), as in:
try:
excel_app = win32com_client.GetActiveObject('Excel.Application')
except com_error:
excel_app = win32com_client.gencache.EnsureDispatch('Excel.Application')
And then I also check to see if the workbook is already loaded (see Workbook.FullName). Iterate through the Application.Workbooks testing the FullName to see if the file is already open. If so, grab that wb as your wb handle.
You might find this helpful for digging around the available Excel APIs directly from pywin32:
def show_python_interface_modules():
os.startfile(os.path.dirname(win32com_client.gencache.GetModuleForProgID('Excel.Application').__file__))
I'm using openpyxl for the first time. I have to read excel file, then after manipulation, populate the result on three different excel sheets -> sheet_T, sheet_D and sheet_U. I created three sheets using openpyxl as follows-
sheet_T = filename2.create_sheet(0)
sheet_T.title = "Target First"
sheet_D = filename2.create_sheet(1)
sheet_D.title = "Distractor First"
sheet_U = filename2.create_sheet(2)
sheet_U.title = "Unclassified"
I used xlwt to do it but there is a constraint of 256 columns. Hence, I used openpyxl. The below code is written by using xlwt-
sheet_T.write(row_first, col_target, Name_Target)
sheet_D.write(row_first, col_target, Name_Target)
sheet_U.write(row_first, col_target, Name_Target)
How do I write the same thing by using openpyxl? All the documentation I read is how to write on a specific cell not sheet.
Many thanks for the help!
You need to create another sheet:
from openpyxl.workbook import Workbook
from openpyxl.writer.excel import ExcelWriter
wb = Workbook()
ws0 = wb.worksheets[0]
ws0.title = 'My Sheet 1'
ws1 = wb.create_sheet()
ws1.title = 'My Sheet 2'
ws2 = wb.create_sheet()
ws2.title = 'My Sheet 3'
Now you can write to the different sheets:
cell_ws0_a1 = ws0.cell('A1')
cell_ws0_a1.value = 'Wrote to cell in 1st sheet.'
cell_ws1_a1 = ws1.cell('A1')
cell_ws1_a1.value = 'Wrote to cell in 2nd sheet.'
cell_ws2_a1 = ws2.cell('A1')
cell_ws2_a1.value = 'Wrote to cell in 3rd sheet.'
writer = ExcelWriter(workbook=wb)
writer.save('example.xlsx')
There is only one sheet in a workbook by default. wb.create_sheet() creates a second sheet.
I would like to make a correction in the code for smooth running-
from openpyxl.workbook import Workbook
from openpyxl.writer.excel import ExcelWriter
wb = Workbook()
ws0 = wb.worksheets[0]
ws0.title = 'My Sheet 1'
ws1 = wb.create_sheet()
ws1.title = 'My Sheet 2'
ws2 = wb.create_sheet()
ws2.title = 'My Sheet 3
v1 = ws1.cell(row=1, column=1)
v1.value = "Hello"
(Basically insert values in this manner instead)
And then end with-
writer = ExcelWriter(wb, 'file.xlsx')
wb.save('file.xlsx')
Hope this helps :)
I am trying to activate multiple excel worksheets and write to both multiple sheets within both workbook(s) using python and openpyxl. I am able to load the second workbook f but I am unable to append cell G2 of my second workbook with the string Recon
from openpyxl import Workbook, load_workbook
filename = 'sda_2015.xlsx'
wb = Workbook()
ws = wb.active
ws['G1'] = 'Path'
ws.title = 'Main'
adf = "Dirty Securities 04222015.xlsx"
f = "F:\\ana\\xlmacro\\" + adf
wb2 = load_workbook(f)
"""
wb22 = Workbook(wb2)
ws = wb22.active
ws['G1'] = "Recon2"
ws.title = 'Main2'
"""
print wb2.get_sheet_names()
wb.save(filename)
I commented out the code which is broken
Update
I adjusted my code with the below answer. The value in cell H1 is written onto wb2 in column H, but for some reason the column is hidden. I have adjusted the column to other columns but still I have seen the code hide multiple columns. There are also occurences when the code executes and titles ws2 as Main21 but the encoded value is Main2
from openpyxl import Workbook, load_workbook
filename = 'sda_2015.xlsx'
wb1 = Workbook()
ws1 = wb1.active
ws1['G1'] = 'Path'
ws1.title = 'Main'
adf = "Dirty Securities 04222015.xlsx"
f = "F:\\ana\\xlmacro\\" + adf
wb2 = load_workbook(f)
ws2 = wb2.active
ws2['H1'] = 'Recon2'
ws2.title = 'Main2'
print wb2.get_sheet_names()
wb1.save(filename)
wb2.save(f)
If you have two workbooks open, wb1 and wb2, you'll also need different names for the various worksheets: ws1 = wb1.active and ws2 = wb2.active.
If you're working with a file with macros, you'll need to set the keep_vba flag to True when opening it in order to preserve the macros.
I had experienced the same thing with hidden cells. Eventually, I unpacked the Excel file and looked at the raw XML to find out that not all of the columns had a dimension for width. Those without a width were being by Excel.
A quick fix is to do something like this...
for col in 'ABCDEFG':
if not worksheet.column_dimensions[col].width:
worksheet.column_dimensions[col].width = 10