xlsxlite 0.1.0__tar.gz → 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of xlsxlite might be problematic. Click here for more details.

xlsxlite-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020-2022 TextIt
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,13 @@
1
+ Metadata-Version: 2.3
2
+ Name: xlsxlite
3
+ Version: 1.0.0
4
+ Summary: Lightweight XLSX writer with emphasis on minimizing memory usage.
5
+ License: MIT
6
+ Author: TextIt
7
+ Author-email: code@textit.com
8
+ Requires-Python: >=3.10
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python
13
+ Project-URL: repository, http://github.com/nyaruka/xlsxlite
@@ -0,0 +1,32 @@
1
+ [project]
2
+ name = "xlsxlite"
3
+ version = "1.0.0"
4
+ description = "Lightweight XLSX writer with emphasis on minimizing memory usage."
5
+ authors = [
6
+ {"name" = "TextIt", "email" = "code@textit.com"}
7
+ ]
8
+ license = "MIT"
9
+ classifiers=[
10
+ 'Intended Audience :: Developers',
11
+ 'License :: OSI Approved :: MIT License',
12
+ 'Operating System :: OS Independent',
13
+ 'Programming Language :: Python',
14
+ ]
15
+ requires-python = ">=3.10"
16
+ dependencies = []
17
+
18
+ [tool.poetry.urls]
19
+ repository = "http://github.com/nyaruka/xlsxlite"
20
+
21
+ [tool.poetry.group.dev.dependencies]
22
+ pytest = "^8.3.4"
23
+ pytest-cov = "^6.0.0"
24
+ pytz = "^2024.2"
25
+ XlsxWriter = "^3.2.0"
26
+ openpyxl = "3.1.5"
27
+ lxml = "^5.3.0"
28
+ flake8 = "^7.1.1"
29
+
30
+ [build-system]
31
+ requires = ["poetry-core>=2.0.0,<3.0.0"]
32
+ build-backend = "poetry.core.masonry.api"
File without changes
@@ -1,9 +1,18 @@
1
- from datetime import datetime, timedelta
1
+ import os
2
+ import pytest
3
+ import shutil
2
4
  import unittest
5
+ from datetime import datetime, timedelta
3
6
 
4
7
 
5
- class XLSXTest(unittest.TestCase):
8
+ @pytest.fixture
9
+ def tests_dir():
10
+ os.mkdir("_tests")
11
+ yield
12
+ shutil.rmtree("_tests")
6
13
 
14
+
15
+ class XLSXTest(unittest.TestCase):
7
16
  def assertExcelRow(self, sheet, row_num, values, tz=None):
