Python Openpyxl schedule replace timestamp range with string - python-3.x

I have workers that starts and end their workdays different times. I get a *.xlsx from a old schedule
program where i see their schedule. I want to replace their time with a string instead.
For example:
'13:00 - 21:30', '13:30 - 21:30','14:00 - 21:30','15:00 - 21:30' with a single 'name'('a-tur').
my code so far is:
from openpyxl import Workbook
from openpyxl import load_workbook
from openpyxl.utils.cell import get_column_letter
wb = load_workbook('sample.xlsx')
ws = wb.active
wb.sheetnames
worksheet = wb["Sheet"]
antal_rader = ws.max_column
antal_kolumn = ws.max_row
for r in range(antal_rader):
for c in range(antal_kolumn):
cellValue = str(worksheet[get_column_letter(r+1)+str(c+1)].value)
if cellValue == 'a':
worksheet[get_column_letter(r+1)+str(c+1)] = 'a-tur'
wb.save('sample.xlsx')
Thanks for all the help i can get.
Sincerely
Dan

for r in range(antal_rader):
for c in range(antal_kolumn):
cellValue = str(worksheet[get_column_letter(r+1)+str(c+1)].value)
# change cell to "a-tur"
if cellValue[0:2] == '07' and time_in_range(start_a, end_a, datetime.time(int(cellValue[8:10]), int(cellValue[11:13], 0))):
worksheet[get_column_letter(r+1)+str(c+1)] = 'a-tur'
# change cell to "c-tur"
elif cellValue[8:10] == '21' and time_in_range(start_c, end_c, datetime.time(int(cellValue[0:2]), int(cellValue[3:5], 0))):
worksheet[get_column_letter(r+1)+str(c+1)] = 'c-tur'
# change cell to "natt"
elif cellValue[0:2] == '21':
worksheet[get_column_letter(r+1)+str(c+1)] = 'natt'

Related

