New style reader writer (#39)
* 🎉 new style ods reader written * This is an auto-commit, updating project meta data, such as changelog.rst, contributors.rst * ✨ new style ods writer Co-authored-by: chfw <chfw@users.noreply.github.com>
This commit is contained in:
parent
07ee703b59
commit
24813b2d34
|
@ -1,6 +1,6 @@
|
|||
[settings]
|
||||
line_length=79
|
||||
known_first_party=lml, pyexcel, odfpy
|
||||
known_first_party=lml, pyexcel_io, odf
|
||||
known_third_party=nose
|
||||
indent=' '
|
||||
multi_line_output=3
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
Change log
|
||||
================================================================================
|
||||
|
||||
0.6.0 - 2020
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
**added**
|
||||
|
||||
#. new style reader and writer plugins. works with pyexcel-io v0.6.0
|
||||
|
||||
0.5.6 - 19.03.2019
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
name: pyexcel-ods
|
||||
organisation: pyexcel
|
||||
releases:
|
||||
- changes:
|
||||
- action: added
|
||||
details:
|
||||
- 'new style reader and writer plugins. works with pyexcel-io v0.6.0'
|
||||
date: 2020
|
||||
version: 0.6.0
|
||||
- changes:
|
||||
- action: added
|
||||
details:
|
||||
|
|
|
@ -25,7 +25,7 @@ project = 'pyexcel-ods'
|
|||
copyright = '2015-2020 Onni Software Ltd.'
|
||||
author = 'chfw'
|
||||
# The short X.Y version
|
||||
version = '0.5.6'
|
||||
version = '0.6.0'
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = '0.5.6'
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
overrides: "pyexcel.yaml"
|
||||
name: "pyexcel-ods"
|
||||
nick_name: ods
|
||||
version: 0.5.6
|
||||
current_version: 0.5.6
|
||||
version: 0.6.0
|
||||
current_version: 0.6.0
|
||||
release: 0.5.6
|
||||
copyright_year: 2015-2020
|
||||
file_type: ods
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
pyexcel_ods
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
The lower level ods file format handler using odfpy
|
||||
:copyright: (c) 2015-2017 by Onni Software Ltd & its contributors
|
||||
:copyright: (c) 2015-2020 by Onni Software Ltd & its contributors
|
||||
:license: New BSD License
|
||||
"""
|
||||
|
||||
|
@ -13,15 +13,23 @@ from pyexcel_io.io import store_data as write_data
|
|||
|
||||
# this line has to be place above all else
|
||||
# because of dynamic import
|
||||
from pyexcel_io.plugins import IOPluginInfoChain
|
||||
from pyexcel_io.plugins import IOPluginInfoChain, IOPluginInfoChainV2
|
||||
|
||||
__FILE_TYPE__ = "ods"
|
||||
IOPluginInfoChain(__name__).add_a_reader(
|
||||
IOPluginInfoChain(__name__)
|
||||
IOPluginInfoChainV2(__name__).add_a_reader(
|
||||
relative_plugin_class_path="odsr.ODSBook",
|
||||
locations=["file", "memory"],
|
||||
file_types=[__FILE_TYPE__],
|
||||
stream_type="binary",
|
||||
).add_a_reader(
|
||||
relative_plugin_class_path="odsr.ODSBookInContent",
|
||||
locations=["content"],
|
||||
file_types=[__FILE_TYPE__],
|
||||
stream_type="binary",
|
||||
).add_a_writer(
|
||||
relative_plugin_class_path="odsw.ODSWriter",
|
||||
locations=["file", "memory"],
|
||||
file_types=[__FILE_TYPE__],
|
||||
stream_type="binary",
|
||||
)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
ods reader
|
||||
|
||||
:copyright: (c) 2014-2017 by Onni Software Ltd.
|
||||
:copyright: (c) 2014-2020 by Onni Software Ltd.
|
||||
:license: New BSD License, see LICENSE for more details
|
||||
"""
|
||||
# Copyright 2011 Marco Conti
|
||||
|
@ -20,6 +20,7 @@
|
|||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from io import BytesIO
|
||||
|
||||
import pyexcel_io.service as service
|
||||
from odf.text import P
|
||||
|
@ -28,17 +29,17 @@ from odf.table import Table, TableRow, TableCell
|
|||
# Thanks to grt for the fixes
|
||||
from odf.teletype import extractText
|
||||
from odf.namespaces import OFFICENS
|
||||
from pyexcel_io.book import BookReader
|
||||
from odf.opendocument import load
|
||||
from pyexcel_io.sheet import SheetReader
|
||||
from pyexcel_io._compact import OrderedDict
|
||||
from pyexcel_io.plugin_api.abstract_sheet import ISheet
|
||||
from pyexcel_io.plugin_api.abstract_reader import IReader
|
||||
|
||||
|
||||
class ODSSheet(SheetReader):
|
||||
class ODSSheet(ISheet):
|
||||
"""native ods sheet"""
|
||||
|
||||
def __init__(self, sheet, auto_detect_int=True, **keywords):
|
||||
SheetReader.__init__(self, sheet, **keywords)
|
||||
self._native_sheet = sheet
|
||||
self._keywords = keywords
|
||||
self.__auto_detect_int = auto_detect_int
|
||||
|
||||
@property
|
||||
|
@ -99,62 +100,38 @@ class ODSSheet(SheetReader):
|
|||
return "\n".join(text_content)
|
||||
|
||||
|
||||
class ODSBook(BookReader):
|
||||
class ODSBook(IReader):
|
||||
"""read ods book"""
|
||||
|
||||
def open(self, file_name, **keywords):
|
||||
"""open ods file"""
|
||||
BookReader.open(self, file_name, **keywords)
|
||||
self._load_from_file()
|
||||
|
||||
def open_stream(self, file_stream, **keywords):
|
||||
"""open ods file stream"""
|
||||
BookReader.open_stream(self, file_stream, **keywords)
|
||||
self._load_from_memory()
|
||||
|
||||
def read_sheet_by_name(self, sheet_name):
|
||||
"""read a named sheet"""
|
||||
tables = self._native_book.spreadsheet.getElementsByType(Table)
|
||||
rets = [
|
||||
table
|
||||
for table in tables
|
||||
if table.getAttribute("name") == sheet_name
|
||||
def __init__(self, file_alike_object, _, **keywords):
|
||||
self._native_book = load(file_alike_object)
|
||||
self._keywords = keywords
|
||||
self.content_array = [
|
||||
NameObject(table.getAttribute("name"), table)
|
||||
for table in self._native_book.spreadsheet.getElementsByType(Table)
|
||||
]
|
||||
if len(rets) == 0:
|
||||
raise ValueError("%s cannot be found" % sheet_name)
|
||||
else:
|
||||
return self.read_sheet(rets[0])
|
||||
|
||||
def read_sheet_by_index(self, sheet_index):
|
||||
def read_sheet(self, sheet_index):
|
||||
"""read a sheet at a specified index"""
|
||||
tables = self._native_book.spreadsheet.getElementsByType(Table)
|
||||
length = len(tables)
|
||||
if sheet_index < length:
|
||||
return self.read_sheet(tables[sheet_index])
|
||||
else:
|
||||
raise IndexError(
|
||||
"Index %d of out bound %d" % (sheet_index, length)
|
||||
)
|
||||
|
||||
def read_all(self):
|
||||
"""read all sheets"""
|
||||
result = OrderedDict()
|
||||
for sheet in self._native_book.spreadsheet.getElementsByType(Table):
|
||||
ods_sheet = ODSSheet(sheet, **self._keywords)
|
||||
result[ods_sheet.name] = ods_sheet.to_array()
|
||||
|
||||
return result
|
||||
|
||||
def read_sheet(self, native_sheet):
|
||||
"""read one native sheet"""
|
||||
sheet = ODSSheet(native_sheet, **self._keywords)
|
||||
return {sheet.name: sheet.to_array()}
|
||||
table = self.content_array[sheet_index].sheet
|
||||
sheet = ODSSheet(table, **self._keywords)
|
||||
return sheet
|
||||
|
||||
def close(self):
|
||||
self._native_book = None
|
||||
|
||||
def _load_from_memory(self):
|
||||
self._native_book = load(self._file_stream)
|
||||
|
||||
def _load_from_file(self):
|
||||
self._native_book = load(self._file_name)
|
||||
class ODSBookInContent(ODSBook):
|
||||
"""
|
||||
Open xlsx as read only mode
|
||||
"""
|
||||
|
||||
def __init__(self, file_content, file_type, **keywords):
|
||||
io = BytesIO(file_content)
|
||||
super().__init__(io, file_type, **keywords)
|
||||
|
||||
|
||||
class NameObject(object):
|
||||
def __init__(self, name, sheet):
|
||||
self.name = name
|
||||
self.sheet = sheet
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
ods writer
|
||||
|
||||
:copyright: (c) 2014-2017 by Onni Software Ltd.
|
||||
:copyright: (c) 2014-2020 by Onni Software Ltd.
|
||||
:license: New BSD License, see LICENSE for more details
|
||||
"""
|
||||
import sys
|
||||
|
@ -13,27 +13,23 @@ import pyexcel_io.service as converter
|
|||
from odf.text import P
|
||||
from odf.table import Table, TableRow, TableCell
|
||||
from odf.namespaces import OFFICENS
|
||||
from pyexcel_io.book import BookWriter
|
||||
from odf.opendocument import OpenDocumentSpreadsheet
|
||||
from pyexcel_io.sheet import SheetWriter
|
||||
from pyexcel_io.plugin_api.abstract_sheet import ISheetWriter
|
||||
from pyexcel_io.plugin_api.abstract_writer import IWriter
|
||||
|
||||
PY2 = sys.version_info[0] == 2
|
||||
|
||||
PY27_BELOW = PY2 and sys.version_info[1] < 7
|
||||
|
||||
|
||||
class ODSSheetWriter(SheetWriter):
|
||||
class ODSSheetWriter(ISheetWriter):
|
||||
"""
|
||||
ODS sheet writer
|
||||
"""
|
||||
|
||||
def set_sheet_name(self, name):
|
||||
"""initialize the native table"""
|
||||
self._native_sheet = Table(name=name)
|
||||
|
||||
def set_size(self, size):
|
||||
"""not used in this class but used in ods3"""
|
||||
pass
|
||||
def __init__(self, ods_book, ods_sheet, sheet_name, **keywords):
|
||||
self._native_book = ods_book
|
||||
self._native_sheet = Table(name=sheet_name)
|
||||
|
||||
def write_cell(self, row, cell):
|
||||
"""write a native cell"""
|
||||
|
@ -77,14 +73,14 @@ class ODSSheetWriter(SheetWriter):
|
|||
self._native_book.spreadsheet.addElement(self._native_sheet)
|
||||
|
||||
|
||||
class ODSWriter(BookWriter):
|
||||
class ODSWriter(IWriter):
|
||||
"""
|
||||
open document spreadsheet writer
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
BookWriter.__init__(self)
|
||||
def __init__(self, file_alike_object, file_type, **keywords):
|
||||
self._file_alike_object = file_alike_object
|
||||
self._native_book = OpenDocumentSpreadsheet()
|
||||
|
||||
def create_sheet(self, name):
|
||||
|
|
2
setup.py
2
setup.py
|
@ -29,7 +29,7 @@ except (ValueError, UnicodeError, locale.Error):
|
|||
|
||||
NAME = "pyexcel-ods"
|
||||
AUTHOR = "chfw"
|
||||
VERSION = "0.5.6"
|
||||
VERSION = "0.6.0"
|
||||
EMAIL = "info@pyexcel.org"
|
||||
LICENSE = "New BSD"
|
||||
DESCRIPTION = (
|
||||
|
|
|
@ -7,8 +7,9 @@ from pyexcel_ods.odsw import ODSWriter
|
|||
|
||||
class TestODSReader(ODSCellTypes):
|
||||
def setUp(self):
|
||||
r = ODSBook()
|
||||
r.open(os.path.join("tests", "fixtures", "ods_formats.ods"))
|
||||
r = ODSBook(
|
||||
os.path.join("tests", "fixtures", "ods_formats.ods"), "ods"
|
||||
)
|
||||
self.data = r.read_all()
|
||||
for key in self.data.keys():
|
||||
self.data[key] = list(self.data[key])
|
||||
|
@ -17,16 +18,15 @@ class TestODSReader(ODSCellTypes):
|
|||
|
||||
class TestODSWriter(ODSCellTypes):
|
||||
def setUp(self):
|
||||
r = ODSBook()
|
||||
r.open(os.path.join("tests", "fixtures", "ods_formats.ods"))
|
||||
r = ODSBook(
|
||||
os.path.join("tests", "fixtures", "ods_formats.ods"), "ods"
|
||||
)
|
||||
self.data1 = r.read_all()
|
||||
self.testfile = "odswriter.ods"
|
||||
w = ODSWriter()
|
||||
w.open(self.testfile)
|
||||
w = ODSWriter(self.testfile, "ods")
|
||||
w.write(self.data1)
|
||||
w.close()
|
||||
r2 = ODSBook()
|
||||
r2.open(self.testfile)
|
||||
r2 = ODSBook(self.testfile, "ods")
|
||||
self.data = r2.read_all()
|
||||
for key in self.data.keys():
|
||||
self.data[key] = list(self.data[key])
|
||||
|
|
|
@ -13,12 +13,10 @@ class TestNativeODSWriter:
|
|||
"Sheet3": [[u"X", u"Y", u"Z"], [1, 4, 7], [2, 5, 8], [3, 6, 9]],
|
||||
}
|
||||
self.testfile = "writer.ods"
|
||||
writer = Writer()
|
||||
writer.open(self.testfile)
|
||||
writer = Writer(self.testfile, "ods")
|
||||
writer.write(self.content)
|
||||
writer.close()
|
||||
reader = Reader()
|
||||
reader.open(self.testfile)
|
||||
reader = Reader(self.testfile, "ods")
|
||||
content = reader.read_all()
|
||||
for key in content.keys():
|
||||
content[key] = list(content[key])
|
||||
|
|
Loading…
Reference in New Issue