8
17
  """
9
18
  Asserts the cell values in the given worksheet row. Date values are converted using the provided timezone.
@@ -0,0 +1,76 @@
1
+ import pytest
2
+ import random
3
+ import string
4
+ import xlsxwriter
5
+
6
+ from openpyxl import Workbook
7
+ from openpyxl.cell.cell import WriteOnlyCell
8
+ from openpyxl.cell._writer import etree_write_cell
9
+ from unittest.mock import patch
10
+ from xlsxlite.writer import XLSXBook
11
+ from .base import tests_dir # noqa
12
+
13
+
14
+ NUM_ROWS = 1000
15
+ NUM_COLS = 10
16
+
17
+ # generate some random strings to use as cell values
18
+ DATA = ["".join(random.choices(string.ascii_uppercase + string.digits, k=16)) for d in range(1000)]
19
+
20
+
21
+ @pytest.mark.usefixtures("tests_dir")
22
+ def test_xlxslite():
23
+ book = XLSXBook()
24
+ sheet1 = book.add_sheet("Sheet1")
25
+
26
+ for r in range(NUM_ROWS):
27
+ row = [DATA[(r * c) % len(DATA)] for c in range(NUM_COLS)]
28
+
29
+ sheet1.append_row(*row)
30
+
31
+ book.finalize(to_file="_tests/test.xlsx")
32
+
33
+
34
+ @pytest.mark.usefixtures("tests_dir")
35
+ @patch("openpyxl.cell._writer.write_cell")
36
+ def test_openpyxl_etree(mock_write_cell):
37
+ mock_write_cell.side_effect = etree_write_cell
38
+
39
+ book = Workbook(write_only=True)
40
+ sheet1 = book.create_sheet("Sheet1")
41
+
42
+ for r in range(NUM_ROWS):
43
+ row = [DATA[(r * c) % len(DATA)] for c in range(NUM_COLS)]
44
+
45
+ cells = [WriteOnlyCell(sheet1, value=v) for v in row]
46
+ sheet1.append(cells)
47
+
48
+ book.save("_tests/test.xlsx")
49
+
50
+
51
+ @pytest.mark.usefixtures("tests_dir")
52
+ def test_openpyxl_lxml():
53
+ book = Workbook(write_only=True)
54
+ sheet1 = book.create_sheet("Sheet1")
55
+
56
+ for r in range(NUM_ROWS):
57
+ row = [DATA[(r * c) % len(DATA)] for c in range(NUM_COLS)]
58
+
59
+ cells = [WriteOnlyCell(sheet1, value=v) for v in row]
60
+ sheet1.append(cells)
61
+
62
+ book.save("_tests/test.xlsx")
63
+
64
+
65
+ @pytest.mark.usefixtures("tests_dir")
66
+ def test_xlsxwriter():
67
+ book = xlsxwriter.Workbook("_tests/test.xlsx")
68
+ sheet1 = book.add_worksheet()
69
+
70
+ for r in range(NUM_ROWS):
71
+ row = [DATA[(r * c) % len(DATA)] for c in range(NUM_COLS)]
72
+
73
+ for c, val in enumerate(row):
74
+ sheet1.write(r, c, val)
75
+
76
+ book.close()
@@ -0,0 +1,15 @@
1
+ from datetime import datetime
2
+
3
+ import pytest
4
+ import pytz
5
+
6
+ from xlsxlite.utils import datetime_to_serial
7
+
8
+
9
+ def test_datetime_to_serial():
10
+ assert datetime_to_serial(datetime(2013, 1, 1, 12, 0, 0)) == 41275.5
11
+ assert datetime_to_serial(datetime(2018, 6, 15, 11, 24, 30, 0)) == 43266.47534722222
12
+
13
+ # try with a non-naive datetime
14
+ with pytest.raises(ValueError):
15
+ datetime_to_serial(datetime(2018, 6, 15, 11, 24, 30, 0, pytz.UTC))
@@ -1,29 +1,15 @@
1
- import os
2
- import pytest
3
- import pytz
4
- import random
5
- import shutil
6
- import string
7
- import time
8
-
9
1
  from datetime import datetime, timedelta
10
- from mock import patch
11
- from openpyxl.reader.excel import load_workbook
12
- from unittest import skip
13
- from xlsxlite.book import XLSXBook
14
- from .base import XLSXTest
15
2
 
3
+ import pytest
4
+ from openpyxl.reader.excel import load_workbook
5
+ from unittest.mock import patch
6
+ from xlsxlite.writer import XLSXBook
16
7
 
17
- @pytest.fixture(scope="module")
18
- def tests_dir():
19
- os.mkdir("_tests")
20
- yield
21
- shutil.rmtree("_tests")
8
+ from .base import XLSXTest, tests_dir # noqa
22
9
 
23
10
 
24
11
  @pytest.mark.usefixtures("tests_dir")
25
12
  class BookTest(XLSXTest):
26
-
27
13
  def test_empty(self):
28
14
  book = XLSXBook()
29
15
  book.finalize(to_file="_tests/empty.xlsx")
@@ -54,16 +40,16 @@ class BookTest(XLSXTest):
54
40
  assert sheet2.title == "People"
55
41
  assert sheet3.title == "Empty"
56
42
 
57
- self.assertExcelSheet(sheet1, [()])
43
+ self.assertExcelSheet(sheet1, [])
58
44
  self.assertExcelSheet(sheet2, [("Name", "Email"), ("Jim", "jim@acme.com"), ("Bob", "bob@acme.com")])
59
- self.assertExcelSheet(sheet3, [()])
45
+ self.assertExcelSheet(sheet3, [])
60
46
 
61
47
  def test_cell_types(self):
62
- d1 = datetime(2018, 6, 14, 11, 26, 30, 0, pytz.UTC)
48
+ d1 = datetime(2013, 1, 1, 12, 0, 0)
63
49
 
64
50
  book = XLSXBook()
65
51
  sheet1 = book.add_sheet("Test")
66
- sheet1.append_row("str", 3, 1.23, d1)
52
+ sheet1.append_row("str", True, False, 3, 1.23, d1)
67
53
 
68
54
  # try to write a cell value with an unsupported type
69
55
  with pytest.raises(ValueError):
@@ -72,58 +58,31 @@ class BookTest(XLSXTest):
72
58
  book.finalize(to_file="_tests/types.xlsx")
73
59
 
74
60
  book = load_workbook(filename="_tests/types.xlsx")
75
- self.assertExcelSheet(book.worksheets[0], [("str", 3, 1.23, d1)], tz=pytz.UTC)
61
+ self.assertExcelSheet(book.worksheets[0], [("str", True, False, 3, 1.23, d1)])
76
62
 
77
63
  def test_escaping(self):
78
64
  book = XLSXBook()
79
65
  sheet1 = book.add_sheet("Test")
80
- sheet1.append_row("< & > \" ! =")
66
+ sheet1.append_row('< & > " ! =')
81
67
  book.finalize(to_file="_tests/escaped.xlsx")
82
68
 
83
69
  book = load_workbook(filename="_tests/escaped.xlsx")
84
- self.assertExcelSheet(book.worksheets[0], [("< & > \" ! =",)])
70
+ self.assertExcelSheet(book.worksheets[0], [('< & > " ! =',)])
85
71
 
86
72
  def test_sheet_limits(self):
87
73
  book = XLSXBook()
88
74
  sheet1 = book.add_sheet("Sheet1")
89
75
 
90
76
  # try to add row with too many columns
91
- column = ['x'] * 20000
77
+ column = ["x"] * 20000
92
78
  with pytest.raises(ValueError):
93
79
  sheet1.append_row(*column)
94
80
 
95
81
  # try to add more rows than allowed
96
- with patch('xlsxlite.book.XLSXSheet.MAX_ROWS', 3):
97
- sheet1.append_row('x')
98
- sheet1.append_row('x')
99
- sheet1.append_row('x')
82
+ with patch("xlsxlite.writer.XLSXSheet.MAX_ROWS", 3):
83
+ sheet1.append_row("x")
84
+ sheet1.append_row("x")
85
+ sheet1.append_row("x")
100
86
 
101
87
  with pytest.raises(ValueError):
102
- sheet1.append_row('x')
103
-
104
- @skip
105
- def test_performance(self):
106
- def random_val():
107
- return ''.join(random.choices(string.ascii_uppercase + string.digits, k=16))
108
-
109
- t0 = time.time()
110
-
111
- book = XLSXBook()
112
- sheet1 = book.add_sheet("Sheet1")
113
- book.add_sheet("Sheet2")
114
-
115
- t1 = time.time()
116
- print(f"Initialized workbook in {t1 - t0} seconds")
117
-
118
- num_rows = 1024 * 1024
119
- for r in range(num_rows):
120
- row = [random_val() for c in range(10)]
121
- sheet1.append_row(*row)
122
-
123
- t2 = time.time()
124
- print(f"Wrote {num_rows} rows in {t2 - t1} seconds")
125
-
126
- book.finalize(to_file="_tests/simple.xlsx")
127
-
128
- t3 = time.time()
129
- print(f"Finalized XLSX file in {t3 - t2} seconds")
88
+ sheet1.append_row("x")
@@ -0,0 +1,14 @@
1
+ from datetime import datetime
2
+
3
+
4
+ def datetime_to_serial(dt):
5
+ """
6
+ Converts the given datetime to the Excel serial format
7
+ """
8
+ if dt.tzinfo:
9
+ raise ValueError("Doesn't support datetimes with timezones")
10
+
11
+ temp = datetime(1899, 12, 30)
12
+ delta = dt - temp
13
+
14
+ return delta.days + (float(delta.seconds) + float(delta.microseconds) / 1E6) / (60 * 60 * 24)
@@ -3,18 +3,53 @@ import shutil
3
3
  import tempfile
4
4
  import xml.etree.ElementTree as ET
5
5
  import zipfile
6
-
7
6
  from datetime import datetime
8
7
  from xml.sax.saxutils import escape
9
8
 
9
+ from .utils import datetime_to_serial
10
10
 
11
11
  XML_HEADER = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n"""
