Set_column not working until manually activatiing each cell - python

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

Related

How to get the actual value of a cell with openpyxl

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)

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.

openpyxl - Write string beginning with equals ('=')

I'm pulling some random text strings from a database and writing them to an xlsx file with openpyxl. Some of the strings happen to start with an equals sign (something like "=134lj9adsasf&^") This leads to the problem of Excel trying to interpret it as a formula and showing it as "#NAME?" due to the error.
In Excel itself, I can avoid this problem by changing the cell's format from General to Text prior to writing the string. I tried to do this with openpyxl but it doesn't make a difference. When I open the generated spreadsheet it does show the cell as having text format, but it still shows the error. How can I get around this?
A working example is below. When I open the file in Excel, it shows #NAME? for the third cell. Yet if I simply select the cell and type "=abc?123" (without quotes), Excel accepts the text with no issue.
import openpyxl
from openpyxl.cell.cell import Cell
stringList = [("abc","123","=abc?123","ok")]
wb = openpyxl.Workbook()
ws = wb.create_sheet('Sheet1')
for row in stringList:
ws.append(row)
for idx, cell in enumerate(ws[ws.max_row]):
cell.number_format = '#' # Set all cells to text format to avoid issue with =
cell.value = str(row[idx]) # Re-write data
wb.save("filename.xlsx")
I figured it out. Just need to change the data_type rather than number_format.
The strings starting with equals had their data_type set to 'f'.
for row in stringList:
ws.append(row)
for cell in ws[ws.max_row]:
if cell.data_type == 'f':
cell.data_type = 's'

Pandas/Excel: Any way to encode the ALT-ENTER / CHAR(10) line break into data when calling DataFrame.to_excel()?

I have a pandas DataFrame that I would like to write to Excel. For one column, I have data values that are comma-delimited strings, like "val1,val2" or "val1,val2,val3". When I write that column, I would like to replace the commas with the equivalent of pressing ALT-ENTER in Excel, so that there are line breaks between the values. So, my first example would display as val1, then a break within the cell, then val2, and so forth. You can also do this in Excel by making the cell a formula and putting &"char(10)"& between each value.
I see how I could do this by coding up formulas via XLSXWriter and writing cells individually. However I'm hopefully (or lazily) wondering whether there's a way to encode the breaks right into the data so that they would all come out via a simple call to to_excel() on the DataFrame.
In XlsxWriter you can use newlines in the string and the text_wrap format property to wrap it onto separate lines. See this section of the Format docs.
wrap_format = workbook.add_format({'text_wrap': True})
worksheet.write(0, 0, "Val1\nval2", wrap_format)
To do it from Pandas you could convert the commas in the strings to \n and then apply the text_wrap format to the column in the target spreadsheet.
I still had to do a bit of research after reading the answers here and therefore I wanted to post here a fully working example
df = pd.DataFrame({'Data': ['bla\nbla', 'blubb\nblubb']})
with pd.ExcelWriter('test.xlsx', engine='xlsxwriter') as writer:
df.to_excel(writer, sheet_name='Sheet1')
workbook = writer.book
worksheet = writer.sheets['Sheet1']
cell_format = workbook.add_format({'text_wrap': True})
worksheet.set_column('A:Z', cell_format=cell_format)
In particular, I had to figure out that after creating the format object I still need to set it on the respective cells.
Note: You need to pip install xlsxwriter before doing it.
Here, again, the link to the Format Class documenation
for me this sort of code worked perfectly:
liste=['adsf','asdfas','dasdsas','asdfsdaf']
text=''
for elem in liste:
text=text+elem+'\n'
ws.Cells(1,1).Value=text

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