Skip to content

Commit

Permalink
Changed version, added readme file, modified the tests and included a…
Browse files Browse the repository at this point in the history
… fixture, date supports different formats
  • Loading branch information
Alexandru Plugaru committed Jan 20, 2011
1 parent a3dd65e commit b89a58e
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 61 deletions.
31 changes: 31 additions & 0 deletions README.rst
@@ -0,0 +1,31 @@
python-xlsx
===========

A small footprint xslx reader that understands shared strings and can process
excel dates.

Usage
+++++++

::

book = Workbook('filename or filedescriptor') #Open xlsx file
for sheet in book:
print sheet.name
for row, cells in sheet.rows().iteritems(): # or sheet.cols()
print row # prints row number
for cell in cells:
print cell.id, cell.value, cell.formula

# or you can access the sheets by their name:

some_sheet = book['some sheet name']
...

Alternatives
------------

To my knowledge there are other python alternatives:

* https://bitbucket.org/ericgazoni/openpyxl/
* https://github.com/leegao/pyXLSX
5 changes: 3 additions & 2 deletions setup.py
@@ -1,9 +1,10 @@
from distutils.core import setup

setup(
version="0.1",
version="0.2",
name='python-xlsx',
description="Tiny python code for parsing data from Microsoft's Office Open XML Spreadsheet format",
description="""Tiny python code for parsing data from Microsoft's Office
Open XML Spreadsheet format""",
long_description="",
classifiers=[
'Development Status :: 3 - Alpha',
Expand Down
18 changes: 10 additions & 8 deletions xlsx/__init__.py
Expand Up @@ -8,15 +8,16 @@
from xml.dom import minidom

class DomZip(object):

def __init__(self, filename):
self.filename = filename
self.ziphandle = zipfile.ZipFile(filename, 'r')

def __getitem__(self, key):
# @type ziphandle ZipFile
ziphandle = zipfile.ZipFile(self.filename)
dom = minidom.parseString(ziphandle.read(key))
ziphandle.close()
return dom
return minidom.parseString(self.ziphandle.read(key))

def __del__(self):
self.ziphandle.close()

class Workbook(object):

Expand Down Expand Up @@ -54,6 +55,7 @@ def __getitem__(self, key):
return self.__sheetsByName[key]

class SharedStrings(list):

def __init__(self, sharedStringsDom):
nodes = sharedStringsDom.firstChild.childNodes
for text in [n.firstChild.firstChild for n in nodes]:
Expand Down Expand Up @@ -85,17 +87,17 @@ def __load(self):
rows = {}
columns = {}
for rowNode in sheetData.childNodes:
rowNum = rowNode.getAttribute("r")
rowNum = int(rowNode.getAttribute("r"))
for columnNode in rowNode.childNodes:
colType = columnNode.getAttribute("t")
cellId = columnNode.getAttribute("r")
cellS = columnNode.getAttribute("s")
colNum = cellId[:len(cellId)-len(rowNum)]
colNum = cellId[:len(cellId)-len(str(rowNum))]
formula = None
if colType == "s":
stringIndex = columnNode.firstChild.firstChild.nodeValue
data = self.workbook.sharedStrings[int(stringIndex)]
elif cellS == '1' and colType == "n": #Date field
elif cellS in ('1', '2', '3', '4') and colType == "n": #Date field
data = xldate_as_tuple(int(columnNode.firstChild.firstChild.nodeValue), datemode=0)
elif columnNode.firstChild:
data = getattr(columnNode.getElementsByTagName("v")[0].firstChild, "nodeValue", None)
Expand Down
51 changes: 0 additions & 51 deletions xlsx/test/XlsxTest.py

This file was deleted.

File renamed without changes.
Binary file added xlsx/tests/fixtures/test1.xlsx
Binary file not shown.
68 changes: 68 additions & 0 deletions xlsx/tests/test_basic.py
@@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
import os
import unittest

from xlsx import Workbook

class WorkbookTestCase(unittest.TestCase):

def setUp(self):
""" Getting all file from fixtures dir """
self.workbooks = {}
fixtures_dir = os.path.abspath(os.path.join(os.path.dirname(__file__),
'fixtures'))
xlsx_files = os.listdir(fixtures_dir)
for filename in xlsx_files:
self.workbooks[filename] = Workbook(
os.path.join(fixtures_dir, filename))

def test_basic(self):
""" These test will run for all test files """

for filename, workbook in self.workbooks.items():
for sheet in workbook:
assert hasattr(sheet, 'id')
assert isinstance(sheet.name, basestring)
assert isinstance(sheet.rows(), dict)
assert isinstance(sheet.cols(), dict)

for row_num, cells in sheet.rows().iteritems():
assert isinstance(row_num, int)
assert isinstance(cells, list)
for cell in cells:
assert hasattr(cell, 'id')
assert hasattr(cell, 'column')
assert hasattr(cell, 'row')
assert hasattr(cell, 'value')
assert cell.row == row_num

def test_test1(self):
""" Specific test for `testdata/test1.xslx` file including
unicode strings and different date formats
"""
workbook = self.workbooks['test1.xlsx']

self.assertEqual(unicode(workbook[1].name), u'рускии')
self.assertEqual(unicode(workbook[2].name), u'性 文化交流 例如')
self.assertEqual(unicode(workbook[3].name), u'تعد. بحق طائ')

for row_num, cells in workbook[1].rows().iteritems():
if row_num == 1:
self.assertEqual(unicode(cells[0].value), u'лорем ипсум')
self.assertEqual(unicode(cells[1].value), u'2')
if row_num == 2: #Test date fields
self.assertEqual(cells[0].value, (2010, 11, 12, 0, 0, 0))
self.assertEqual(cells[1].value, (1987, 12, 20, 0, 0, 0))
self.assertEqual(cells[2].value, (1987, 12, 20, 0, 0, 0))
self.assertEqual(cells[3].value, (1987, 12, 20, 0, 0, 0))
break

# Cell A1 in u'性 文化交流 例如'
self.assertEqual(unicode(workbook[2].cols()['A'][0].value),
u'性 文化交流 例如')
self.assertEqual(unicode(workbook[2].cols()['A'][1].value),
u'エム セシビ め「こを バジョン')


if __name__ == '__main__':
unittest.main()

0 comments on commit b89a58e

Please sign in to comment.