Write Excel files with Python using xlwt

In a previous post (which turned out to be pretty popular) I showed you how to read Excel files with Python. Now for the reverse: writing Excel files.

First, you’ll need to install the xlwt package by John Machin.

The basics

In order to write data to an Excel spreadsheet, first you have to initialize a Workbook object and then add a Worksheet object to that Workbook. It goes something like this:

import xlwt
wbk = xlwt.Workbook()
sheet = wbk.add_sheet('sheet 1')

Now that the sheet is created, it’s very easy to write data to it.

# indexing is zero based, row then column
sheet.write(0,1,'test text')

When you’re done, save the workbook (you don’t have to close it like you do with a file object)

wbk.save('test.xls')

Digging deeper

Overwriting cells

Worksheet objects, by default, give you a warning when you try to overwrite:

sheet.write(0,0,'test')
sheet.write(0,0,'oops') 

# returns error:
# Exception: Attempt to overwrite cell: sheetname=u'sheet 1' rowx=0 colx=0

To change this behavior, use the cell_overwrite_ok=True kwarg when creating the worksheet, like so:

sheet2 = wbk.add_sheet('sheet 2', cell_overwrite_ok=True)
sheet2.write(0,0,'some text')
sheet2.write(0,0,'this should overwrite')

Now you can overwrite sheet 2 (but not sheet 1).

More goodies

# Initialize a style
style = xlwt.XFStyle()

# Create a font to use with the style
font = xlwt.Font()
font.name = 'Times New Roman'
font.bold = True

# Set the style's font to this new one you set up
style.font = font

# Use the style when writing
sheet.write(0, 0, 'some bold Times text', style)

xlwt allows you to format your spreadsheets on a cell-by-cell basis or by entire rows; it also allows you to add hyperlinks or even formulas. Rather than recap it all here, I encourage you to grab a copy of the source code, in which you can find the examples directory. Some highlights from the examples directory in the source code:

  • dates.py, which shows how to use the different date formats
  • hyperlinks.py, which shows how to create hyperlinks (hint: you need to use a formula)
  • merged.py, which shows how to merge cells
  • row_styles.py, which shows how to apply styles to entire rows.

Non-trivial example

Here’s an example of some data where the dates not formatted well for easy import into Excel:

20 Sep, 263, 1148,   0,   1,   0,   0,   1,   12.1,   13.9, 1+1, 19.9
 20 Sep, 263, 1118,   0,   1,   0, 360,   0,   14.1,   15.3, 1+1, 19.9
 20 Sep, 263, 1048,   0,   1,   0,   0,   0,   14.2,   15.1, 1+1, 19.9
 20 Sep, 263, 1018,   0,   1,   0, 360,   0,   14.2,   15.9, 1+1, 19.9
 20 Sep, 263, 0948,   0,   1,   0,   0,   0,   14.4,   15.3, 1+1, 19.9

The first column has the day and month separated by a space. The second column is year-day, which we’ll ignore. The third column has the time. The data we’re interested in is in the 9th column (temperature). The goal is to have a simple Excel file where the first column is date, and the second column is temperature.

Here’s a [heavily commented] script to do just that. It assumes that you have the data saved as weather.data.example.

'''
Script to convert awkwardly-formatted weather data
into an Excel spreadsheet using Python and xlwt.
'''

from datetime import datetime
import xlwt

# Create workbook and worksheet
wbk = xlwt.Workbook()
sheet = wbk.add_sheet('temperatures')

# Set up a date format style to use in the
# spreadsheet
excel_date_fmt = 'M/D/YY h:mm'
style = xlwt.XFStyle()
style.num_format_str = excel_date_fmt

# Weather data has no year, so assume it's the current year.
year = datetime.now().year

# Convert year to a string because we'll be
# building a date string below
year = str(year)

# The format of the date string we'll be building
python_str_date_fmt = '%d %b-%H%M-%Y'

row = 0  # row counter
f = open('weather.data.example')
for line in f:
    # separate fields by commas
    L = line.rstrip().split(',')

    # skip this line if all fields not present
    if len(L) < 12:
        continue

    # Fields have leading spaces, so strip 'em
    date = L[0].strip()
    time = L[2].strip()

    # Datatypes matter. If we kept this as a string
    # in Python, it would be a string in the Excel sheet.
    temperature = float(L[8])

    # Construct a date string based on the string
    # date format  we specified above
    date_string = date + '-' + time + '-' + year

    # Use the newly constructed string to create a
    # datetime object
    date_object = datetime.strptime(date_string,
                                    python_str_date_fmt)

    # Write the data, using the style defined above.
    sheet.write(row,0,date_object, style)
    sheet.write(row,1,temperature)

    row += 1

wbk.save('reformatted.data.xls')

Still curious? Other questions? Check out the python-excel google group ! Also check out xlutils for more functionality, which I plan to play around with next.

9 Responses to “Write Excel files with Python using xlwt”


  • Yeah, more Python and Excel! I’ve created a cheatsheet showing a few more features of xlwt[0].
    cheers,
    -matt
    0 – http://panela.blog-city.com/pyexcelerator_xlwt_cheatsheet_create_native_excel_from_pu.htm

  • Very good tutorial and examples, mate. Thanks.
    Here I got a question:
    How can I read an excel file using xlrd, then write the calculation results back to the same excel using xlwt?

    Thanks again.

  • Yes, really good explanation.

    I wonder know the response about Cross Zheng question… Is it possible?

    Cheers

  • hi,
    i need to know how to open an excel in order add data in it. I do not want to open it just to read using xlrd. I need to open an existing excel sheet and add in data to it. IF it is possible with xlrt, kindly let me know how to do it. If theres some other way pl let me know the procedure in detail.

    Thanks

  • RE “How can I read an excel file using xlrd, then write the calculation results back to the same excel using xlwt?”

    Short answer: You can’t.

    Long answer: Even excel does not do this; read one of John Machin’s (creator of xlwt) many explanations on the mailing list. e.g.

    http://groups.google.com/group/python-excel/browse_thread/thread/9181c1437bde5637

  • Hello.

    how can i generate wbk in a save as box to let the user the ability to save it instead of using wbk.save() ?

    am using the following code to generate save as box:

    response.headers['Content-Type'] = \
    gluon.contenttype.contenttype(‘.xls’)
    response.headers['Content-disposition'] = ‘attachment; filename=projects.xls’\

    But how can i make response generate wbk ?

    Thanks

  • Hi,
    I didn’t find any way in xlwt to suppress/delete a previously created row so that the indexes of the remaining ones are updated.

    Any idea?

    Thanks,

  • Hi, for Neveen Adel (and others),

    you could use a python webapp like Grok (see http://grok.zope.org), a nice mainstream mostly Dutch invention (..).
    We read and write spreadsheets all the time webbased (using xlwt and xlrd), roundtripping data-entry (including formulas) and synchronisation with databases, which makes a nice interface for users used to data-entry in spreadsheets.
    Making the data-entry intuitive and human takes all the effort.

    I would set the response like so:
    self.response.setHeader(‘Content-Type’,
    ‘application/vnd.ms-excel’)
    self.response.setHeader(‘Content-Disposition’,
    “filename=path_2_ur_spreadsheet.xls”)

    But it depends of course on the platform you use.

  • Awesome post. Has anyone had luck copying data from one spreadsheet to another? I’d like to take a big series of data and basically chunk it up into blocks copied into a series of other spreadsheets.

    Thanks for any help or replies!

Leave a Reply