12
- WORKBOOK_HEADER = (
13
- """<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">"""
14
- )
15
- WORKSHEET_HEADER = (
16
- """<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">"""
17
- )
12
+
13
+ WORKBOOK_HEADER = """<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">"""
14
+ WORKSHEET_HEADER = """<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">"""
15
+
16
+ MINIMAL_STYLESHEET = """<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
17
+ <numFmts count="1">
18
+ <numFmt formatCode="yyyy-mm-dd h:mm:ss" numFmtId="164"/>
19
+ </numFmts>
20
+ <fonts count="1">
21
+ <font>
22
+ <name val="Calibri"/>
23
+ <family val="2"/>
24
+ <color theme="1"/>
25
+ <sz val="11"/>
26
+ <scheme val="minor"/>
27
+ </font>
28
+ </fonts>
29
+ <fills count="2">
30
+ <fill><patternFill/></fill>
31
+ <fill><patternFill patternType="gray125"/></fill>
32
+ </fills>
33
+ <borders count="1">
34
+ <border>
35
+ <left/>
36
+ <right/>
37
+ <top/>
38
+ <bottom/>
39
+ <diagonal/>
40
+ </border>
41
+ </borders>
42
+ <cellStyleXfs count="1">
43
+ <xf borderId="0" fillId="0" fontId="0" numFmtId="0"/>
44
+ </cellStyleXfs>
45
+ <cellXfs count="2">
46
+ <xf borderId="0" fillId="0" fontId="0" numFmtId="0" pivotButton="0" quotePrefix="0" xfId="0"/>
47
+ <xf borderId="0" fillId="0" fontId="0" numFmtId="164" pivotButton="0" quotePrefix="0" xfId="0"/>
48
+ </cellXfs>
49
+ <cellStyles count="1">
50
+ <cellStyle builtinId="0" hidden="0" name="Normal" xfId="0"/>
51
+ </cellStyles>
52
+ </styleSheet>"""
18
53
 
