I'm using xlwt to make a .xls spreadsheet, and I need to create date cells.
I've got writing out numbers, and setting the number format string to make them look like dates, but critically they aren't actually getting written as dates - if you do format cell in Excel, it's a "custom" Category rather than a "date" one, and this matters.
Can I make xlwt actually write "date" cells?
The number will show up in the Excel "Date" category if you use a format string that corresponds to one of Excel's built-in format strings such as dd/mm/yyy. for example:
import xlwt
import datetime
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('Sheet1')
date_format = xlwt.XFStyle()
date_format.num_format_str = 'dd/mm/yyyy'
worksheet.write(0, 0, datetime.datetime.now(), date_format)
workbook.save('date_format.xls')
If you modify this example to use a format string of d/mm/yyy then the number will show up in the "Custom" category.
Note: the above code works for the version of Excel that I tried but it is possible that this is subject to regional variation. The best thing to do is format a number in Excel with the "Date" format that you want and then, in the same dialog, click on "Custom" to see what format string is associated with the "Date" format. Then use that in your program.
Also: There isn't any native date type in the Excel XLS format. All dates are stored as numbers plus a format. There is nothing to distinguish them from any other number with a format except for the format string. This is one of the things that makes parsing an Excel file a pain since you have to apply heuristics to determine if a cell contains a date.
From http://www.youlikeprogramming.com/2011/04/examples-generating-excel-documents-using-pythons-xlwt/
Entering a Date into a Cell
import xlwt
import datetime
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('My Sheet')
style = xlwt.XFStyle()
style.num_format_str = 'D-MMM-YY' # Other options: D-MMM-YY, D-MMM, MMM-YY, h:mm, h:mm:ss, h:mm, h:mm:ss, M/D/YY h:mm, mm:ss, [h]:mm:ss, mm:ss.0
worksheet.write(0, 0, datetime.datetime.now(), style)
workbook.save('Excel_Workbook.xls')
Related
I'm trying to get values from an excel sheet however there is a column filled with dates.
Image of that column
I want to get the value exactly how it is in the cell(22-Nov-21) but instead I'm getting the value as 2021-11-22 00:00:00
Openpyxl doesn't evaluate the cell contents or formatting on it's own, as it doesn't actually run Excel, just accesses the file. Therefore, when you get the cell value, you are getting the datetime object it contains, not the displayed format you see when opening Excel. You could do as #Gedas suggested and get the cell format using cell.number_format and try and format based on that. But it's easier to just do as #Charlie recommended and format yourself (see the documentation for datetime for more information on formatting and format codes).
import openpyxl as op
import datetime as dt
wb = op.load_workbook("Date_format.xlsx")
ws = wb["Sheet1"]
your_date = ws.cell(row=1, column=1).value
your_formatted_date = your_date.strftime("%d-%b-%y")
print(your_formatted_date)
>>>
22-Nov-21
To access the value for a specific cell you would use:
value = worksheet.cell(row, column)
Code:
def write_pandas_dataframe_to_excel(df):
book = openpyxl.load_workbook('~/Documents/test.xlsm', read_only=False, keep_vba=True)
sheet = book['Database']
# Delete all rows after the header so that we can replace them with the contents of our pandas dataframe
sheet.delete_rows(1,sheet.max_row)
#Write values from the pandas dataframe to the sheet
for r in dataframe_to_rows(df,index=include_index, header=True):
sheet.append(r)
for row in sheet[2:sheet.max_row]: # skip the header
cell = row[0] # column A is a Date Field.
cell.number_format = 'YYYY-mm-dd'
book.save(excel_file_path)
book.close()
Expected Result: I open up test.xlsm, and in column A, all dates should already be in the format YYYY-mm-dd
Actual Result: While the YYYY-mm-dd format gets applied without any issues when I run the python code, I then have to open up the excel file, select each cell manually and hit 'Return' in the formula window for the YYYY-mm-dd format to be applied.
Is there a way for my specified date format to be applied through the python code rather than having to manually apply it by opening up excel and selecting each cell, going to the formula bar and hitting 'Return' every time?
Thanks in advance!
I've figured out the answer. Put simply, the date was being written to excel as a string, and that was causing the issue.
In the pandas dataframe I'm containing my data I had used strptime to format the date, which converted the date type to a generic 'object' type. I removed the strptime so that it maintained the datetime object, and that way when I write to excel it writes as a pandas Timestamp object rather than a string.
Been trying to get the set_column to work still. Having problems getting Pandas to work, so have been doing it just in xlsxwriter. Right now am using:
'worksheet.set_column('D:D',None,format4)' - this only seems to work when I go into the xlsx file and actually activate each cell in the "D" column. Is there some way of activating each cell so that I wouldn't have to do it manually?
Thanks in advance.
import xlsxwriter,os,sys,datetime
now=datetime.datetime.now()
def main():
platform=sys.platform
if platform.find('win')>=0:
TheSlash='\\'
else:
TheSlash='/'
output = '%s-%s.xlsx' % ('XlsxSample',now.strftime("%m%d%Y-%H%M"))
workbook = xlsxwriter.Workbook(output, {'strings_to_numbers':True,'default_date_format':'mm/dd/yy hh:mm'})
worksheet = workbook.add_worksheet()
count=0
counter=0
format=workbook.add_format({'font_size':'8','border':True})
formatdict={'num_format':'mm/dd/yy hh:mm'}
format4=workbook.add_format(formatdict)
cur =('Pole1','33.62283963','-90.54639967','4/20/16 11:43','-90.54640226','33.62116957','5207069','25-04','50','3','PRIMARY','PGC')
for name in cur:
worksheet.write(counter, count, name,format)
count+=1
counter+=1
worksheet.set_column('D:D',None,format4)
workbook.close()
if __name__ == "__main__":
main()
as stated above - date format only seems to activate if you get into the "D" cell itself with the cursor.
The reason that the column date format isn't showing up in the column cells is that the program is overwriting it with a cell format here:
for name in cur:
worksheet.write(counter, count, name,format)
count+=1
In XlsxWriter, as in Excel, a cell format overrides a column format.
If you want to have a cell or column format that is the result of 2 combined formats you will need to create a new format that combines those formats and apply it to the cells or the column.
Update: Also, I just noticed that you are writing a string in column D. Dates in Excel are formatted numbers. This is probably why you see the cell data change when you hit return. Excel is converting the date-like string into a formatted number displayed as a date. In XlsxWriter you will need to do the conversion. See the Working with Dates and Time section of the XlsxWriter docs.
You need change format using datetime.datetime.strptime()
Example
import datetime
datetime_result = datetime.dateime.strptime('04/20/16 11:43', '%m/%d/%Y %H:%M')
format5 = workbook.add_format({'num_format':'mm/dd/yy hh:mm'})
worksheet.write('A5', datetime_result, format5)
Refer to Working with Dates and Time in XlsxWriter docs.
In VBA, Columns("D").Select does what you want. If you are running from an external script, you might be able to save a VBA macro and run it with a technique like this: How do I call an Excel macro from Python using xlwings?.
I am trying to convert a date format in Excel to be formatted such that it can be read into a MySQL database. I am using python to process the date column, export it back into a csv file and then dump it into a MySQL table.
Here is how the date column look like :
Date
6/10/13
6/17/13
6/24/13
I want it to be in the format : 2013-06-10 or ("%Y-%m-%d")
Here is my code:
import datetime
import csv
def read(filename):
new_date=[]
cr = csv.reader(open(filename,"rU").readlines()[1:], dialect='excel')
for row in cr:
# print row[0]
cols=datetime.datetime.strptime(row[0] , "%m/%d/%y" )
newcols=cols.strftime("%Y-%m-%d")
# print newcols
new_date.append(newcols)
print new_date[0]
with open('new_file.csv', 'wb') as f:
writer = csv.writer(f)
for date in new_date:
writer.writerow([date])
The code runs, but when i open the new_file.csv, the date column automatically reverts back to the old format in excel.
How can i change this?
Thanks,
Have you tried opening the .csv in a simple text editor (like notepad, for example) to see if the date is being printed to that file correctly? My guess is that Excel, which has the ability to recognize dates, is just reformatting it to it's default date format when you open the file, and that if you open your .csv file in a simple text editor to check, you'll see that your code has correctly reformatted the dates in the csv.
(By default, Excel formats dates like you specify in Control Panel, and you can change your default date formatting in Control Panel to change Excel's default formatting.)
You can change the way that Excel formats dates as described here in the documentation.
Select the cells you want to format.
Press CTRL+1.
In the Format Cells box, click the Number tab.
In the Category list, click Date.
You can create a custom date format from this menu if the format you see is not there. Details here.
I'm trying to write some dates from one excel spreadsheet to another. Currently, I'm getting a representation in excel that isn't quite what I want such as this: "40299.2501157407"
I can get the date to print out fine to the console, however it doesn't seem to work right writing to the excel spreadsheet -- the data must be a date type in excel, I can't have a text version of it.
Here's the line that reads the date in:
date_ccr = xldate_as_tuple(sheet_ccr.cell(row_ccr_index, 9).value, book_ccr.datemode)
Here's the line that writes the date out:
row.set_cell_date(11, datetime(*date_ccr))
There isn't anything being done to date_ccr in between those two lines other than a few comparisons.
Any ideas?
You can write the floating point number directly to the spreadsheet and set the number format of the cell. Set the format using the num_format_str of an XFStyle object when you write the value.
https://secure.simplistix.co.uk/svn/xlwt/trunk/xlwt/doc/xlwt.html#xlwt.Worksheet.write-method
The following example writes the date 01-05-2010. (Also includes time of 06:00:10, but this is hidden by the format chosen in this example.)
import xlwt
# d can also be a datetime object
d = 40299.2501157407
wb = xlwt.Workbook()
sheet = wb.add_sheet('new')
style = xlwt.XFStyle()
style.num_format_str = 'DD-MM-YYYY'
sheet.write(5, 5, d, style)
wb.save('test_new.xls')
There are examples of number formats (num_formats.py) in the examples folder of the xlwt source code. On my Windows machine: C:\Python26\Lib\site-packages\xlwt\examples
You can read about how Excel stores dates (third section on this page): https://secure.simplistix.co.uk/svn/xlrd/trunk/xlrd/doc/xlrd.html