Skip to content

Commit b32c05a

Browse files
committed
adding json support, save_as and save_to_stream
1 parent cba3626 commit b32c05a

File tree

5 files changed

+247
-16
lines changed

5 files changed

+247
-16
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ install:
1414
- pip install git+https://github.com/chfw/pyexcel.git
1515
- pip install -r tests/requirements.txt --use-mirrors
1616
script:
17-
nosetests --rednose --with-cov
17+
nosetests --rednose --with-cov --with-doctest --doctest-extension=.rst
1818
after_success:
1919
codecov

README.rst

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,95 @@
11
pyexcel-text
22
============
33

4-
It is a plugin to pyexcel and provides the capbility to present and write data in text fromats
4+
.. image:: https://api.travis-ci.org/chfw/pyexcel-text.svg?branch=master
5+
:target: http://travis-ci.org/chfw/pyexcel-text
6+
7+
It is a plugin to [pyexcel and extends its capbility to present and write data in text fromats mainly through `tabulate`:
8+
9+
* "plain"
10+
* "simple"
11+
* "grid"
12+
* "pipe"
13+
* "orgtbl"
14+
* "rst"
15+
* "mediawiki"
16+
* "latex"
17+
* "latex_booktabs"
18+
* "json"
19+
20+
Usage::
21+
22+
>>> import pyexcel as pe
23+
>>> import pyexcel.ext.text as text
24+
>>> content = [
25+
... ["Column 1", "Column 2", "Column 3"],
26+
... [1, 2, 3],
27+
... [4, 5, 6],
28+
... [7, 8, 9]
29+
... ]
30+
>>> sheet = pe.Sheet(content)
31+
>>> sheet
32+
Sheet Name: pyexcel
33+
-------- -------- --------
34+
Column 1 Column 2 Column 3
35+
1 2 3
36+
4 5 6
37+
7 8 9
38+
-------- -------- --------
39+
>>> sheet.name_columns_by_row(0)
40+
>>> sheet
41+
Sheet Name: pyexcel
42+
Column 1 Column 2 Column 3
43+
---------- ---------- ----------
44+
1 2 3
45+
4 5 6
46+
7 8 9
47+
>>> multiple_sheets = {
48+
... 'Sheet 1':
49+
... [
50+
... [1.0, 2.0, 3.0],
51+
... [4.0, 5.0, 6.0],
52+
... [7.0, 8.0, 9.0]
53+
... ],
54+
... 'Sheet 2':
55+
... [
56+
... ['X', 'Y', 'Z'],
57+
... [1.0, 2.0, 3.0],
58+
... [4.0, 5.0, 6.0]
59+
... ],
60+
... 'Sheet 3':
61+
... [
62+
... ['O', 'P', 'Q'],
63+
... [3.0, 2.0, 1.0],
64+
... [4.0, 3.0, 2.0]
65+
... ]
66+
... }
67+
>>> book = pe.Book(multiple_sheets)
68+
>>> text.TABLEFMT = "rst"
69+
>>> text.save_as(book, "myfile.rst")
70+
>>> myfile = open("myfile.rst")
71+
>>> print(myfile.read())
72+
Sheet Name: Sheet 1
73+
= = =
74+
1 2 3
75+
4 5 6
76+
7 8 9
77+
= = =
78+
Sheet Name: Sheet 2
79+
=== === ===
80+
X Y Z
81+
1.0 2.0 3.0
82+
4.0 5.0 6.0
83+
=== === ===
84+
Sheet Name: Sheet 3
85+
=== === ===
86+
O P Q
87+
3.0 2.0 1.0
88+
4.0 3.0 2.0
89+
=== === ===
90+
91+
92+
Dependencies
93+
============
94+
95+
* tabulate

pyexcel_text/__init__.py

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
TABLEFMT="simple"
1515

16+
1617
def class_name(name):
1718
if sys.version_info[0] > 2:
1819
return "<class '%s'>" % name
@@ -21,26 +22,53 @@ def class_name(name):
2122

2223

2324
def present_matrix(matrix_instance):
24-
import tabulate
25-
return tabulate.tabulate(matrix_instance.to_array(), tablefmt=TABLEFMT)
25+
"""Textualize a Matrix"""
26+
if TABLEFMT == "json":
27+
import json
28+
return json.dumps(matrix_instance.to_array())
29+
else:
30+
import tabulate
31+
return tabulate.tabulate(matrix_instance.to_array(), tablefmt=TABLEFMT)
2632

2733

2834
def present_nominable_sheet(nmsheet_instance):
29-
import tabulate
30-
ret = "Sheet Name: %s\n" % nmsheet_instance.name
31-
if len(nmsheet_instance.colnames) > 0:
32-
data = nmsheet_instance.to_array()
33-
return ret+tabulate.tabulate(data, headers="firstrow")
35+
"""Textualize a NominableSheet"""
36+
if TABLEFMT == "json":
37+
import json
38+
return json.dumps({nmsheet_instance.name:nmsheet_instance.to_array()})
3439
else:
35-
return ret+present_matrix(nmsheet_instance)
40+
import tabulate
41+
ret = "Sheet Name: %s\n" % nmsheet_instance.name
42+
if len(nmsheet_instance.colnames) > 0:
43+
data = nmsheet_instance.to_array()
44+
return ret+tabulate.tabulate(data, headers="firstrow")
45+
else:
46+
return ret+present_matrix(nmsheet_instance)
3647

3748

3849
def present_book(book_instance):
39-
ret = ""
40-
for sheet in book_instance.sheets:
41-
ret += present_nominable_sheet(book_instance.sheets[sheet])
42-
ret += "\n"
43-
return ret.strip('\n')
50+
"""Textualize a pyexcel Book"""
51+
if TABLEFMT == "json":
52+
import json
53+
return json.dumps(book_instance.to_dict())
54+
else:
55+
ret = ""
56+
for sheet in book_instance.sheets:
57+
ret += present_nominable_sheet(book_instance.sheets[sheet])
58+
ret += "\n"
59+
return ret.strip('\n')
60+
61+
62+
def save_as(instance, filename):
63+
"""Save a pyexcel instance as text to a file"""
64+
f = open(filename, "w")
65+
f.write(str(instance))
66+
f.close()
67+
68+
69+
def save_to_memory(instance, stream):
70+
"""Save a pyexcel instance as text to a stream"""
71+
stream.write(str(instance))
4472

4573

4674
STRINGIFICATION[class_name("pyexcel.sheets.matrix.Matrix")] = present_matrix

tests/test_io.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import os
2+
import sys
3+
from textwrap import dedent
4+
import pyexcel as pe
5+
from pyexcel.ext import text
6+
if sys.version_info[0] < 3:
7+
from StringIO import StringIO
8+
else:
9+
from io import StringIO
10+
11+
class TestIO:
12+
def setUp(self):
13+
self.testfile = "testfile.txt"
14+
def test_normal_usage(self):
15+
content = [
16+
[1, 2, 3],
17+
[4, 588, 6],
18+
[7, 8, 999]
19+
]
20+
s = pe.Sheet(content)
21+
text.save_as(s, self.testfile)
22+
f = open(self.testfile, "r")
23+
written_content = f.read()
24+
f.close()
25+
content = dedent("""
26+
Sheet Name: pyexcel
27+
- --- ---
28+
1 2 3
29+
4 588 6
30+
7 8 999
31+
- --- ---""").strip('\n')
32+
print written_content
33+
assert written_content == content
34+
35+
def tearDown(self):
36+
if os.path.exists(self.testfile):
37+
os.unlink(self.testfile)
38+
39+
40+
class TestStream:
41+
def setUp(self):
42+
self.testfile = StringIO()
43+
def test_normal_usage(self):
44+
content = [
45+
[1, 2, 3],
46+
[4, 588, 6],
47+
[7, 8, 999]
48+
]
49+
s = pe.Sheet(content)
50+
text.save_to_memory(s, self.testfile)
51+
written_content = self.testfile.getvalue()
52+
content = dedent("""
53+
Sheet Name: pyexcel
54+
- --- ---
55+
1 2 3
56+
4 588 6
57+
7 8 999
58+
- --- ---""").strip('\n')
59+
print written_content
60+
assert written_content == content

tests/test_presentation.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,60 @@
33
from pyexcel.ext import text
44

55

6+
class TestJson:
7+
def setUp(self):
8+
text.TABLEFMT = "json"
9+
10+
def test_matrix(self):
11+
content = [
12+
[1, 2, 3],
13+
[4, 588, 6],
14+
[7, 8, 999]
15+
]
16+
s = pe.sheets.Matrix(content)
17+
content = "[[1, 2, 3], [4, 588, 6], [7, 8, 999]]"
18+
assert str(s) == content
19+
20+
def test_sheet(self):
21+
content = [
22+
[1, 2, 3],
23+
[4, 588, 6],
24+
[7, 8, 999]
25+
]
26+
s = pe.Sheet(content, "mytest")
27+
content = "{\"mytest\": [[1, 2, 3], [4, 588, 6], [7, 8, 999]]}"
28+
assert str(s) == content
29+
30+
def test_book_presentation(self):
31+
data = {
32+
'Sheet 1':
33+
[
34+
[1.0, 2.0, 3.0],
35+
[4.0, 5.0, 6.0],
36+
[7.0, 8.0, 9.0]
37+
],
38+
'Sheet 2':
39+
[
40+
['X', 'Y', 'Z'],
41+
[1.0, 2.0, 3.0],
42+
[4.0, 5.0, 6.0]
43+
],
44+
'Sheet 3':
45+
[
46+
['O', 'P', 'Q'],
47+
[3.0, 2.0, 1.0],
48+
[4.0, 3.0, 2.0]
49+
]
50+
}
51+
book = pe.Book(data)
52+
content = '{"Sheet 1": [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]], "Sheet 2": [["X", "Y", "Z"], [1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], "Sheet 3": [["O", "P", "Q"], [3.0, 2.0, 1.0], [4.0, 3.0, 2.0]]}'
53+
assert str(book) == content
54+
55+
656
class TestPresentation:
57+
def setUp(self):
58+
text.TABLEFMT = "simple"
59+
760
def test_normal_usage(self):
861
content = [
962
[1, 2, 3],
@@ -130,4 +183,3 @@ def test_book_presentation(self):
130183
4.0 3.0 2.0
131184
--- --- ---""").strip("\n")
132185
assert str(book) == content
133-

0 commit comments

Comments
 (0)