19
54
  # use a nice big 1MB I/O buffer for the worksheet files
20
55
  WORKSHEET_IO_BUFFER = 1048576
@@ -24,6 +59,7 @@ class XLSXSheet:
24
59
  """
25
60
  A worksheet within a XLSX workbook
26
61
  """
62
+
27
63
  MAX_ROWS = 1048576
28
64
  MAX_COLS = 16384
29
65
 
@@ -53,11 +89,13 @@ class XLSXSheet:
53
89
  row = "<row>"
54
90
  for val in columns:
55
91
  if isinstance(val, str):
56
- row += f"<c t=\"inlineStr\"><is><t>{escape(val)}</t></is></c>"
92
+ row += f'<c t="inlineStr"><is><t>{escape(val)}</t></is></c>'
93
+ elif isinstance(val, bool):
94
+ row += f'<c t="b"><v>{int(val)}</v></c>'
57
95
  elif isinstance(val, (int, float)):
58
- row += f"<c t=\"n\"><v>{str(val)}</v></c>"
96
+ row += f'<c t="n"><v>{str(val)}</v></c>'
59
97
  elif isinstance(val, datetime):
60
- row += f"<c t=\"d\"><v>{val.isoformat()}</v></c>"
98
+ row += f'<c t="n" s="1"><v>{datetime_to_serial(val)}</v></c>'
61
99
  else:
62
100
  raise ValueError(f"Unsupported type in column data: {type(val)}")
63
101
 
