Where I have a cell in an .xlsx file that is "=..." I want to replace the "=" with '=, so can see the cells as strings rather than as the values.
For example,
A1 = 5
A2 = 10
A3 = (A1/A2) = 0.5
I want to see =A1/A2 rather than 0.5.
Thank you in advance for any and all help.
As suggested openpyxl solves this problem:
import openpyxl
from openpyxl.utils.cell import get_column_letter
wb = openpyxl.load_workbook('example.xlsx')
wb.sheetnames
sheet = wb["Sheet1"]
amountOfRows = sheet.max_row
amountOfColumns = sheet.max_column
for i in range(amountOfColumns):
for k in range(amountOfRows):
cell = str(sheet[get_column_letter(i+1)+str(k+1)].value)
if( str(cell[0]) == "="):
newCell = "'=,"+cell[1:]
sheet[get_column_letter(i+1)+str(k+1)]=newCell
wb.save('example_copy.xlsx')
Related
I have a list value and want to assign it into a column in a excel file. The values I want to change are in sheet 6.
my poor code looks something like this the best I could do is try to first change the AF6:AF22 to a fixed value 5 with hope that I could change it to list.
But is there a simple way to change AF6:AF22 values to a list?
something simple ws['AF6:AF22'] = l?
from openpyxl import Workbook
import pandas as pd
from openpyxl import load_workbook
l = list(range(5))
FilePath = 'excel_file.xlsx'
wb = load_workbook(FilePath)
ws = wb.worksheets
sheet_number = 6
for sheet_number in ws.iter_cols('AF6:AF22'):
for cell in sheet_number:
cell.value = 5
Option 1
Hi - I am adding a faster way here. This is probably better as it avoids the for loop and updating cells one at a time.
from openpyxl import Workbook
import pandas as pd
from openpyxl import load_workbook
l = list(range(17)) #The list - You can replace l with whatever you need
with pd.ExcelWriter('excel_file.xlsx', mode='a', engine = 'openpyxl') as writer:
pd.DataFrame(l).to_excel(writer, sheet_name='Sheet6', startrow = 5, startcol= 31, index=False, header=None)
Option 2
You can use the below code to do what you need. Added comments, so you get an understanding of my logic...
from openpyxl import Workbook
import pandas as pd
from openpyxl import load_workbook
l = list(range(17)) #The list - You can replace l with whatever you need
FilePath = 'excel_file.xlsx'
wb = load_workbook(FilePath)
ws = wb.worksheets[5] #Worksheet 5 is the 6th sheet as numbering starts from zero
for i in range(6,23): # Column numbers 6 through 22
ws.cell(row=i, column=32).value = l[i-6] #Write to cell in AF = column 32
wb.save("excel_file.xlsx")
I am trying to create an automatic numbering system with leading zeros in Python and openpyxl.
What is the best way to define the columns?
I would like to name them first and then say for each column what needs to be done.
Go to column 1 and put a numbering in it from 00001 to 00500.
Go to column 2 and put a numbering in there from 00501 to 01000.
...
In my opinion if I have these I can make any variants I want.
from openpyxl import Workbook, load_workbook
wb = Workbook()
ws = wb.active
ws.title = "Numbers"
ws.append(['N1','N2'])
#create Leading zero's
#zero_filled_number = number_str.zfill(5)
#print(zero_filled_number)
# Here I get stuck
for i in ws.append_columns(0)
i = range (1,500,1) number_str.zfill(5)
#ws.append_columns(1)
#for N2 in range (501,1000,1) number_str.zfill(5)
wb.save('Auto_numbers.xlsx')
from openpyxl import Workbook
import openpyxl
wb = Workbook()
sheet = wb.active
test_file = openpyxl.load_workbook('test.xlsx')
sheet = test_file.active
sheet['A1'] = 'ID'
counter = sheet.max_row
while counter < 10:
for row in sheet.rows:
counter += 1
sheet[f'A{counter}'] = f'N{counter}'
sheet.append([f'N{counter}'])
test_file.save('test.xlsx')
I am trying to do something like grabbing all values in each cell while they are referencing one by one. Maybe an example help illustration.
Example:
A
B
C
=B2
='I am' & C2
'Peter
Example2 - in term of number:
A
B
C
D
=B2
=C2*D2
12
56
So I want to get a concat string 'I am Peter' or 672 (from 12*56) when I reading the cell A2
Code I tried:
from openpyxl import load_workbook
import pandas as pd
wb = load_workbook(filename = 'new.xlsx')
sheet_names = wb.get_sheet_names()
name = sheet_names[0]
sheet_ranges = wb[name]
df = pd.DataFrame(sheet_ranges.values)
print(df)
The formula will become 'NaN'
Any suggestion to achieve it? Thanks!
If you want to have the actual values of the cells, you have to use data_only=True
wb = load_workbook(filename = 'new.xlsx', data_only=True)
Look here: Read Excel cell value and not the formula computing it -openpyxl
Anyway, as you use pandas, it would be way easier to go directly:
import pandas as pd
df = pd.read_excel('new.xlsx')
print(df)
which grabs the first sheet (but could be specified) and gives the values as output.
openpyxl supports either the formula or the value of the formula. You can select which using the data_only parameter when loading a workbook.
You can change your code like below:
from openpyxl import load_workbook
import pandas as pd
wb = load_workbook(filename='new.xlsx', data_only=True)
sheet_names = wb.get_sheet_names()
name = sheet_names[0]
sheet_ranges = wb[name]
df = pd.DataFrame(sheet_ranges.values)
print(df)
Is it possible to create a python script to automatic which is subtract cell value with 2 worksheet in one excel file?
I have checked some documents, and seem that use the method of pandas or openpyxl to do so. But I can't to do that. Do you have any suggestion to me? Many thanks.
Script:
from datetime import datetime
import pandas as pd
import openpyxl as xl;
currDateTime = datetime.now()
Sheet1 ="C:\\Users\\peter\\Downloads\\" + currDateTime.strftime('%Y%m%d') + "\\5250A" + "\\5250A.xlsx"
wb3 = xl.load_workbook(Sheet1)
ws3 = wb3.worksheets[0]
wb4 = xl.load_workbook(Sheet1)
ws4 = wb4.worksheets[1]
wb5 = xl.load_workbook(Sheet1)
ws5 = wb5.create_sheet("Done")
wb4.subtract(wb3)
wb5.save(str(Sheet1))
Expected Result:
Do so in excel coule be way easier I think. There could be a smarter way to write this code.
[NOTE] I just do the subsctraction cell by cell, so if there's any mismatch like same row but different dept.id or same col but different item will make errors. If you may meet this situation, you'll have a change some in the following code.
import openpyxl as xl
def get_row_values(worksheet):
"""
return data structure:
[
[A1, B1, C1, ...],
[A2, B2, C2, ...],
...
]
"""
result = []
for i in worksheet.rows:
row_data = []
for j in i:
row_data.append(j.value)
result.append(row_data)
return result
if __name__ == '__main__':
# load excel file
wb = xl.load_workbook('test1.xlsx')
ws1 = wb.worksheets[0]
ws2 = wb.worksheets[1]
# get data from the first 2 worksheets
ws1_rows = get_row_values(ws1)
ws2_rows = get_row_values(ws2)
# calculate and make a new sheet
ws_new = wb.create_sheet('Done')
# insert header
ws_new.append(ws1_rows[0])
for row in range(1, len(ws1_rows)):
# do the substract cell by cell
row_data = []
for column, value in enumerate(ws1_rows[row]):
if column == 0:
# insert first column
row_data.append(value)
else:
if ws1_rows[row][0] == ws2_rows[row][0]:
# process only when first column match
row_data.append(value - ws2_rows[row][column])
ws_new.append(row_data)
wb.save('test2.xlsx')
here's my sample excel file
first sheet:
second sheet:
generated sheet:
I would like to copy an Excel worksheet in Python using openpyxl. However, it defaults to placing the copied worksheet at the end. I want it at the front. The copy_worksheet doesn't allow specifying the position, unlike create_sheet. I'd rather not have to recreate the template.
I've considered sorting the sheets, but I'm not sure how to implement that.
Suppose I have a file called number.xlsx with an existing worksheet titled "blank" that I want to copy.
from openpyxl import load_workbook
from datetime import datetime
n = float(input("Number: "))
today = datetime.now()
m = today.month
d = today.day
y = str(today.year)
wb = load_workbook('number.xlsx')
if y in wb.sheetnames:
ws = wb[y]
ws.cell(row = 2 + d, column = 1 + m).value = n
wb.save('number.xlsx')
else:
ws = wb.copy_worksheet(wb["blank"]) #I want the copied sheet at the front, not the back
ws.title = y
ws.cell(row = 2 + d, column = 1 + m).value = n
wb.save('number.xlsx')
You can use move_sheet(sheet, offset=0) method for this. Here offset calculated as "current sheet index" + offset. Copy worksheet will add the sheet to the last of the workbook. So you need to give negative value to move sheet to index 0.
from openpyxl import load_workbook
wb = load_workbook("text.xlsx")
ws = wb.copy_worksheet(wb["sample"])
ws.title = "NewNameForCopiedSheet"
wb.move_sheet("NewNameForCopiedSheet", -(len(wb.sheetnames)-1))
I am posting an example
wb._sheets is what you use to control the order of tabs/sheets.
Get the position of sheet you want to rearrange and modify the list of sheets with new positions.
from openpyxl import Workbook
wb=Workbook()
# wb.create_sheet("Sheet")
wb.create_sheet("Sheet2")
wb.create_sheet("Sheet3")
wb.create_sheet("SheetA")
wb.create_sheet("ASheet")
wb.create_sheet("blank")
wb.save('book_original.xlsx')
blank_sheet_position = wb.worksheets.index(wb['blank'']) #get position of new sheet
blank_sheet_new_position = 0 #position where you want to move
sheets = wb._sheets.copy()
sheets.insert(blan_sheet_new_position, sheets.pop(blank_sheet_position))) #modifying the sheets list
wb._sheets = sheets
wb.save('book_myorder.xlsx')