Find next empty column to write query data in Excel using Python (

I'm using pandas to fetch query results from Oracle and I want to write it to an Excel file and put the data in the first column that is empty, so the first time should be Column A, next time I run this program it should add the data into Column B etc.
I'm using openpyxl to write this data using the max_row / max_column method I found. I've been searching for awhile and cannot find a way to use openpyxl to do it in the next empty column though.
main_file = glob('C:\\Users\\dataTemplate.xlsx')[0]
nwb = load_workbook(main_file)
nws = nwb.worksheets[0]
copy_file = (
r'C:\\Users\\queryData.xlsx')
cwb = load_workbook(copy_file)
cws = cwb.worksheets[0]
#Updated
nmc = nws.max_column + 1
mr = cws.max_row
mc = cws.max_column
for i in range(1, mr + 1):
for j in range(1, mc + 1):
c = cws.cell(row=i, column=j)
nws.cell(row=i, column=nmc + j).value = c.value
Update
As you use pandas, you can use the following code:
with pd.ExcelWriter('data.xlsx', engine='openpyxl', mode='a', if_sheet_exists='overlay') as writer:
wb = writer.book
ws = wb.active
df.to_excel(writer, startrow=ws.min_row-1, startcol=ws.max_column, index=False)
Old answer
You can use ws.max_column and ws.max_row:
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
wb = load_workbook('test.xlsx')
ws = wb.active
Output:
>>> ws.max_row
5
>>> ws.max_column
9
>>> get_column_letter(ws.max_column)
'I'
My excel file:

Python deleting row which not contains specific value?

If the ninth column doesn't contains the name of city ISTANBUL, then I need to be able to delete
the entire row. i wrote the code it works but it doesn't delete row.
from openpyxl import Workbook, load_workbook
from openpyxl.utils import get_column_letter
wb = load_workbook('deneme.xlsx')
ws = wb.active
for row in range(1, 3313):
for col in [9]:
char = get_column_letter(col)
if ws[char + str(row)].value is not 'İSTANBUL':
ws.delete_rows(row)
wb.save('deneme.xlsx')
Here it is solution i just found.
import pandas as pd
df = pd.read_excel('staji.xlsx') #here you can put your file path
filt = (df['ŞEHİR'] == 'İSTANBUL') # put your condition ŞEHİR=column name.
df[filt].to_excel('den1.xlsx')

How to read visible-only cells using Python?

I want to read and merge only visible cells in Excel, but I failed.
Also, I've tried openpyxl but didn't work. (Find my second code)
Is there any other ways to read only visible cells and paste on new excel?
I want to read only visible cells because sometimes they need to be filtered or hidden.
Please kindly advise me.
What kind of module should I put in?
If every excel module cannot do that, please also let me know.
My current code:
import os
import glob
import xlwings as xw
import xlrd
import xlsxwriter
xw.App().visible = False
path = os.getcwd()
x=input('name:') + '.xlsx'
target_xls = os.path.join(path,x)
data = []
for file in glob.glob(path+'\*.*'):
if file.endswith((".xls", ".xlsm", ".xlsx")):
wb = xlrd.open_workbook(file)
for sheet in wb.sheets():
for rownum in range(sheet.nrows):
data.append(sheet.row_values(rownum))
workbook = xlsxwriter.Workbook(target_xls)
worksheet = workbook.add_worksheet()
for i in range(len(data)):
print(range(len(data)))
for j in range(len(data[i])):
worksheet.write(i, j, data[i][j])
workbook.close()
My openpyxl code:
import os
import glob
import xlwings as xw
import xlrd
import xlsxwriter
from openpyxl import load_workbook
xw.App().visible = False
path = os.getcwd()
x = input('name:') + '.xlsx'
target_xls = os.path.join(path, x)
data = []
wb = load_workbook('sample.xlsx')
ws = wb['Sheet1']
for row in ws:
if ws.row_dimensions[row[0].row].hidden == False:
for cell in row:
data.append(cell.value)
workbook = xlsxwriter.Workbook(target_xls)
worksheet = workbook.add_worksheet()
for i in range(len(data)):
print(range(len(data)))
for j in range(len(data[i])):
worksheet.write(i, j, data[i][j])
workbook.close()
I want to read excel like below:
And output into:
#Reference: xlrd manual: https://media.readthedocs.org/pdf/xlrd/latest/xlrd.pdf
#Python Forum Reference: https://python-forum.io/Thread-Identify-Hidden-rows-in-xls
import xlrd
print("Read the VALUE and ROW VISIBILITY from cells A1:A6 in a .xls file from 'Sheet2'.")
print()
######################################################
# Access .xls file (Excel 2003 and before)
excel_filename = "HiddenRow3OnSheet2.xls"
# Open the workbook
#NOTE: Traceback error if 'formatting_info=True' is NOT INCLUDED
xl_workbook = xlrd.open_workbook(excel_filename, formatting_info=True)
#Set the focus on 'Sheet2'
my_sheet_name = "Sheet2"
xl_sheet = xl_workbook.sheet_by_name(my_sheet_name)
print("File: {}".format(excel_filename))
for irow in range(xl_sheet.nrows):
ihidden = xl_sheet.rowinfo_map[irow].hidden #Row Visibility 0=Visible 1=Hidden
if ihidden == True:
shidden = "VISIBLE"
else:
shidden = "HIDDEN"
svalue = xl_sheet.cell(irow,0).value
print("Value: {} Row Visibility: {}".format(svalue, shidden))
######################################################
# Access .xlsx file (Excel 2007 and later)
excel_filename = "HiddenRow3OnSheet2.xlsx"
# Open the workbook
#NOTE: 'formatting_info=True' is NOT SUPPORTED for .xlsx files
xl_workbook = xlrd.open_workbook(excel_filename)
#Set the focus on 'Sheet2'
my_sheet_name = "Sheet2"
xl_sheet = xl_workbook.sheet_by_name(my_sheet_name)
print()
print("File: {}".format(excel_filename))
for irow in range(xl_sheet.nrows):
svalue = xl_sheet.cell(irow,0).value
print("Value: {} Row Visibility: {}".format(svalue, "Not Available for .xlsx files"))

excel automation using python

I am trying to write a function to read data from excel file using python. My function should read rows from excel sheet one at a time. Below is my code which will print 1st row.
import xlrd
from xlrd import open_workbook, cellname
book = open_workbook('./Excel/Book1.xls')
def read_excel(sheetName):
sheet = book.sheet_by_name(sheetName)
row = sheet.nrows
for i in range(1):
rows = sheet.row_values(i+1)
print(rows)
file = r'd:\pythonTest.xlsx '
import xlrd
wb = xlrd.open_workbook(file)
sheet = wb.sheet_by_index(0)
# For row 0 and column 0
sheet.cell_value(0, 0)
# Extracting number of columns
print(sheet.ncols)
print(sheet.nrows)
print(sheet.row_values(1))
for i in range(sheet.nrows):
print(sheet.cell_value(i, 0), sheet.cell_value(i, 1))

openpyxl - overwrite datasheet and preserve pivot table

I've seen a few answers around to this question but none of them are working.
eg: How to write to an existing excel file without breaking formulas with openpyxl?
Docs give nothing away it seems:
http://openpyxl.readthedocs.io/en/latest/api/openpyxl.reader.excel.html
I tried replacing xls.load_workbook with xls.reader.excel.load_workbook but it doesn't change anything.
My current code overwrites the data in the data sheet, but kills the pivot table functionality in the other sheet (the sheet is still there but only with values). Any idea how to keep the pivot table?
import pandas as pd
import openpyxl as xls
from shutil import copyfile
template_file = 'openpy_test.xlsx'
output_file = 'openpy_output.xlsx'
copyfile(template_file, output_file)
book = xls.load_workbook(output_file,guess_types=False,data_only=False)
writer = pd.ExcelWriter(output_file,engine='openpyxl')
writer.book = book
writer.sheets = dict((ws.title, ws) for ws in book.worksheets)
df.to_excel(writer,sheet_name='data',index=False,encoding='utf8')
writer.save()
I have also tried book.save('dummycopy.xlsx'), which also saves with a non-funcitoning pivot table. So I am sure the problem is related to the load_workbook function.
Package versions:
openpyxl 2.4.10 py36_0
pandas 0.20.3 py36hce827b7_2
i don't think openpyxl supports excel pivot tables currently. I had to switch to using win32com library.
here is a wrapper module i wrote to do specific stuff with pivot tables; it's basically VBA translated to python (record macros and read the VBA, it'll make sense). hope it helps. it's still a work in progress but should be enough for you to work with.
import os, datetime
import win32com.client as win32
win32c = win32.constants
import sys, datetime
letters = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ' #space to compensate for index. if letter is a if column is 1
def Pull_excel_workbook(path = '', filename = '', visible = False):
'''function to run excel on the given filename'''
if path == '': path = os.getcwd()
if filename == '': raise FileNotFoundError('Please supply a file')
excel = win32.gencache.EnsureDispatch('Excel.Application')
excel.Visible = visible
try: wb = excel.Workbooks.Open(path + filename)
except: print('Try again\n{}'.format(sys.exc_info()))
ws = wb.ActiveSheet
data = list(ws.UsedRange.Value) #2d list of rows and columns
src = '{}!R1C1:R{}C{}'.format(ws.Name, len(data), len(data[0]))
return excel, wb, src
#wb.SaveAs(path + filename)
def Create_pivottable(wb, src, table_name = 'Pivot'):
'''creates Pivot Table object in the wb in a new Pivot worksheet'''
ws = wb.Sheets.Add() #should also change wb.ActiveSheet to the new one.
ws.Name = table_name
tname = ws.Name
starting_point = (4,1) #row, column
pc = wb.PivotCaches().Add(SourceType = win32c.xlDatabase,
SourceData = src)
try:
pt = pc.CreatePivotTable(TableDestination = '{}!R{}C{}'.format(tname, starting_point[0], starting_point[1]),
TableName = table_name,
DefaultVersion = win32c.xlPivotTableVersion10 #15
)
except: #not sure if will work...
print('{}:{}:{}:{}'.format(wb, src, table_name, '{}!R{}C{}'.format(tname, starting_point[0], starting_point[1])))
#tabledestination format of RN Pivot!R4C1 is not correct format, should be 'RN Pivot'!R4C1
pt = pc.CreatePivotTable(TableDestination = '{}!R{}C{}'.format(tname, starting_point[0], starting_point[1]),
TableName = table_name,
DefaultVersion = win32c.xlPivotTableVersion15
)
wb.Sheets(ws.Name).Select()
wb.Sheets(ws.Name).Cells(3,1).Select()
def Add_to_Filter(wb, tname, field_name):
''' '''
field = wb.ActiveSheet.PivotTables(tname).PivotFields(field_name)
field.Orientation = win32c.xlPageField
field.Position = 1
def Add_to_Row(wb, tname, field_name, position = 1):
''' '''
field = wb.ActiveSheet.PivotTables(tname).PivotFields(field_name)
field.Orientation = win32c.xlRowField
field.Position = position
def Add_to_Column(wb, tname, field_name, position = 1):
''' '''
field = wb.ActiveSheet.PivotTables(tname).PivotFields(field_name)
field.Orientation = win32c.xlColumnField
field.Position = position
if position > 1:
text = 'maybe do something here....'
pass
def Add_to_Value(wb, tname, field_name, alias = '', calculation = 'xlSum'):
''' '''
if type(calculation) is str and calculation in win32c.__dict__['__dicts__'][0]:
calculation = win32c.__dict__['__dicts__'][0][calculation]
datafield = wb.ActiveSheet.PivotTables(tname).PivotFields(field_name)
wb.ActiveSheet.PivotTables(tname).AddDataField(datafield, alias, calculation)
def LtoC(letter):
global letters
col = letters.index(letter)
return col
def CtoL(col):
global letters
letter = letters[col]
return letter
def Format_pretty(wb, tname, row_to_colapse):
'''makes it look prettier'''
wb.ActiveSheet.PivotTables(tname).TableStyle2 = 'PivotStyleMedium9'
if type(row_to_colapse) is not str:
for row in row_to_colapse:
wb.ActiveSheet.PivotTables(tname).PivotFields(row).ShowDetail = False #collapses
wb.ActiveSheet.PivotTables(tname).PivotFields(row).RepeatLabels = True #repeats labels
else:
wb.ActiveSheet.PivotTables(tname).PivotFields(row_to_colapse).ShowDetail = False #collapses
wb.ActiveSheet.PivotTables(tname).PivotFields(row_to_colapse).RepeatLabels = True #repeats labels
wb.ActiveSheet.Columns('A:Z').EntireColumn.AutoFit()
wb.ActiveSheet.Range('A1').Select()
def Add_calcd_col(ws, col, row_start, row_end, formula, style = '', col_title = 'default'):
'''col and rows should be int
'''
letter = CtoL(col)
ws.Range('{0}{1}:{0}{2}'.format(letter, row_start, row_end)).Select()
ws.Cells(row_start, col).Value = col_title
for row in range(row_start + 1, row_end + 1):
ws.Cells(row, col).Value = formula.format(row)
ws.Range('{0}{1}:{0}{2}'.format(letter, row_start, row_end)).Style = style
#print("ws.Range('{0}1:{0}200'.format({0})).Style = style".format(letter))
#ws.Range('{0}1:{0}200'.format(letter)).Style = style
def Values_to_columns(wb,tname, position = 2):
''' '''
wb.ActiveSheet.PivotTables(tname).DataPivotField.Orientation = win32c.xlColumnField
wb.ActiveSheet.PivotTables(tname).DataPivotField.Position = position
def WB_save(wb, path, tname, filename):
'''clean save of the new file '''
#Format_pretty(wb, tname, 'Division') #that needs to be fixed....
new_filename = filename[:-5] + '-{}.xlsx'.format(datetime.date.today().strftime('%m.%d.%y'))
wb.SaveAs(path + new_filename)
def Pivot_refresh(path, filename, pivot_sheet_name, pivot_table_name = 'Pivot'):
'''function to refresh the pivot table
tested and functional with recruiting prod report'''
excel, wb, src = Pull_excel_workbook(path = path, filename = filename)
wb.Sheets(pivot_sheet_name).Select()
cell = 'A6' #need a better way for this
excel.Worksheets(pivot_sheet_name).Range(cell).PivotTable.RefreshTable()
#pvt = excel.Worksheets(pivot_sheet_name).Range(cell).PivotTable
#pvt.RefreshTable()
WB_save(wb, path, pivot_table_name, filename)
#pivot refresh
#new = filename[:-5] + '-{}.xlsx'.format(2)
#Pivot_refresh(path = path, filename = new, pivot_sheet_name = 'Pivot')
def Hide_columns(wb, tname, start, end):
'''Hides columns'''
if type(start) is not str: start = CtoL(start)
if type(end) is not str: end = CtoL(end)
wb.ActiveSheet.Columns('{}:{}'.format(start, end)).EntireColumn.Hidden = True

Resources