@@ -78,6 +116,7 @@ class XLSXBook:
78
116
  """
79
117
  An XLSX workbook
80
118
  """
119
+
81
120
  def __init__(self):
82
121
  self.base_dir = tempfile.mkdtemp()
83
122
  self.app_dir = os.path.join(self.base_dir, "xl")
@@ -108,6 +147,14 @@ class XLSXBook:
108
147
  {"Extension": "rels", "ContentType": "application/vnd.openxmlformats-package.relationships+xml"},
109
148
  )
110
149
  ET.SubElement(types, "Default", {"Extension": "xml", "ContentType": "application/xml"})
150
+ ET.SubElement(
151
+ types,
152
+ "Override",
153
+ {
154
+ "PartName": "/xl/styles.xml",
155
+ "ContentType": "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
156
+ },
157
+ )
111
158
  ET.SubElement(
112
159
  types,
113
160
  "Override",
@@ -171,10 +218,25 @@ class XLSXBook:
171
218
  },
172
219
  )
173
220
 
221
+ ET.SubElement(
222
+ relationships,
223
+ "Relationship",
224
+ {
225
+ "Id": "rIdStyles",
226
+ "Type": "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
227
+ "Target": "styles.xml",
228
+ },
229
+ )
230
+
174
231
  with open(os.path.join(self.app_dir, "_rels/workbook.xml.rels"), "w", encoding="utf-8") as f:
175
232
  f.write(XML_HEADER)
176
233
  f.write(ET.tostring(relationships, encoding="unicode"))
177
234
 
235
+ def _create_styles(self):
236
+ with open(os.path.join(self.app_dir, "styles.xml"), "w", encoding="utf-8") as f:
237
+ f.write(XML_HEADER)
238
+ f.write(MINIMAL_STYLESHEET)
239
+
178
240
  def _create_workbook(self):
179
241
  sheets = ET.Element("sheets")
180
242
  for sheet in self.sheets:
@@ -204,6 +266,7 @@ class XLSXBook:
204
266
  self._create_content_types()
205
267
  self._create_root_rels()
206
268
  self._create_app_rels()
269
+ self._create_styles()
207
270
  self._create_workbook()
208
271
 
209
272
  for sheet in self.sheets:
