I'm having trouble extracting the styles from an excel worksheet using openpyxl, in the case below I'm creating a spreadsheet, and I can see that the formatting is correct, but I don't know how to get that data back.
In my real use case I'm just reading a file - I'm not the one creating it, so I'd like to be able to programmatically retrieve the formatting.
from openpyxl import Workbook
from openpyxl.reader.excel import load_workbook
from openpyxl.style import Color, Fill
#this is all setup
wb = Workbook()
dest_filename = 'c:\\temp\\test.xlsx'
ws = wb.worksheets[0]
ws.title = 'test'
ws.cell('A1').value = 'foo'
ws.cell('A1').style.font.bold = True
ws.cell('B1').value = 'bar'
ws.cell('B1').style.fill.fill_type = Fill.FILL_SOLID
ws.cell('B1').style.fill.start_color.index = Color.DARKYELLOW
wb.save(filename = dest_filename )
#setup complete
book = load_workbook( filename = dest_filename )
sheet = book.get_sheet_by_name('test')
#value work properly
print sheet.cell('A1').value #returns foo
print sheet.cell('B1').value #return bar
#formatting does not - THIS IS THE PROBLEM CODE
print sheet.cell('A1').style.font.bold #returns False
print sheet.cell('B1').style.fill.fill_type #returns none
print sheet.cell('B1').style.fill.start_color.index #returns FFFFFFFF
print sheet.cell('B1').has_style #returns true
#but these 2 return the same values! even thought C1 was never set and should be different
print sheet.get_style('A1')
print sheet.get_style('C1')
Related
wrbk = xlrd.open_workbook("D:Book1.xlsx")
idx = 0
book_1 = xlrd.open_workbook("D:Book2.xlsx")
sh_1 = book_1.sheet_by_name('Sheet4')
i = 0
for x in range(sh_1.nrows):
i = i + 1
if i >= sh_1.nrows:
break
if sh_1.cell(i, 2).value:
concat = sh_1.cell(i, 2).value
for y in range(len(wrbk.sheets())):
sht = wrbk.sheet_by_index(y)
for j in range(sht.ncols):
for cell in range(sht.nrows):
list = str(sht.cell(cell, j).value)
if list.__contains__(concat):
print(sh_1.cell(i, 2).value)
Im using this code to find a value in a workbook and then search that value in another workbook.
I'm using xlrd, the output is fine so far but i can't read and write with xlrd.i need suggestions to change this code from xlrd to openpyxl.
This defines a function to do the search and uses a Regular Expression to do the 'contains' match. Change the print to suit.
from openpyxl import load_workbook
import re
# open workbook
excel_file1 = 'D:Book1.xlsx'
wb1 = load_workbook(excel_file1) # wrbk
ws1 = wb1["Sheet1"]
excel_file2 = 'D:Book2.xlsx'
wb2 = load_workbook(excel_file2) # book_1
ws2 = wb2["Sheet4"] # sh_1
# fn to search all sheets in workbook
def myfind(wb,s):
for ws in wb.worksheets:
for c in range(1,ws.max_column+1):
for r in range(1,ws.max_row+1):
txt = ws.cell(r,c).value
if txt is None:
pass
elif re.search(s,txt):
print("Found",s,txt,ws,r,c)
# scan col C
for r in range(1,ws2.max_row+1):
s = ws2.cell(r, 3).value
if s is None:
pass
else:
print(r,s)
myfind(wb1,s)
I have a large number of Excel sheets that I want to iterate through and update the first-page footer and set the worksheet to "Different first page" on them using openpyxl. The following code works to open the excel file, alter the first-page footer but I cannot find in the docs how to change which footer is the active one for printing. Is this even possible?
https://openpyxl.readthedocs.io/en/stable/api/openpyxl.worksheet.header_footer.html
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
filename = '150913M2_IS.xlsm'
wb = load_workbook(filename, read_only=False, keep_vba=True)
ws = wb.active
#Attempted setting this value to True but this does nothing
ws.differentFirst = True
#This works perfectly to set the first page footer
#but I have to manually go in and change the Excel sheet
#to 'Different first page'
ws.firstFooter.left.text = 'Hello World'
wb.save(filename)
Question: set active header/footer type
HeaderFooter
HeaderFooterItem
class _HeaderFooterPart:
def __init__(self, text=None, font=None, size=None, color=None):
self.text = text
self.font = font
self.size = size
self.color = color
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws.HeaderFooter.differentFirst = True
ws.HeaderFooter.firstFooter.left.text = 'Hello World'
print(ws.HeaderFooter.firstFooter.left.text)
>>> Hello World
# wb.save(<File Name>)
Tested with Python 3.6 - openpyxl 3.0.0
I'm trying to copy a worksheet from one excel file, to a worksheet on different excel file. But the problem is it is adding it as a additional sheet and not pasting on the existing sheet and overwriting the sheet. I know that I am using Before=wb2.Worksheets(1) which adds the new sheet before the existing sheet, but what is the argument to paste onto the existing sheet instead?
import time, os.path, os
from win32com.client import Dispatch
path1 = 'C:\\example.xlsx'
path2 = 'C:\\Todolist2.xlsx'
path3 = 'C:\\example2.xlsx'
xl = Dispatch("Excel.Application")
xl.Visible = True
wb1= xl.Workbooks.Open(Filename=path1)
wb2= xl.Workbooks.Open(Filename=path2)
ws1 = wb1.Worksheets(1)
ws1.Copy(Before=wb2.Worksheets(1))
One way to do it is using openpyxl library. If the cell has style, we can copy it to new sheet also.
import openpyxl as xl
from copy import copy
path1 = 'C:\\example.xlsx'
path2 = 'C:\\Todolist2.xlsx'
wb1 = xl.load_workbook(filename=path1)
ws1 = wb1.worksheets[0]
wb2 = xl.load_workbook(filename=path2)
ws2 = wb2.worksheets[0]
for row in ws1:
for cell in row:
ws2[cell.coordinate].value = cell.value
if cell.has_style:
ws2[cell.coordinate].font = copy(cell.font)
ws2[cell.coordinate].border = copy(cell.border)
ws2[cell.coordinate].fill = copy(cell.fill)
ws2[cell.coordinate].number_format = copy(cell.number_format)
ws2[cell.coordinate].protection = copy(cell.protection)
ws2[cell.coordinate].alignment = copy(cell.alignment)
wb2.save(path2)
Then you will see your sheet2 is replaced by sheet1.
#tomcy
The code is below. What I am really trying to accomplish is to be able to keep rewriting data to Todolist2.xlsx. I would really want to have Todolist2.xlsx open in excel application in windows and have it update the sheet whenever there is new data. So far I have found two ways to do this. One is the code you are helping me with using openpyxl. Doing it this way I think I will have to write data to Todolist2 then open. Then with new data, it will have to close before writing data back in. Then reopen it again. Below is what I have so far. Using the 10 sleep to allow me the chance to update example.xlsx so as to simulate writing new data to Todolist2. It works the first go, but on the second, it gives me permission denied to Todolist2.
import openpyxl as xl
from copy import copy
import time
path1 = 'C:\\example.xlsx'
path2 = 'C:\\Todolist2.xlsx'
wb1 = xl.load_workbook(filename=path1)
ws1 = wb1.worksheets[0]
wb2 = xl.load_workbook(filename=path2)
ws2 = wb2.worksheets[0]
while True:
for row in ws1:
for cell in row:
ws2[cell.coordinate].value = cell.value
if cell.has_style:
ws2[cell.coordinate].font = copy(cell.font)
ws2[cell.coordinate].border = copy(cell.border)
ws2[cell.coordinate].fill = copy(cell.fill)
ws2[cell.coordinate].number_format =
copy(cell.number_format)
ws2[cell.coordinate].protection = copy(cell.protection)
ws2[cell.coordinate].alignment = copy(cell.alignment)
wb2.save(path2)
wb2.close()
time.sleep(10) #during this time I will modify example.xlsx and
#save, so on the next go around it rewrites the
#new data to Todolist1.xlsx
The second way I'm trying to solve this is with win32com. This allows me to keep Todolist2 open in excel in windows while it writes to it from example, example1, then example2. But the problem is, it does not write on the activesheet, it keeps adding additional sheets. So on this one, If I can find a way to keep rewriting over the active sheet in Todolist2 or after it adds the additional sheet, if I can only delete one sheet i'm golden.
import time, os.path, os
from win32com.client import Dispatch
path1 = 'C:\\example.xlsx'
path2 = 'C:\\Todolist2.xlsx'
path3 = 'C:\\example2.xlsx'
path4 = 'C:\\example3.xlsx'
xl = Dispatch("Excel.Application")
xl.Visible = True
wb1= xl.Workbooks.Open(Filename=path1)
wb2= xl.Workbooks.Open(Filename=path2)
ws1 = wb1.Worksheets(1)
ws1.Copy(Before=wb2.Worksheets(1))
time.sleep(5)
wb3= xl.Workbooks.Open(Filename=path3)
ws3 = wb3.Worksheets(1)
ws2 = wb2.Worksheets(3) #it seems by using (3) is the only way it
#allows me to delete one sheet before it
#adds another.
ws2.Delete()
ws3.Copy(Before=wb2.Worksheets(1))
time.sleep(5)
wb4= xl.Workbooks.Open(Filename=path4)
ws4 = wb4.Worksheets(1)
ws2.Delete() #I got into trouble here, and throws error even
#though it does the delete and copy
ws4.Copy(Before=wb2.Worksheets(1))
How to copy a worksheet from one excel file to another?
from openpyxl import load_workbook
from copy import copy
def copySheet(target, source):
for (row, col), source_cell in source._cells.items():
target_cell = target.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)
for attr in ('row_dimensions', 'column_dimensions'):
src = getattr(source, attr)
trg = getattr(target, attr)
for key, dim in src.items():
trg[key] = copy(dim)
trg[key].worksheet = trg
target.sheet_format = copy(source.sheet_format)
target.sheet_properties = copy(source.sheet_properties)
target.merged_cells = copy(source.merged_cells)
target.page_margins = copy(source.page_margins)
target.page_setup = copy(source.page_setup)
target.print_options = copy(source.print_options)
"copy to"
wb1 = load_workbook(path_to)
target = wb1.create_sheet("lol")
"copy from"
wb2 = load_workbook(path_from)
source = wb2.active
copySheet(target=target, source=source)
wb1.save("fusion.xlsx")
I am trying to read in multiple excel files and append the data from each file into one master file. Each file will have the same headers (So I can skip the import of the first row after the initial file).
I am pretty new to both Python and the OpenPyXL module. I am able to import the first workbook without problem. My problem comes in when I need to open the subsequent file and copy the data to paste into the original worksheet.
Here is my code so far:
# Creating blank workbook
from openpyxl import Workbook
wb = Workbook()
# grab active worksheet
ws = wb.active
# Read in excel data
from openpyxl import load_workbook
wb = load_workbook('first_file.xlsx') #explicitly loading workbook, will automate later
# grab active worksheet in current workbook
ws = wb.active
#get max columns and rows
sheet = wb.get_sheet_by_name('Sheet1')
print ("Rows: ", sheet.max_row) # for debugging purposes
print ("Columns: ", sheet.max_column) # for debugging purposes
last_data_point = ws.cell(row = sheet.max_row, column = sheet.max_column).coordinate
print ("Last data point in current worksheet:", last_data_point) #for debugging purposes
#import next file and add to master
append_point = ws.cell(row = sheet.max_row + 1, column = 1).coordinate
print ("Start new data at:", append_point)
wb = load_workbook('second_file.xlsx')
sheet2 = wb.get_sheet_by_name('Sheet1')
start = ws.cell(coordinate='A2').coordinate
print("New data start: ", start)
end = ws.cell(row = sheet2.max_row, column = sheet2.max_column).coordinate
print ("New data end: ", end)
# write a value to selected cell
#sheet[append_point] = 311
#print (ws.cell(append_point).value)
#save file
wb.save('master_file.xlsx')
Thanks!
I don't really understand your code. It looks too complicated. When copying between worksheets you probably want to use ws.rows.
wb1 = load_workbook('master.xlsx')
ws2 = wb1.active
for f in files:
wb2 = load_workbook(f)
ws2 = wb2['Sheet1']
for row in ws2.rows[1:]:
ws1.append((cell.value for cell in row))
I just started working with openpyxl a couple of days ago and its a great library. However, the documentation seems to be sparse for advanced features. I have a couple of issues.
openpyxl seems to change the formula that I insert to a lower case which results in an unknown reference from excel.
furthermore, i changed the name of the sheet to accomidate the lowercase and still found a #NAME? error in the cell where the reference was at.
Can someone please show me how or where to find out how to reference a cell from another sheet in openpyxl
import openpyxl.Workbook
wb = Workbook()
ws = wb.get_active_sheet()
#shows up lowercase with name error in excel
ws.cell('A1).value = "$'Sheet'.E7 + 123"
#still shows a name error in excel
ws.cell('A2').value = "$'sheet'.E7 + 123"
Try this:
from openpyxl import Workbook
wb = Workbook()
ws = wb.create_sheet()
ws.title ='NewSheet'
ws.cell('E7').value = 7
ws = wb.create_sheet()
ws.cell('A1').value = "=NewSheet!E7 + 123"
wb.save( filename = 'temp2.xlsx' )
from openpyxl import Workbook, utils
wb = Workbook()
ws = wb.create_sheet()
ws.title ='NewSheet'
ws.cell('E7').value = 7
ws = wb.create_sheet()
ws.cell('A1').value = f"={utils.quote_sheetname(ws.title)}!E7 + 123"
wb.save( filename = 'temp2.xlsx' )
The problem with the previous answer is that it's dependant on the title of the sheet being 'NewSheet'. Using quote_sheetname()controls that.