So, given:
dttm = datetime.datetime.strptime(\"2014-06-23 13:56:30\", \"%Y-%m-%d %H:%M:%S\")
ws[\'A1\'] = dttm
The result in excel is that
I believe you will need to set a openpyxl.styles.Style
on the cell(s) that you want to format.
Looking at the documentation here, something like this should work:
dttm = datetime.datetime.strptime("2014-06-23 13:56:30", "%Y-%m-%d %H:%M:%S")
s = Style(number_format=NumberFormat('dd-mm-yyyy h:mm:ss'))
ws['A1'] = dttm
ws['A1'].styles = s
Update: Style class is no longer used, for the solution refer to this answer.
For openpyxl 2.3.4 the NumberFormat cannot be imported, but this code works to set the style:
from openpyxl.styles import Style
…
date_style = Style(number_format="DD/MM/YYYY HH:MM:MM")
ws['A1'].style = date_style
from openpyxl import load_workbook
from openpyxl.styles import NamedStyle
xlsx_file = args.xlsx_file.name
# openning:
wb = load_workbook(filename = xlsx_file)
# create date style:
date_style = NamedStyle(name='date_style', number_format='DD.MM.YYYY HH:MM:MM')
# apply the style to the column H of the default sheet:
ws = wb.active
for row in ws[2:ws.max_row]: # skip the header
cell = row[7] # column H
cell.style = date_style
# saving:
wb.save(xlsx_file)
Edit: the above works for me, but somehow does not work on my coleagues machine. Converting the cell to string fixed that:
import datetime
from openpyxl import load_workbook
from openpyxl.styles import Alignment
xlsx_file = 'file.xlsx'
date_format = '%Y-%b-%d'
# openning:
wb = load_workbook(filename = xlsx_file)
# we also center align that column:
alignment = Alignment(horizontal='center')
# apply python date format to column H of the default sheet, and convert the column to Excel text:
ws = wb.active
for row in ws[2:ws.max_row]: # skip the header
cell = row[7] # column H
if isinstance(cell.value, datetime.datetime):
cell.value = cell.value.strftime(date_format)
cell.alignment = alignment
# saving:
wb.save(xlsx_file)
The same wrapped in a script:
#!/usr/bin/env python3
import argparse
import datetime
from openpyxl import load_workbook
from openpyxl.styles import Alignment
# ==============
## parsing args:
desc="""
Applies python date format to a given column of the xlsx file (default sheet) and converts the column to a Excel text format.
Dependencies:
pip3 install --user --upgrade openpyxl
"""
parser = argparse.ArgumentParser(description=desc, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('--version', action='version', version='%(prog)s 0.01')
parser.add_argument('-f', '--file',
help = "xlsx file",
dest = 'xlsx_file',
type = argparse.FileType('r'),
)
parser.add_argument('-c', '--column',
help = "column (starting from A) (default to %(default)s)",
dest = 'column',
type = str,
default = "A",
)
parser.add_argument('-d', '--date-format',
help = "date format to use, e.g. %%d.%%m.%%Y (default to %(default)s)",
dest = 'date_format',
type = str,
default = '%Y-%b-%d',
)
args = parser.parse_args()
# =========
## program:
xlsx_file = args.xlsx_file.name
column_number = sum(
[ ord(char) - 97 + i*26 for i,char in enumerate(
list( args.column.lower() )
) ]
)
# openning:
wb = load_workbook(filename = xlsx_file)
# we also center align that column:
alignment = Alignment(horizontal='center')
# apply python date format to a given column of the default sheet, and convert the column to Excel text:
ws = wb.active
for row in ws[2:ws.max_row]: # skip the header
cell = row[column_number]
if isinstance(cell.value, datetime.datetime):
cell.value = cell.value.strftime(args.date_format)
cell.alignment = alignment
# saving:
wb.save(xlsx_file)
I found that this worked. Although number_format is used it seems to recognise the date format specified when put into the excel wb.
import datetime
date = datetime.date(2020, 2, 24) # python datetime format is yyyy mm dd
ws.cell(row=[row_ref], column=[col_ref], value=date)
ws.cell(row=[row_ref], column=[col_ref]).number_format = 'dd/mm/yy'
I'm adding this as a new answer since I don't have enough reputation to add a comment to the above. The simplest way to format a cell is using .number_format = "format" as in:
value = datetime.datetime.strptime("2014-06-23 13:56:30", "%Y-%m-%d %H:%M:%S")
cell = ws['A1']
cell.value = value
cell.number_format = 'YYYY MMM DD'
This is tested in openpyxl (2.2.2)
For openpyxl 2.4.5 you'll no longer have access to NumberFormat
and Style
and will have to use NamedStyle
. Here's some sample usage:
from openpyxl.styles import NamedStyle
date_style = NamedStyle(name='datetime', number_format='DD/MM/YYYY HH:MM:MM')
ws['A1'].style = date_style
Alternatively with the new NamedStyle
class, you can set the style by the string name once NamedStyle
has been instantiated:
from openpyxl.styles import NamedStyle
NamedStyle(name='custom_datetime', number_format='DD/MM/YYYY HH:MM:MM')
ws['A1'].style = 'custom_datetime'
Documentation here: https://openpyxl.readthedocs.io/en/stable/styles.html