How to get the actual value of a cell with openpyxl - python

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)

Related

Finding first Excel column with no data using xlwings

I have an workbook in Excel and I need to find the first column that is empty / has no data in it. I need to keep Excel open at all times, so something like openpyxl won't do.
Here's my code so far:
import xlwings as xw
from pathlib import Path
wbPath = Path('test.xlsx')
wb = xw.Book(wbPath)
sourceSheet = wb.sheets['source']
This can be done using
destinationSheet["A1"].expand("right").last_cell.column
Depending on what you need exactly, this code might be most robust. With using used_range, the code gives you the first empty column at the very end of the data as integer, regardless of empty/blank columns before the last column with data.
a_rng = sourceSheet.used_range[-1].offset(column_offset=1).column
print(a_rng)

Openpyxl Number_Format Not Applied Until Manually Applied

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.

Set_column not working until manually activatiing each cell

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?.

Writing xlwt dates with Excel 'date' format

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')

datetime issue with xlrd & xlwt python libs

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

Categories

Resources