xlsxlite-0.1.0/PKG-INFO DELETED
@@ -1,50 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: xlsxlite
3
- Version: 0.1.0
4
- Summary: Lightweight XLSX writer with emphasis on minimizing memory usage.
5
- Home-page: http://github.com/nyaruka/xlxslite
6
- Author: Nyaruka
7
- Author-email: code@nyaruka.com
8
- License: MIT
9
- Project-URL: Bug Reports, https://github.com/nyaruka/xlsxlite/issues
10
- Project-URL: Source, https://github.com/nyaruka/xlsxlite/
11
- Description: # Introduction
12
-
13
- [![Build Status](https://travis-ci.org/nyaruka/xlsxlite.svg?branch=master)](https://travis-ci.org/nyaruka/xlsxlite)
14
- [![Coverage Status](https://coveralls.io/repos/github/nyaruka/xlsxlite/badge.svg?branch=master)](https://coveralls.io/github/nyaruka/xlsxlite?branch=master)
15
- [![PyPI Release](https://img.shields.io/pypi/v/xlsxlite.svg)](https://pypi.python.org/pypi/xlsxlite/)
16
-
17
- XLSXLite is a lightweight XLSX writer with emphasis on minimizing memory usage. It's also really fast.
18
-
19
- ```python
20
- from xlsxlite.book import XLSXBook
21
- book = XLSXBook()
22
- sheet1 = book.add_sheet("People")
23
- sheet1.append_row("Name", "Email", "Age")
24
- sheet1.append_row("Jim", "jim@acme.com", 45)
25
- book.finalize(to_file="simple.xlsx")
26
- ```
27
-
28
- ## Limitations
29
-
30
- This library is for projects which need to generate large spreadsheets, quickly, for the purposes of data exchange, and
31
- so it intentionally only supports a tiny subset of XLSX specification:
32
-
33
- * No styling
34
- * Only strings, numbers and dates are supported cell types
35
-
36
- ## Development
37
-
38
- To run all tests:
39
-
40
- ```
41
- py.test xlsxlite -s
42
- ```
43
-
44
- Keywords: excel xlxs
45
- Platform: UNKNOWN
46
- Classifier: Intended Audience :: Developers
47
- Classifier: License :: OSI Approved :: MIT License
48
- Classifier: Operating System :: OS Independent
49
- Classifier: Programming Language :: Python
50
- Description-Content-Type: text/markdown
xlsxlite-0.1.0/README.md DELETED
@@ -1,32 +0,0 @@
1
- # Introduction
2
-
3
- [![Build Status](https://travis-ci.org/nyaruka/xlsxlite.svg?branch=master)](https://travis-ci.org/nyaruka/xlsxlite)
4
- [![Coverage Status](https://coveralls.io/repos/github/nyaruka/xlsxlite/badge.svg?branch=master)](https://coveralls.io/github/nyaruka/xlsxlite?branch=master)
5
- [![PyPI Release](https://img.shields.io/pypi/v/xlsxlite.svg)](https://pypi.python.org/pypi/xlsxlite/)
6
-
7
- XLSXLite is a lightweight XLSX writer with emphasis on minimizing memory usage. It's also really fast.
8
-
9
- ```python
10
- from xlsxlite.book import XLSXBook
11
- book = XLSXBook()
12
- sheet1 = book.add_sheet("People")
13
- sheet1.append_row("Name", "Email", "Age")
14
- sheet1.append_row("Jim", "jim@acme.com", 45)
15
- book.finalize(to_file="simple.xlsx")
16
- ```
17
-
18
- ## Limitations
19
-
20
- This library is for projects which need to generate large spreadsheets, quickly, for the purposes of data exchange, and
21
- so it intentionally only supports a tiny subset of XLSX specification:
22
-
23
- * No styling
24
- * Only strings, numbers and dates are supported cell types
25
-
26
- ## Development
27
-
28
- To run all tests:
29
-
30
- ```
31
- py.test xlsxlite -s
32
- ```
xlsxlite-0.1.0/setup.cfg DELETED
@@ -1,29 +0,0 @@
1
- [flake8]
2
- max-line-length = 120
3
- filename = *.py,*.py.dev
4
- exclude = ./env/*,./config/*,./fab*,.git/*,static/bower/*,sitestatic/bower/,*/gen/*
5
- ignore = E501,F405,T003,E203,W503
6
-
7
- [isort]
8
- multi_line_output = 3
9
- including_trailing_comma = True
10
- force_grid_wrap = 0
11
- line_length = 119
12
- include_trailing_comma = True
13
- combine_as_imports = True
14
- sections = FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
15
-
16
- [coverage:run]
17
- source = xlsxlite
18
- omit = xlsxlite/test/*
19
-
20
- [metadata]
21
- license_file = LICENSE
22
-
23
- [bdist_wheel]
24
- universal = 1
25
-
26
- [egg_info]
27
- tag_build =
28
- tag_date = 0
29
-
xlsxlite-0.1.0/setup.py DELETED
@@ -1,53 +0,0 @@
1
- # Always prefer setuptools over distutils
2
- from setuptools import setup, find_packages
3
- from os import path
4
-
5
- here = path.abspath(path.dirname(__file__))
6
-
7
- # Get the long description from the README file
8
- with open(path.join(here, 'README.md'), encoding='utf-8') as f:
9
- long_description = f.read()
10
-
11
-
12
- def _is_requirement(line):
13
- """Returns whether the line is a valid package requirement."""
14
- line = line.strip()
15
- return line and not line.startswith("#")
16
-
17
-
18
- def _read_requirements(filename):
19
- """Parses a file for pip installation requirements."""
20
- with open(filename) as requirements_file:
21
- contents = requirements_file.read()
22
- return [line.strip() for line in contents.splitlines() if _is_requirement(line)]
23
-
24
-
25
- setup(
26
- name='xlsxlite',
27
- version=__import__('xlsxlite').__version__,
28
- description='Lightweight XLSX writer with emphasis on minimizing memory usage.',
29
- long_description=long_description,
30
- long_description_content_type='text/markdown',
31
-
32
- classifiers=[
33
- 'Intended Audience :: Developers',
34
- 'License :: OSI Approved :: MIT License',
35
- 'Operating System :: OS Independent',
36
- 'Programming Language :: Python'
37
- ],
38
- keywords='excel xlxs',
39
- url='http://github.com/nyaruka/xlxslite',
40
- license='MIT',
41
-
42
- author='Nyaruka',
43
- author_email='code@nyaruka.com',
44
-
45
- packages=find_packages(),
46
- install_requires=_read_requirements("requirements/base.txt"),
47
- tests_require=_read_requirements("requirements/tests.txt"),
48
-
49
- project_urls={
50
- 'Bug Reports': 'https://github.com/nyaruka/xlsxlite/issues',
51
- 'Source': 'https://github.com/nyaruka/xlsxlite/',
52
- },
53
- )
@@ -1 +0,0 @@
1
- __version__ = "0.1.0"
@@ -1,50 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: xlsxlite
3
- Version: 0.1.0
4
- Summary: Lightweight XLSX writer with emphasis on minimizing memory usage.
5
- Home-page: http://github.com/nyaruka/xlxslite
6
- Author: Nyaruka
7
- Author-email: code@nyaruka.com
8
- License: MIT
9
- Project-URL: Bug Reports, https://github.com/nyaruka/xlsxlite/issues
10
- Project-URL: Source, https://github.com/nyaruka/xlsxlite/
11
- Description: # Introduction
12
-
13
- [![Build Status](https://travis-ci.org/nyaruka/xlsxlite.svg?branch=master)](https://travis-ci.org/nyaruka/xlsxlite)
14
- [![Coverage Status](https://coveralls.io/repos/github/nyaruka/xlsxlite/badge.svg?branch=master)](https://coveralls.io/github/nyaruka/xlsxlite?branch=master)
15
- [![PyPI Release](https://img.shields.io/pypi/v/xlsxlite.svg)](https://pypi.python.org/pypi/xlsxlite/)
16
-
17
- XLSXLite is a lightweight XLSX writer with emphasis on minimizing memory usage. It's also really fast.
18
-
19
- ```python
20
- from xlsxlite.book import XLSXBook
21
- book = XLSXBook()
22
- sheet1 = book.add_sheet("People")
23
- sheet1.append_row("Name", "Email", "Age")
24
- sheet1.append_row("Jim", "jim@acme.com", 45)
25
- book.finalize(to_file="simple.xlsx")
26
- ```
27
-
28
- ## Limitations
29
-
30
- This library is for projects which need to generate large spreadsheets, quickly, for the purposes of data exchange, and
31
- so it intentionally only supports a tiny subset of XLSX specification:
32
-
33
- * No styling
34
- * Only strings, numbers and dates are supported cell types
35
-
36
- ## Development
37
-
38
- To run all tests:
39
-
40
- ```
41
- py.test xlsxlite -s
42
- ```
43
-
44
- Keywords: excel xlxs
45
- Platform: UNKNOWN
46
- Classifier: Intended Audience :: Developers
47
- Classifier: License :: OSI Approved :: MIT License
48
- Classifier: Operating System :: OS Independent
49
- Classifier: Programming Language :: Python
50
- Description-Content-Type: text/markdown
@@ -1,12 +0,0 @@
1
- README.md
2
- setup.cfg
3
- setup.py
4
- xlsxlite/__init__.py
5
- xlsxlite/book.py
6
- xlsxlite.egg-info/PKG-INFO
7
- xlsxlite.egg-info/SOURCES.txt
8
- xlsxlite.egg-info/dependency_links.txt
9
- xlsxlite.egg-info/top_level.txt
10
- xlsxlite/test/__init__.py
11
- xlsxlite/test/base.py
12
- xlsxlite/test/test_book.py
@@ -1 +0,0 @@
1
- xlsxlite