summaryrefslogtreecommitdiff
path: root/tablib/packages
diff options
context:
space:
mode:
authorKenneth Reitz <me@kennethreitz.com>2011-05-13 00:28:50 -0400
committerKenneth Reitz <me@kennethreitz.com>2011-05-13 00:28:50 -0400
commita60e2f132e67ebdfab6a4220953c8b15d6e97378 (patch)
tree634a31452eda5bf6f0af16967be76e2cc29aec80 /tablib/packages
parent2b36d71554b50e4123bc2a6eb5065689b8860272 (diff)
downloadtablib-a60e2f132e67ebdfab6a4220953c8b15d6e97378.tar.gz
Finally! :sparkles:Python 3:sparkles: port of openpyxl
Diffstat (limited to 'tablib/packages')
-rw-r--r--tablib/packages/openpyxl3/cell.py4
-rw-r--r--tablib/packages/openpyxl3/chart.py680
-rw-r--r--tablib/packages/openpyxl3/drawing.py804
-rw-r--r--tablib/packages/openpyxl3/reader/__init__.py10
-rw-r--r--tablib/packages/openpyxl3/reader/excel.py14
-rw-r--r--tablib/packages/openpyxl3/reader/iter_worksheet.py686
-rw-r--r--tablib/packages/openpyxl3/reader/worksheet.py13
-rw-r--r--tablib/packages/openpyxl3/shared/__init__.py12
-rw-r--r--tablib/packages/openpyxl3/shared/date_time.py4
-rw-r--r--tablib/packages/openpyxl3/style.py2
-rw-r--r--tablib/packages/openpyxl3/tests/helper.py4
-rw-r--r--tablib/packages/openpyxl3/tests/test_cell.py2
-rw-r--r--tablib/packages/openpyxl3/tests/test_chart.py262
-rw-r--r--tablib/packages/openpyxl3/tests/test_iter.py224
-rw-r--r--tablib/packages/openpyxl3/tests/test_meta.py2
-rw-r--r--tablib/packages/openpyxl3/tests/test_named_range.py2
-rw-r--r--tablib/packages/openpyxl3/tests/test_number_format.py6
-rw-r--r--tablib/packages/openpyxl3/tests/test_props.pybin9060 -> 4494 bytes
-rw-r--r--tablib/packages/openpyxl3/tests/test_read.py2
-rw-r--r--tablib/packages/openpyxl3/tests/test_strings.py2
-rw-r--r--tablib/packages/openpyxl3/tests/test_style.py2
-rw-r--r--tablib/packages/openpyxl3/tests/test_write.py4
-rw-r--r--tablib/packages/openpyxl3/worksheet.py8
-rw-r--r--tablib/packages/openpyxl3/writer/charts.py523
-rw-r--r--tablib/packages/openpyxl3/writer/dump_worksheet.py8
-rw-r--r--tablib/packages/openpyxl3/writer/excel.py16
-rw-r--r--tablib/packages/openpyxl3/writer/strings.py4
-rw-r--r--tablib/packages/openpyxl3/writer/styles.py6
-rw-r--r--tablib/packages/openpyxl3/writer/worksheet.py2
29 files changed, 1657 insertions, 1651 deletions
diff --git a/tablib/packages/openpyxl3/cell.py b/tablib/packages/openpyxl3/cell.py
index 300f0ed..1171fde 100644
--- a/tablib/packages/openpyxl3/cell.py
+++ b/tablib/packages/openpyxl3/cell.py
@@ -335,7 +335,7 @@ class Cell(object):
@property
def style(self):
- """Returns the :class:`openpyxl.style.Style` object for this cell"""
+ """Returns the :class:`.style.Style` object for this cell"""
return self.parent.get_style(self.get_coordinate())
@property
@@ -367,7 +367,7 @@ class Cell(object):
:param column: number of columns to offset
:type column: int
- :rtype: :class:`openpyxl.cell.Cell`
+ :rtype: :class:`.cell.Cell`
"""
offset_column = get_column_letter(column_index_from_string(
column = self.column) + column)
diff --git a/tablib/packages/openpyxl3/chart.py b/tablib/packages/openpyxl3/chart.py
index 19ba3b9..265ccaf 100644
--- a/tablib/packages/openpyxl3/chart.py
+++ b/tablib/packages/openpyxl3/chart.py
@@ -1,340 +1,340 @@
-'''
-Copyright (c) 2010 openpyxl
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-@license: http://www.opensource.org/licenses/mit-license.php
-@author: Eric Gazoni
-'''
-
-import math
-
-from .style import NumberFormat
-from .drawing import Drawing, Shape
-from .shared.units import pixels_to_EMU, short_color
-from .cell import get_column_letter
-
-class Axis(object):
-
- POSITION_BOTTOM = 'b'
- POSITION_LEFT = 'l'
-
- ORIENTATION_MIN_MAX = "minMax"
-
- def __init__(self):
-
- self.orientation = self.ORIENTATION_MIN_MAX
- self.number_format = NumberFormat()
- for attr in ('position','tick_label_position','crosses',
- 'auto','label_align','label_offset','cross_between'):
- setattr(self, attr, None)
- self.min = 0
- self.max = None
- self.unit = None
-
- @classmethod
- def default_category(cls):
- """ default values for category axes """
-
- ax = Axis()
- ax.id = 60871424
- ax.cross = 60873344
- ax.position = Axis.POSITION_BOTTOM
- ax.tick_label_position = 'nextTo'
- ax.crosses = "autoZero"
- ax.auto = True
- ax.label_align = 'ctr'
- ax.label_offset = 100
- return ax
-
- @classmethod
- def default_value(cls):
- """ default values for value axes """
-
- ax = Axis()
- ax.id = 60873344
- ax.cross = 60871424
- ax.position = Axis.POSITION_LEFT
- ax.major_gridlines = None
- ax.tick_label_position = 'nextTo'
- ax.crosses = 'autoZero'
- ax.auto = False
- ax.cross_between = 'between'
- return ax
-
-class Reference(object):
- """ a simple wrapper around a serie of reference data """
-
- def __init__(self, sheet, pos1, pos2=None):
-
- self.sheet = sheet
- self.pos1 = pos1
- self.pos2 = pos2
-
- def get_type(self):
-
- if isinstance(self.cache[0], str):
- return 'str'
- else:
- return 'num'
-
- def _get_ref(self):
- """ format excel reference notation """
-
- if self.pos2:
- return '%s!$%s$%s:$%s$%s' % (self.sheet.title,
- get_column_letter(self.pos1[1]+1), self.pos1[0]+1,
- get_column_letter(self.pos2[1]+1), self.pos2[0]+1)
- else:
- return '%s!$%s$%s' % (self.sheet.title,
- get_column_letter(self.pos1[1]+1), self.pos1[0]+1)
-
-
- def _get_cache(self):
- """ read data in sheet - to be used at writing time """
-
- cache = []
- if self.pos2:
- for row in range(self.pos1[0], self.pos2[0]+1):
- for col in range(self.pos1[1], self.pos2[1]+1):
- cache.append(self.sheet.cell(row=row, column=col).value)
- else:
- cell = self.sheet.cell(row=self.pos1[0], column=self.pos1[1])
- cache.append(cell.value)
- return cache
-
-
-class Serie(object):
- """ a serie of data and possibly associated labels """
-
- MARKER_NONE = 'none'
-
- def __init__(self, values, labels=None, legend=None, color=None, xvalues=None):
-
- self.marker = Serie.MARKER_NONE
- self.values = values
- self.xvalues = xvalues
- self.labels = labels
- self.legend = legend
- self.error_bar = None
- self._color = color
-
- def _get_color(self):
- return self._color
-
- def _set_color(self, color):
- self._color = short_color(color)
-
- color = property(_get_color, _set_color)
-
- def get_min_max(self):
-
- if self.error_bar:
- err_cache = self.error_bar.values._get_cache()
- vals = [v + err_cache[i] \
- for i,v in enumerate(self.values._get_cache())]
- else:
- vals = self.values._get_cache()
- return min(vals), max(vals)
-
- def __len__(self):
-
- return len(self.values.cache)
-
-class Legend(object):
-
- def __init__(self):
-
- self.position = 'r'
- self.layout = None
-
-class ErrorBar(object):
-
- PLUS = 1
- MINUS = 2
- PLUS_MINUS = 3
-
- def __init__(self, _type, values):
-
- self.type = _type
- self.values = values
-
-class Chart(object):
- """ raw chart class """
-
- GROUPING_CLUSTERED = 'clustered'
- GROUPING_STANDARD = 'standard'
-
- BAR_CHART = 1
- LINE_CHART = 2
- SCATTER_CHART = 3
-
- def __init__(self, _type, grouping):
-
- self._series = []
-
- # public api
- self.type = _type
- self.grouping = grouping
- self.x_axis = Axis.default_category()
- self.y_axis = Axis.default_value()
- self.legend = Legend()
- self.lang = 'fr-FR'
- self.title = ''
- self.print_margins = dict(b=.75, l=.7, r=.7, t=.75, header=0.3, footer=.3)
-
- # the containing drawing
- self.drawing = Drawing()
-
- # the offset for the plot part in percentage of the drawing size
- self.width = .6
- self.height = .6
- self.margin_top = self._get_max_margin_top()
- self.margin_left = 0
-
- # the user defined shapes
- self._shapes = []
-
- def add_serie(self, serie):
-
- serie.id = len(self._series)
- self._series.append(serie)
- self._compute_min_max()
- if not None in [s.xvalues for s in self._series]:
- self._compute_xmin_xmax()
-
- def add_shape(self, shape):
-
- shape._chart = self
- self._shapes.append(shape)
-
- def get_x_units(self):
- """ calculate one unit for x axis in EMU """
-
- return max([len(s.values._get_cache()) for s in self._series])
-
- def get_y_units(self):
- """ calculate one unit for y axis in EMU """
-
- dh = pixels_to_EMU(self.drawing.height)
- return (dh * self.height) / self.y_axis.max
-
- def get_y_chars(self):
- """ estimate nb of chars for y axis """
-
- _max = max([max([x for x in s.values._get_cache() if x is not None]) for s in self._series])
- return len(str(int(_max)))
-
- def _compute_min_max(self):
- """ compute y axis limits and units """
-
- maxi = max([max([x for x in s.values._get_cache() if x is not None]) for s in self._series])
-
- mul = None
- if maxi < 1:
- s = str(maxi).split('.')[1]
- mul = 10
- for x in s:
- if x == '0':
- mul *= 10
- else:
- break
- maxi = maxi * mul
-
- maxi = math.ceil(maxi * 1.1)
- sz = len(str(int(maxi))) - 1
- unit = math.ceil(math.ceil(maxi / pow(10, sz)) * pow(10, sz-1))
- maxi = math.ceil(maxi/unit) * unit
-
- if mul is not None:
- maxi = maxi/mul
- unit = unit/mul
-
- if maxi / unit > 9:
- # no more that 10 ticks
- unit *= 2
-
- self.y_axis.max = maxi
- self.y_axis.unit = unit
-
- def _compute_xmin_xmax(self):
- """ compute x axis limits and units """
-
- maxi = max([max([x for x in s.xvalues._get_cache() if x is not None]) for s in self._series])
-
- mul = None
- if maxi < 1:
- s = str(maxi).split('.')[1]
- mul = 10
- for x in s:
- if x == '0':
- mul *= 10
- else:
- break
- maxi = maxi * mul
-
- maxi = math.ceil(maxi * 1.1)
- sz = len(str(int(maxi))) - 1
- unit = math.ceil(math.ceil(maxi / pow(10, sz)) * pow(10, sz-1))
- maxi = math.ceil(maxi/unit) * unit
-
- if mul is not None:
- maxi = maxi/mul
- unit = unit/mul
-
- if maxi / unit > 9:
- # no more that 10 ticks
- unit *= 2
-
- self.x_axis.max = maxi
- self.x_axis.unit = unit
-
- def _get_max_margin_top(self):
-
- mb = Shape.FONT_HEIGHT + Shape.MARGIN_BOTTOM
- plot_height = self.drawing.height * self.height
- return float(self.drawing.height - plot_height - mb)/self.drawing.height
-
- def _get_min_margin_left(self):
-
- ml = (self.get_y_chars() * Shape.FONT_WIDTH) + Shape.MARGIN_LEFT
- return float(ml)/self.drawing.width
-
- def _get_margin_top(self):
- """ get margin in percent """
-
- return min(self.margin_top, self._get_max_margin_top())
-
- def _get_margin_left(self):
-
- return max(self._get_min_margin_left(), self.margin_left)
-
-class BarChart(Chart):
- def __init__(self):
- super(BarChart, self).__init__(Chart.BAR_CHART, Chart.GROUPING_CLUSTERED)
-
-class LineChart(Chart):
- def __init__(self):
- super(LineChart, self).__init__(Chart.LINE_CHART, Chart.GROUPING_STANDARD)
-
-class ScatterChart(Chart):
- def __init__(self):
- super(ScatterChart, self).__init__(Chart.SCATTER_CHART, Chart.GROUPING_STANDARD)
-
-
+'''
+Copyright (c) 2010 openpyxl
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+@license: http://www.opensource.org/licenses/mit-license.php
+@author: Eric Gazoni
+'''
+
+import math
+
+from .style import NumberFormat
+from .drawing import Drawing, Shape
+from .shared.units import pixels_to_EMU, short_color
+from .cell import get_column_letter
+
+class Axis(object):
+
+ POSITION_BOTTOM = 'b'
+ POSITION_LEFT = 'l'
+
+ ORIENTATION_MIN_MAX = "minMax"
+
+ def __init__(self):
+
+ self.orientation = self.ORIENTATION_MIN_MAX
+ self.number_format = NumberFormat()
+ for attr in ('position','tick_label_position','crosses',
+ 'auto','label_align','label_offset','cross_between'):
+ setattr(self, attr, None)
+ self.min = 0
+ self.max = None
+ self.unit = None
+
+ @classmethod
+ def default_category(cls):
+ """ default values for category axes """
+
+ ax = Axis()
+ ax.id = 60871424
+ ax.cross = 60873344
+ ax.position = Axis.POSITION_BOTTOM
+ ax.tick_label_position = 'nextTo'
+ ax.crosses = "autoZero"
+ ax.auto = True
+ ax.label_align = 'ctr'
+ ax.label_offset = 100
+ return ax
+
+ @classmethod
+ def default_value(cls):
+ """ default values for value axes """
+
+ ax = Axis()
+ ax.id = 60873344
+ ax.cross = 60871424
+ ax.position = Axis.POSITION_LEFT
+ ax.major_gridlines = None
+ ax.tick_label_position = 'nextTo'
+ ax.crosses = 'autoZero'
+ ax.auto = False
+ ax.cross_between = 'between'
+ return ax
+
+class Reference(object):
+ """ a simple wrapper around a serie of reference data """
+
+ def __init__(self, sheet, pos1, pos2=None):
+
+ self.sheet = sheet
+ self.pos1 = pos1
+ self.pos2 = pos2
+
+ def get_type(self):
+
+ if isinstance(self.cache[0], str):
+ return 'str'
+ else:
+ return 'num'
+
+ def _get_ref(self):
+ """ format excel reference notation """
+
+ if self.pos2:
+ return '%s!$%s$%s:$%s$%s' % (self.sheet.title,
+ get_column_letter(self.pos1[1]+1), self.pos1[0]+1,
+ get_column_letter(self.pos2[1]+1), self.pos2[0]+1)
+ else:
+ return '%s!$%s$%s' % (self.sheet.title,
+ get_column_letter(self.pos1[1]+1), self.pos1[0]+1)
+
+
+ def _get_cache(self):
+ """ read data in sheet - to be used at writing time """
+
+ cache = []
+ if self.pos2:
+ for row in range(self.pos1[0], self.pos2[0]+1):
+ for col in range(self.pos1[1], self.pos2[1]+1):
+ cache.append(self.sheet.cell(row=row, column=col).value)
+ else:
+ cell = self.sheet.cell(row=self.pos1[0], column=self.pos1[1])
+ cache.append(cell.value)
+ return cache
+
+
+class Serie(object):
+ """ a serie of data and possibly associated labels """
+
+ MARKER_NONE = 'none'
+
+ def __init__(self, values, labels=None, legend=None, color=None, xvalues=None):
+
+ self.marker = Serie.MARKER_NONE
+ self.values = values
+ self.xvalues = xvalues
+ self.labels = labels
+ self.legend = legend
+ self.error_bar = None
+ self._color = color
+
+ def _get_color(self):
+ return self._color
+
+ def _set_color(self, color):
+ self._color = short_color(color)
+
+ color = property(_get_color, _set_color)
+
+ def get_min_max(self):
+
+ if self.error_bar:
+ err_cache = self.error_bar.values._get_cache()
+ vals = [v + err_cache[i] \
+ for i,v in enumerate(self.values._get_cache())]
+ else:
+ vals = self.values._get_cache()
+ return min(vals), max(vals)
+
+ def __len__(self):
+
+ return len(self.values.cache)
+
+class Legend(object):
+
+ def __init__(self):
+
+ self.position = 'r'
+ self.layout = None
+
+class ErrorBar(object):
+
+ PLUS = 1
+ MINUS = 2
+ PLUS_MINUS = 3
+
+ def __init__(self, _type, values):
+
+ self.type = _type
+ self.values = values
+
+class Chart(object):
+ """ raw chart class """
+
+ GROUPING_CLUSTERED = 'clustered'
+ GROUPING_STANDARD = 'standard'
+
+ BAR_CHART = 1
+ LINE_CHART = 2
+ SCATTER_CHART = 3
+
+ def __init__(self, _type, grouping):
+
+ self._series = []
+
+ # public api
+ self.type = _type
+ self.grouping = grouping
+ self.x_axis = Axis.default_category()
+ self.y_axis = Axis.default_value()
+ self.legend = Legend()
+ self.lang = 'fr-FR'
+ self.title = ''
+ self.print_margins = dict(b=.75, l=.7, r=.7, t=.75, header=0.3, footer=.3)
+
+ # the containing drawing
+ self.drawing = Drawing()
+
+ # the offset for the plot part in percentage of the drawing size
+ self.width = .6
+ self.height = .6
+ self.margin_top = self._get_max_margin_top()
+ self.margin_left = 0
+
+ # the user defined shapes
+ self._shapes = []
+
+ def add_serie(self, serie):
+
+ serie.id = len(self._series)
+ self._series.append(serie)
+ self._compute_min_max()
+ if not None in [s.xvalues for s in self._series]:
+ self._compute_xmin_xmax()
+
+ def add_shape(self, shape):
+
+ shape._chart = self
+ self._shapes.append(shape)
+
+ def get_x_units(self):
+ """ calculate one unit for x axis in EMU """
+
+ return max([len(s.values._get_cache()) for s in self._series])
+
+ def get_y_units(self):
+ """ calculate one unit for y axis in EMU """
+
+ dh = pixels_to_EMU(self.drawing.height)
+ return (dh * self.height) / self.y_axis.max
+
+ def get_y_chars(self):
+ """ estimate nb of chars for y axis """
+
+ _max = max([max(s.values._get_cache()) for s in self._series])
+ return len(str(int(_max)))
+
+ def _compute_min_max(self):
+ """ compute y axis limits and units """
+
+ maxi = max([max(s.values._get_cache()) for s in self._series])
+
+ mul = None
+ if maxi < 1:
+ s = str(maxi).split('.')[1]
+ mul = 10
+ for x in s:
+ if x == '0':
+ mul *= 10
+ else:
+ break
+ maxi = maxi * mul
+
+ maxi = math.ceil(maxi * 1.1)
+ sz = len(str(int(maxi))) - 1
+ unit = math.ceil(math.ceil(maxi / pow(10, sz)) * pow(10, sz-1))
+ maxi = math.ceil(maxi/unit) * unit
+
+ if mul is not None:
+ maxi = maxi/mul
+ unit = unit/mul
+
+ if maxi / unit > 9:
+ # no more that 10 ticks
+ unit *= 2
+
+ self.y_axis.max = maxi
+ self.y_axis.unit = unit
+
+ def _compute_xmin_xmax(self):
+ """ compute x axis limits and units """
+
+ maxi = max([max(s.xvalues._get_cache()) for s in self._series])
+
+ mul = None
+ if maxi < 1:
+ s = str(maxi).split('.')[1]
+ mul = 10
+ for x in s:
+ if x == '0':
+ mul *= 10
+ else:
+ break
+ maxi = maxi * mul
+
+ maxi = math.ceil(maxi * 1.1)
+ sz = len(str(int(maxi))) - 1
+ unit = math.ceil(math.ceil(maxi / pow(10, sz)) * pow(10, sz-1))
+ maxi = math.ceil(maxi/unit) * unit
+
+ if mul is not None:
+ maxi = maxi/mul
+ unit = unit/mul
+
+ if maxi / unit > 9:
+ # no more that 10 ticks
+ unit *= 2
+
+ self.x_axis.max = maxi
+ self.x_axis.unit = unit
+
+ def _get_max_margin_top(self):
+
+ mb = Shape.FONT_HEIGHT + Shape.MARGIN_BOTTOM
+ plot_height = self.drawing.height * self.height
+ return float(self.drawing.height - plot_height - mb)/self.drawing.height
+
+ def _get_min_margin_left(self):
+
+ ml = (self.get_y_chars() * Shape.FONT_WIDTH) + Shape.MARGIN_LEFT
+ return float(ml)/self.drawing.width
+
+ def _get_margin_top(self):
+ """ get margin in percent """
+
+ return min(self.margin_top, self._get_max_margin_top())
+
+ def _get_margin_left(self):
+
+ return max(self._get_min_margin_left(), self.margin_left)
+
+class BarChart(Chart):
+ def __init__(self):
+ super(BarChart, self).__init__(Chart.BAR_CHART, Chart.GROUPING_CLUSTERED)
+
+class LineChart(Chart):
+ def __init__(self):
+ super(LineChart, self).__init__(Chart.LINE_CHART, Chart.GROUPING_STANDARD)
+
+class ScatterChart(Chart):
+ def __init__(self):
+ super(ScatterChart, self).__init__(Chart.SCATTER_CHART, Chart.GROUPING_STANDARD)
+
+
diff --git a/tablib/packages/openpyxl3/drawing.py b/tablib/packages/openpyxl3/drawing.py
index 6b3c76d..0007569 100644
--- a/tablib/packages/openpyxl3/drawing.py
+++ b/tablib/packages/openpyxl3/drawing.py
@@ -1,402 +1,402 @@
-'''
-Copyright (c) 2010 openpyxl
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-@license: http://www.opensource.org/licenses/mit-license.php
-@author: Eric Gazoni
-'''
-
-import math
-from .style import Color
-from .shared.units import pixels_to_EMU, EMU_to_pixels, short_color
-
-class Shadow(object):
-
- SHADOW_BOTTOM = 'b'
- SHADOW_BOTTOM_LEFT = 'bl'
- SHADOW_BOTTOM_RIGHT = 'br'
- SHADOW_CENTER = 'ctr'
- SHADOW_LEFT = 'l'
- SHADOW_TOP = 't'
- SHADOW_TOP_LEFT = 'tl'
- SHADOW_TOP_RIGHT = 'tr'
-
- def __init__(self):
- self.visible = False
- self.blurRadius = 6
- self.distance = 2
- self.direction = 0
- self.alignment = self.SHADOW_BOTTOM_RIGHT
- self.color = Color(Color.BLACK)
- self.alpha = 50
-
-class Drawing(object):
- """ a drawing object - eg container for shapes or charts
- we assume user specifies dimensions in pixels; units are
- converted to EMU in the drawing part
- """
-
- count = 0
-
- def __init__(self):
-
- self.name = ''
- self.description = ''
- self.coordinates = ((1,2), (16,8))
- self.left = 0
- self.top = 0
- self._width = EMU_to_pixels(200000)
- self._height = EMU_to_pixels(1828800)
- self.resize_proportional = False
- self.rotation = 0
-# self.shadow = Shadow()
-
- def _set_width(self, w):
-
- if self.resize_proportional and w:
- ratio = self._height / self._width
- self._height = round(ratio * w)
- self._width = w
-
- def _get_width(self):
-
- return self._width
-
- width = property(_get_width, _set_width)
-
- def _set_height(self, h):
-
- if self.resize_proportional and h:
- ratio = self._width / self._height
- self._width = round(ratio * h)
- self._height = h
-
- def _get_height(self):
-
- return self._height
-
- height = property(_get_height, _set_height)
-
- def set_dimension(self, w=0, h=0):
-
- xratio = w / self._width
- yratio = h / self._height
-
- if self.resize_proportional and w and h:
- if (xratio * self._height) < h:
- self._height = math.ceil(xratio * self._height)
- self._width = width
- else:
- self._width = math.ceil(yratio * self._width)
- self._height = height
-
- def get_emu_dimensions(self):
- """ return (x, y, w, h) in EMU """
-
- return (pixels_to_EMU(self.left), pixels_to_EMU(self.top),
- pixels_to_EMU(self._width), pixels_to_EMU(self._height))
-
-
-class Shape(object):
- """ a drawing inside a chart
- coordiantes are specified by the user in the axis units
- """
-
- MARGIN_LEFT = 6 + 13 + 1
- MARGIN_BOTTOM = 17 + 11
-
- FONT_WIDTH = 7
- FONT_HEIGHT = 8
-
- ROUND_RECT = 'roundRect'
- RECT = 'rect'
-
- # other shapes to define :
- '''
- "line"
- "lineInv"
- "triangle"
- "rtTriangle"
- "diamond"
- "parallelogram"
- "trapezoid"
- "nonIsoscelesTrapezoid"
- "pentagon"
- "hexagon"
- "heptagon"
- "octagon"
- "decagon"
- "dodecagon"
- "star4"
- "star5"
- "star6"
- "star7"
- "star8"
- "star10"
- "star12"
- "star16"
- "star24"
- "star32"
- "roundRect"
- "round1Rect"
- "round2SameRect"
- "round2DiagRect"
- "snipRoundRect"
- "snip1Rect"
- "snip2SameRect"
- "snip2DiagRect"
- "plaque"
- "ellipse"
- "teardrop"
- "homePlate"
- "chevron"
- "pieWedge"
- "pie"
- "blockArc"
- "donut"
- "noSmoking"
- "rightArrow"
- "leftArrow"
- "upArrow"
- "downArrow"
- "stripedRightArrow"
- "notchedRightArrow"
- "bentUpArrow"
- "leftRightArrow"
- "upDownArrow"
- "leftUpArrow"
- "leftRightUpArrow"
- "quadArrow"
- "leftArrowCallout"
- "rightArrowCallout"
- "upArrowCallout"
- "downArrowCallout"
- "leftRightArrowCallout"
- "upDownArrowCallout"
- "quadArrowCallout"
- "bentArrow"
- "uturnArrow"
- "circularArrow"
- "leftCircularArrow"
- "leftRightCircularArrow"
- "curvedRightArrow"
- "curvedLeftArrow"
- "curvedUpArrow"
- "curvedDownArrow"
- "swooshArrow"
- "cube"
- "can"
- "lightningBolt"
- "heart"
- "sun"
- "moon"
- "smileyFace"
- "irregularSeal1"
- "irregularSeal2"
- "foldedCorner"
- "bevel"
- "frame"
- "halfFrame"
- "corner"
- "diagStripe"
- "chord"
- "arc"
- "leftBracket"
- "rightBracket"
- "leftBrace"
- "rightBrace"
- "bracketPair"
- "bracePair"
- "straightConnector1"
- "bentConnector2"
- "bentConnector3"
- "bentConnector4"
- "bentConnector5"
- "curvedConnector2"
- "curvedConnector3"
- "curvedConnector4"
- "curvedConnector5"
- "callout1"
- "callout2"
- "callout3"
- "accentCallout1"
- "accentCallout2"
- "accentCallout3"
- "borderCallout1"
- "borderCallout2"
- "borderCallout3"
- "accentBorderCallout1"
- "accentBorderCallout2"
- "accentBorderCallout3"
- "wedgeRectCallout"
- "wedgeRoundRectCallout"
- "wedgeEllipseCallout"
- "cloudCallout"
- "cloud"
- "ribbon"
- "ribbon2"
- "ellipseRibbon"
- "ellipseRibbon2"
- "leftRightRibbon"
- "verticalScroll"
- "horizontalScroll"
- "wave"
- "doubleWave"
- "plus"
- "flowChartProcess"
- "flowChartDecision"
- "flowChartInputOutput"
- "flowChartPredefinedProcess"
- "flowChartInternalStorage"
- "flowChartDocument"
- "flowChartMultidocument"
- "flowChartTerminator"
- "flowChartPreparation"
- "flowChartManualInput"
- "flowChartManualOperation"
- "flowChartConnector"
- "flowChartPunchedCard"
- "flowChartPunchedTape"
- "flowChartSummingJunction"
- "flowChartOr"
- "flowChartCollate"
- "flowChartSort"
- "flowChartExtract"
- "flowChartMerge"
- "flowChartOfflineStorage"
- "flowChartOnlineStorage"
- "flowChartMagneticTape"
- "flowChartMagneticDisk"
- "flowChartMagneticDrum"
- "flowChartDisplay"
- "flowChartDelay"
- "flowChartAlternateProcess"
- "flowChartOffpageConnector"
- "actionButtonBlank"
- "actionButtonHome"
- "actionButtonHelp"
- "actionButtonInformation"
- "actionButtonForwardNext"
- "actionButtonBackPrevious"
- "actionButtonEnd"
- "actionButtonBeginning"
- "actionButtonReturn"
- "actionButtonDocument"
- "actionButtonSound"
- "actionButtonMovie"
- "gear6"
- "gear9"
- "funnel"
- "mathPlus"
- "mathMinus"
- "mathMultiply"
- "mathDivide"
- "mathEqual"
- "mathNotEqual"
- "cornerTabs"
- "squareTabs"
- "plaqueTabs"
- "chartX"
- "chartStar"
- "chartPlus"
- '''
-
- def __init__(self, coordinates=((0,0), (1,1)), text=None, scheme="accent1"):
-
- self.coordinates = coordinates # in axis unit
- self.text = text
- self.scheme = scheme
- self.style = Shape.RECT
- self._border_width = 3175 # in EMU
- self._border_color = Color.BLACK[2:] #"F3B3C5"
- self._color = Color.WHITE[2:]
- self._text_color = Color.BLACK[2:]
-
- def _get_border_color(self):
- return self._border_color
-
- def _set_border_color(self, color):
- self._border_color = short_color(color)
-
- border_color = property(_get_border_color, _set_border_color)
-
- def _get_color(self):
- return self._color
-
- def _set_color(self, color):
- self._color = short_color(color)
-
- color = property(_get_color, _set_color)
-
- def _get_text_color(self):
- return self._text_color
-
- def _set_text_color(self, color):
- self._text_color = short_color(color)
-
- text_color = property(_get_text_color, _set_text_color)
-
- def _get_border_width(self):
-
- return EMU_to_pixels(self._border_width)
-
- def _set_border_width(self, w):
-
- self._border_width = pixels_to_EMU(w)
- print(self._border_width)
-
- border_width = property(_get_border_width, _set_border_width)
-
- def get_coordinates(self):
- """ return shape coordinates in percentages (left, top, right, bottom) """
-
- (x1, y1), (x2, y2) = self.coordinates
-
- drawing_width = pixels_to_EMU(self._chart.drawing.width)
- drawing_height = pixels_to_EMU(self._chart.drawing.height)
- plot_width = drawing_width * self._chart.width
- plot_height = drawing_height * self._chart.height
-
- margin_left = self._chart._get_margin_left() * drawing_width
- xunit = plot_width / self._chart.get_x_units()
-
- margin_top = self._chart._get_margin_top() * drawing_height
- yunit = self._chart.get_y_units()
-
- x_start = (margin_left + (float(x1) * xunit)) / drawing_width
- y_start = (margin_top + plot_height - (float(y1) * yunit)) / drawing_height
-
- x_end = (margin_left + (float(x2) * xunit)) / drawing_width
- y_end = (margin_top + plot_height - (float(y2) * yunit)) / drawing_height
-
- def _norm_pct(pct):
- """ force shapes to appear by truncating too large sizes """
- if pct>1: pct = 1
- elif pct<0: pct = 0
- return pct
-
- # allow user to specify y's in whatever order
- # excel expect y_end to be lower
- if y_end < y_start:
- y_end, y_start = y_start, y_end
-
- return (_norm_pct(x_start), _norm_pct(y_start),
- _norm_pct(x_end), _norm_pct(y_end))
-
+'''
+Copyright (c) 2010 openpyxl
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+@license: http://www.opensource.org/licenses/mit-license.php
+@author: Eric Gazoni
+'''
+
+import math
+from .style import Color
+from .shared.units import pixels_to_EMU, EMU_to_pixels, short_color
+
+class Shadow(object):
+
+ SHADOW_BOTTOM = 'b'
+ SHADOW_BOTTOM_LEFT = 'bl'
+ SHADOW_BOTTOM_RIGHT = 'br'
+ SHADOW_CENTER = 'ctr'
+ SHADOW_LEFT = 'l'
+ SHADOW_TOP = 't'
+ SHADOW_TOP_LEFT = 'tl'
+ SHADOW_TOP_RIGHT = 'tr'
+
+ def __init__(self):
+ self.visible = False
+ self.blurRadius = 6
+ self.distance = 2
+ self.direction = 0
+ self.alignment = self.SHADOW_BOTTOM_RIGHT
+ self.color = Color(Color.BLACK)
+ self.alpha = 50
+
+class Drawing(object):
+ """ a drawing object - eg container for shapes or charts
+ we assume user specifies dimensions in pixels; units are
+ converted to EMU in the drawing part
+ """
+
+ count = 0
+
+ def __init__(self):
+
+ self.name = ''
+ self.description = ''
+ self.coordinates = ((1,2), (16,8))
+ self.left = 0
+ self.top = 0
+ self._width = EMU_to_pixels(200000)
+ self._height = EMU_to_pixels(1828800)
+ self.resize_proportional = False
+ self.rotation = 0
+# self.shadow = Shadow()
+
+ def _set_width(self, w):
+
+ if self.resize_proportional and w:
+ ratio = self._height / self._width
+ self._height = round(ratio * w)
+ self._width = w
+
+ def _get_width(self):
+
+ return self._width
+
+ width = property(_get_width, _set_width)
+
+ def _set_height(self, h):
+
+ if self.resize_proportional and h:
+ ratio = self._width / self._height
+ self._width = round(ratio * h)
+ self._height = h
+
+ def _get_height(self):
+
+ return self._height
+
+ height = property(_get_height, _set_height)
+
+ def set_dimension(self, w=0, h=0):
+
+ xratio = w / self._width
+ yratio = h / self._height
+
+ if self.resize_proportional and w and h:
+ if (xratio * self._height) < h:
+ self._height = math.ceil(xratio * self._height)
+ self._width = width
+ else:
+ self._width = math.ceil(yratio * self._width)
+ self._height = height
+
+ def get_emu_dimensions(self):
+ """ return (x, y, w, h) in EMU """
+
+ return (pixels_to_EMU(self.left), pixels_to_EMU(self.top),
+ pixels_to_EMU(self._width), pixels_to_EMU(self._height))
+
+
+class Shape(object):
+ """ a drawing inside a chart
+ coordiantes are specified by the user in the axis units
+ """
+
+ MARGIN_LEFT = 6 + 13 + 1
+ MARGIN_BOTTOM = 17 + 11
+
+ FONT_WIDTH = 7
+ FONT_HEIGHT = 8
+
+ ROUND_RECT = 'roundRect'
+ RECT = 'rect'
+
+ # other shapes to define :
+ '''
+ "line"
+ "lineInv"
+ "triangle"
+ "rtTriangle"
+ "diamond"
+ "parallelogram"
+ "trapezoid"
+ "nonIsoscelesTrapezoid"
+ "pentagon"
+ "hexagon"
+ "heptagon"
+ "octagon"
+ "decagon"
+ "dodecagon"
+ "star4"
+ "star5"
+ "star6"
+ "star7"
+ "star8"
+ "star10"
+ "star12"
+ "star16"
+ "star24"
+ "star32"
+ "roundRect"
+ "round1Rect"
+ "round2SameRect"
+ "round2DiagRect"
+ "snipRoundRect"
+ "snip1Rect"
+ "snip2SameRect"
+ "snip2DiagRect"
+ "plaque"
+ "ellipse"
+ "teardrop"
+ "homePlate"
+ "chevron"
+ "pieWedge"
+ "pie"
+ "blockArc"
+ "donut"
+ "noSmoking"
+ "rightArrow"
+ "leftArrow"
+ "upArrow"
+ "downArrow"
+ "stripedRightArrow"
+ "notchedRightArrow"
+ "bentUpArrow"
+ "leftRightArrow"
+ "upDownArrow"
+ "leftUpArrow"
+ "leftRightUpArrow"
+ "quadArrow"
+ "leftArrowCallout"
+ "rightArrowCallout"
+ "upArrowCallout"
+ "downArrowCallout"
+ "leftRightArrowCallout"
+ "upDownArrowCallout"
+ "quadArrowCallout"
+ "bentArrow"
+ "uturnArrow"
+ "circularArrow"
+ "leftCircularArrow"
+ "leftRightCircularArrow"
+ "curvedRightArrow"
+ "curvedLeftArrow"
+ "curvedUpArrow"
+ "curvedDownArrow"
+ "swooshArrow"
+ "cube"
+ "can"
+ "lightningBolt"
+ "heart"
+ "sun"
+ "moon"
+ "smileyFace"
+ "irregularSeal1"
+ "irregularSeal2"
+ "foldedCorner"
+ "bevel"
+ "frame"
+ "halfFrame"
+ "corner"
+ "diagStripe"
+ "chord"
+ "arc"
+ "leftBracket"
+ "rightBracket"
+ "leftBrace"
+ "rightBrace"
+ "bracketPair"
+ "bracePair"
+ "straightConnector1"
+ "bentConnector2"
+ "bentConnector3"
+ "bentConnector4"
+ "bentConnector5"
+ "curvedConnector2"
+ "curvedConnector3"
+ "curvedConnector4"
+ "curvedConnector5"
+ "callout1"
+ "callout2"
+ "callout3"
+ "accentCallout1"
+ "accentCallout2"
+ "accentCallout3"
+ "borderCallout1"
+ "borderCallout2"
+ "borderCallout3"
+ "accentBorderCallout1"
+ "accentBorderCallout2"
+ "accentBorderCallout3"
+ "wedgeRectCallout"
+ "wedgeRoundRectCallout"
+ "wedgeEllipseCallout"
+ "cloudCallout"
+ "cloud"
+ "ribbon"
+ "ribbon2"
+ "ellipseRibbon"
+ "ellipseRibbon2"
+ "leftRightRibbon"
+ "verticalScroll"
+ "horizontalScroll"
+ "wave"
+ "doubleWave"
+ "plus"
+ "flowChartProcess"
+ "flowChartDecision"
+ "flowChartInputOutput"
+ "flowChartPredefinedProcess"
+ "flowChartInternalStorage"
+ "flowChartDocument"
+ "flowChartMultidocument"
+ "flowChartTerminator"
+ "flowChartPreparation"
+ "flowChartManualInput"
+ "flowChartManualOperation"
+ "flowChartConnector"
+ "flowChartPunchedCard"
+ "flowChartPunchedTape"
+ "flowChartSummingJunction"
+ "flowChartOr"
+ "flowChartCollate"
+ "flowChartSort"
+ "flowChartExtract"
+ "flowChartMerge"
+ "flowChartOfflineStorage"
+ "flowChartOnlineStorage"
+ "flowChartMagneticTape"
+ "flowChartMagneticDisk"
+ "flowChartMagneticDrum"
+ "flowChartDisplay"
+ "flowChartDelay"
+ "flowChartAlternateProcess"
+ "flowChartOffpageConnector"
+ "actionButtonBlank"
+ "actionButtonHome"
+ "actionButtonHelp"
+ "actionButtonInformation"
+ "actionButtonForwardNext"
+ "actionButtonBackPrevious"
+ "actionButtonEnd"
+ "actionButtonBeginning"
+ "actionButtonReturn"
+ "actionButtonDocument"
+ "actionButtonSound"
+ "actionButtonMovie"
+ "gear6"
+ "gear9"
+ "funnel"
+ "mathPlus"
+ "mathMinus"
+ "mathMultiply"
+ "mathDivide"
+ "mathEqual"
+ "mathNotEqual"
+ "cornerTabs"
+ "squareTabs"
+ "plaqueTabs"
+ "chartX"
+ "chartStar"
+ "chartPlus"
+ '''
+
+ def __init__(self, coordinates=((0,0), (1,1)), text=None, scheme="accent1"):
+
+ self.coordinates = coordinates # in axis unit
+ self.text = text
+ self.scheme = scheme
+ self.style = Shape.RECT
+ self._border_width = 3175 # in EMU
+ self._border_color = Color.BLACK[2:] #"F3B3C5"
+ self._color = Color.WHITE[2:]
+ self._text_color = Color.BLACK[2:]
+
+ def _get_border_color(self):
+ return self._border_color
+
+ def _set_border_color(self, color):
+ self._border_color = short_color(color)
+
+ border_color = property(_get_border_color, _set_border_color)
+
+ def _get_color(self):
+ return self._color
+
+ def _set_color(self, color):
+ self._color = short_color(color)
+
+ color = property(_get_color, _set_color)
+
+ def _get_text_color(self):
+ return self._text_color
+
+ def _set_text_color(self, color):
+ self._text_color = short_color(color)
+
+ text_color = property(_get_text_color, _set_text_color)
+
+ def _get_border_width(self):
+
+ return EMU_to_pixels(self._border_width)
+
+ def _set_border_width(self, w):
+
+ self._border_width = pixels_to_EMU(w)
+ print(self._border_width)
+
+ border_width = property(_get_border_width, _set_border_width)
+
+ def get_coordinates(self):
+ """ return shape coordinates in percentages (left, top, right, bottom) """
+
+ (x1, y1), (x2, y2) = self.coordinates
+
+ drawing_width = pixels_to_EMU(self._chart.drawing.width)
+ drawing_height = pixels_to_EMU(self._chart.drawing.height)
+ plot_width = drawing_width * self._chart.width
+ plot_height = drawing_height * self._chart.height
+
+ margin_left = self._chart._get_margin_left() * drawing_width
+ xunit = plot_width / self._chart.get_x_units()
+
+ margin_top = self._chart._get_margin_top() * drawing_height
+ yunit = self._chart.get_y_units()
+
+ x_start = (margin_left + (float(x1) * xunit)) / drawing_width
+ y_start = (margin_top + plot_height - (float(y1) * yunit)) / drawing_height
+
+ x_end = (margin_left + (float(x2) * xunit)) / drawing_width
+ y_end = (margin_top + plot_height - (float(y2) * yunit)) / drawing_height
+
+ def _norm_pct(pct):
+ """ force shapes to appear by truncating too large sizes """
+ if pct>1: pct = 1
+ elif pct<0: pct = 0
+ return pct
+
+ # allow user to specify y's in whatever order
+ # excel expect y_end to be lower
+ if y_end < y_start:
+ y_end, y_start = y_start, y_end
+
+ return (_norm_pct(x_start), _norm_pct(y_start),
+ _norm_pct(x_end), _norm_pct(y_end))
+ \ No newline at end of file
diff --git a/tablib/packages/openpyxl3/reader/__init__.py b/tablib/packages/openpyxl3/reader/__init__.py
index 9b0ee2f..76f10f8 100644
--- a/tablib/packages/openpyxl3/reader/__init__.py
+++ b/tablib/packages/openpyxl3/reader/__init__.py
@@ -26,8 +26,8 @@
"""Imports for the openpyxl.reader namespace."""
# package imports
-from ..reader import excel
-from ..reader import strings
-from ..reader import style
-from ..reader import workbook
-from ..reader import worksheet
+from . import excel
+from . import strings
+from . import style
+from . import workbook
+from . import worksheet
diff --git a/tablib/packages/openpyxl3/reader/excel.py b/tablib/packages/openpyxl3/reader/excel.py
index 698d292..3fee695 100644
--- a/tablib/packages/openpyxl3/reader/excel.py
+++ b/tablib/packages/openpyxl3/reader/excel.py
@@ -33,12 +33,12 @@ from ..shared.exc import OpenModeError, InvalidFileException
from ..shared.ooxml import ARC_SHARED_STRINGS, ARC_CORE, ARC_APP, \
ARC_WORKBOOK, PACKAGE_WORKSHEETS, ARC_STYLE
from ..workbook import Workbook
-from ..reader.strings import read_string_table
-from ..reader.style import read_style_table
-from ..reader.workbook import read_sheets_titles, read_named_ranges, \
+from .strings import read_string_table
+from .style import read_style_table
+from .workbook import read_sheets_titles, read_named_ranges, \
read_properties_core, get_sheet_ids
-from ..reader.worksheet import read_worksheet
-from ..reader.iter_worksheet import unpack_worksheet
+from .worksheet import read_worksheet
+from .iter_worksheet import unpack_worksheet
def load_workbook(filename, use_iterators = False):
"""Open the given filename and return the workbook
@@ -49,11 +49,11 @@ def load_workbook(filename, use_iterators = False):
:param use_iterators: use lazy load for cells
:type use_iterators: bool
- :rtype: :class:`openpyxl.workbook.Workbook`
+ :rtype: :class:`..workbook.Workbook`
.. note::
- When using lazy load, all worksheets will be :class:`openpyxl.reader.iter_worksheet.IterableWorksheet`
+ When using lazy load, all worksheets will be :class:`.iter_worksheet.IterableWorksheet`
and the returned workbook will be read-only.
"""
diff --git a/tablib/packages/openpyxl3/reader/iter_worksheet.py b/tablib/packages/openpyxl3/reader/iter_worksheet.py
index 7bc9ed4..670e6b1 100644
--- a/tablib/packages/openpyxl3/reader/iter_worksheet.py
+++ b/tablib/packages/openpyxl3/reader/iter_worksheet.py
@@ -1,343 +1,343 @@
-# file openpyxl/reader/iter_worksheet.py
-
-# Copyright (c) 2010 openpyxl
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-#
-# @license: http://www.opensource.org/licenses/mit-license.php
-# @author: Eric Gazoni
-
-""" Iterators-based worksheet reader
-*Still very raw*
-"""
-
-from io import BytesIO as StringIO
-import warnings
-import operator
-from functools import partial
-from itertools import groupby
-from ..worksheet import Worksheet
-from ..cell import coordinate_from_string, get_column_letter, Cell
-from ..reader.excel import get_sheet_ids
-from ..reader.strings import read_string_table
-from ..reader.style import read_style_table, NumberFormat
-from ..shared.date_time import SharedDate
-from ..reader.worksheet import read_dimension
-from ..shared.ooxml import (MIN_COLUMN, MAX_COLUMN, PACKAGE_WORKSHEETS,
- MAX_ROW, MIN_ROW, ARC_SHARED_STRINGS, ARC_APP, ARC_STYLE)
-from xml.etree.cElementTree import iterparse
-from zipfile import ZipFile
-from .. import cell
-import re
-import tempfile
-import zlib
-import zipfile
-import struct
-
-TYPE_NULL = Cell.TYPE_NULL
-MISSING_VALUE = None
-
-RE_COORDINATE = re.compile('^([A-Z]+)([0-9]+)$')
-
-SHARED_DATE = SharedDate()
-
-_COL_CONVERSION_CACHE = dict((get_column_letter(i), i) for i in range(1, 18279))
-def column_index_from_string(str_col, _col_conversion_cache=_COL_CONVERSION_CACHE):
- # we use a function argument to get indexed name lookup
- return _col_conversion_cache[str_col]
-del _COL_CONVERSION_CACHE
-
-RAW_ATTRIBUTES = ['row', 'column', 'coordinate', 'internal_value', 'data_type', 'style_id', 'number_format']
-
-try:
- from collections import namedtuple
- BaseRawCell = namedtuple('RawCell', RAW_ATTRIBUTES)
-except ImportError:
-
- warnings.warn("""Unable to import 'namedtuple' module, this may cause memory issues when using optimized reader. Please upgrade your Python installation to 2.6+""")
-
- class BaseRawCell(object):
-
- def __init__(self, *args):
- assert len(args)==len(RAW_ATTRIBUTES)
-
- for attr, val in zip(RAW_ATTRIBUTES, args):
- setattr(self, attr, val)
-
- def _replace(self, **kwargs):
-
- self.__dict__.update(kwargs)
-
- return self
-
-
-class RawCell(BaseRawCell):
- """Optimized version of the :class:`openpyxl.cell.Cell`, using named tuples.
-
- Useful attributes are:
-
- * row
- * column
- * coordinate
- * internal_value
-
- You can also access if needed:
-
- * data_type
- * number_format
-
- """
-
- @property
- def is_date(self):
- res = (self.data_type == Cell.TYPE_NUMERIC
- and self.number_format is not None
- and ('d' in self.number_format
- or 'm' in self.number_format
- or 'y' in self.number_format
- or 'h' in self.number_format
- or 's' in self.number_format
- ))
-
- return res
-
-def iter_rows(workbook_name, sheet_name, xml_source, range_string = '', row_offset = 0, column_offset = 0):
-
- archive = get_archive_file(workbook_name)
-
- source = xml_source
-
- if range_string:
- min_col, min_row, max_col, max_row = get_range_boundaries(range_string, row_offset, column_offset)
- else:
- min_col, min_row, max_col, max_row = read_dimension(xml_source = source)
- min_col = column_index_from_string(min_col)
- max_col = column_index_from_string(max_col) + 1
- max_row += 6
-
- try:
- string_table = read_string_table(archive.read(ARC_SHARED_STRINGS))
- except KeyError:
- string_table = {}
-
- style_table = read_style_table(archive.read(ARC_STYLE))
-
- source.seek(0)
- p = iterparse(source)
-
- return get_squared_range(p, min_col, min_row, max_col, max_row, string_table, style_table)
-
-
-def get_rows(p, min_column = MIN_COLUMN, min_row = MIN_ROW, max_column = MAX_COLUMN, max_row = MAX_ROW):
-
- return groupby(get_cells(p, min_row, min_column, max_row, max_column), operator.attrgetter('row'))
-
-def get_cells(p, min_row, min_col, max_row, max_col, _re_coordinate=RE_COORDINATE):
-
- for _event, element in p:
-
- if element.tag == '{http://schemas.openxmlformats.org/spreadsheetml/2006/main}c':
- coord = element.get('r')
- column_str, row = _re_coordinate.match(coord).groups()
-
- row = int(row)
- column = column_index_from_string(column_str)
-
- if min_col <= column <= max_col and min_row <= row <= max_row:
- data_type = element.get('t', 'n')
- style_id = element.get('s')
- value = element.findtext('{http://schemas.openxmlformats.org/spreadsheetml/2006/main}v')
- yield RawCell(row, column_str, coord, value, data_type, style_id, None)
-
- if element.tag == '{http://schemas.openxmlformats.org/spreadsheetml/2006/main}v':
- continue
- element.clear()
-
-
-
-def get_range_boundaries(range_string, row = 0, column = 0):
-
- if ':' in range_string:
- min_range, max_range = range_string.split(':')
- min_col, min_row = coordinate_from_string(min_range)
- max_col, max_row = coordinate_from_string(max_range)
-
- min_col = column_index_from_string(min_col) + column
- max_col = column_index_from_string(max_col) + column
- min_row += row
- max_row += row
-
- else:
- min_col, min_row = coordinate_from_string(range_string)
- min_col = column_index_from_string(min_col)
- max_col = min_col + 1
- max_row = min_row
-
- return (min_col, min_row, max_col, max_row)
-
-def get_archive_file(archive_name):
-
- return ZipFile(archive_name, 'r')
-
-def get_xml_source(archive_file, sheet_name):
-
- return archive_file.read('%s/%s' % (PACKAGE_WORKSHEETS, sheet_name))
-
-def get_missing_cells(row, columns):
-
- return dict([(column, RawCell(row, column, '%s%s' % (column, row), MISSING_VALUE, TYPE_NULL, None, None)) for column in columns])
-
-def get_squared_range(p, min_col, min_row, max_col, max_row, string_table, style_table):
-
- expected_columns = [get_column_letter(ci) for ci in range(min_col, max_col)]
-
- current_row = min_row
- for row, cells in get_rows(p, min_row = min_row, max_row = max_row, min_column = min_col, max_column = max_col):
- full_row = []
- if current_row < row:
-
- for gap_row in range(current_row, row):
-
- dummy_cells = get_missing_cells(gap_row, expected_columns)
-
- yield tuple([dummy_cells[column] for column in expected_columns])
-
- current_row = row
-
- temp_cells = list(cells)
-
- retrieved_columns = dict([(c.column, c) for c in temp_cells])
-
- missing_columns = list(set(expected_columns) - set(retrieved_columns.keys()))
-
- replacement_columns = get_missing_cells(row, missing_columns)
-
- for column in expected_columns:
-
- if column in retrieved_columns:
- cell = retrieved_columns[column]
-
- if cell.style_id is not None:
- style = style_table[int(cell.style_id)]
- cell = cell._replace(number_format = style.number_format.format_code) #pylint: disable-msg=W0212
- if cell.internal_value is not None:
- if cell.data_type == Cell.TYPE_STRING:
- cell = cell._replace(internal_value = string_table[int(cell.internal_value)]) #pylint: disable-msg=W0212
- elif cell.data_type == Cell.TYPE_BOOL:
- cell = cell._replace(internal_value = cell.internal_value == 'True')
- elif cell.is_date:
- cell = cell._replace(internal_value = SHARED_DATE.from_julian(float(cell.internal_value)))
- elif cell.data_type == Cell.TYPE_NUMERIC:
- cell = cell._replace(internal_value = float(cell.internal_value))
- full_row.append(cell)
-
- else:
- full_row.append(replacement_columns[column])
-
- current_row = row + 1
-
- yield tuple(full_row)
-
-#------------------------------------------------------------------------------
-
-class IterableWorksheet(Worksheet):
-
- def __init__(self, parent_workbook, title, workbook_name,
- sheet_codename, xml_source):
-
- Worksheet.__init__(self, parent_workbook, title)
- self._workbook_name = workbook_name
- self._sheet_codename = sheet_codename
- self._xml_source = xml_source
-
- def iter_rows(self, range_string = '', row_offset = 0, column_offset = 0):
- """ Returns a squared range based on the `range_string` parameter,
- using generators.
-
- :param range_string: range of cells (e.g. 'A1:C4')
- :type range_string: string
-
- :param row: row index of the cell (e.g. 4)
- :type row: int
-
- :param column: column index of the cell (e.g. 3)
- :type column: int
-
- :rtype: generator
-
- """
-
- return iter_rows(workbook_name = self._workbook_name,
- sheet_name = self._sheet_codename,
- xml_source = self._xml_source,
- range_string = range_string,
- row_offset = row_offset,
- column_offset = column_offset)
-
- def cell(self, *args, **kwargs):
-
- raise NotImplementedError("use 'iter_rows()' instead")
-
- def range(self, *args, **kwargs):
-
- raise NotImplementedError("use 'iter_rows()' instead")
-
-def unpack_worksheet(archive, filename):
-
- temp_file = tempfile.TemporaryFile(mode='r+', prefix='openpyxl.', suffix='.unpack.temp')
-
- zinfo = archive.getinfo(filename)
-
- if zinfo.compress_type == zipfile.ZIP_STORED:
- decoder = None
- elif zinfo.compress_type == zipfile.ZIP_DEFLATED:
- decoder = zlib.decompressobj(-zlib.MAX_WBITS)
- else:
- raise zipfile.BadZipFile("Unrecognized compression method")
-
- archive.fp.seek(_get_file_offset(archive, zinfo))
- bytes_to_read = zinfo.compress_size
-
- while True:
- buff = archive.fp.read(min(bytes_to_read, 102400))
- if not buff:
- break
- bytes_to_read -= len(buff)
- if decoder:
- buff = decoder.decompress(buff)
- temp_file.write(buff)
-
- if decoder:
- temp_file.write(decoder.decompress('Z'))
-
- return temp_file
-
-def _get_file_offset(archive, zinfo):
-
- try:
- return zinfo.file_offset
- except AttributeError:
- # From http://stackoverflow.com/questions/3781261/how-to-simulate-zipfile-open-in-python-2-5
-
- # Seek over the fixed size fields to the "file name length" field in
- # the file header (26 bytes). Unpack this and the "extra field length"
- # field ourselves as info.extra doesn't seem to be the correct length.
- archive.fp.seek(zinfo.header_offset + 26)
- file_name_len, extra_len = struct.unpack("<HH", archive.fp.read(4))
- return zinfo.header_offset + 30 + file_name_len + extra_len
+# file openpyxl/reader/iter_worksheet.py
+
+# Copyright (c) 2010 openpyxl
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# @license: http://www.opensource.org/licenses/mit-license.php
+# @author: Eric Gazoni
+
+""" Iterators-based worksheet reader
+*Still very raw*
+"""
+
+from io import StringIO
+import warnings
+import operator
+from functools import partial
+from itertools import groupby
+from ..worksheet import Worksheet
+from ..cell import coordinate_from_string, get_column_letter, Cell
+from .excel import get_sheet_ids
+from .strings import read_string_table
+from .style import read_style_table, NumberFormat
+from ..shared.date_time import SharedDate
+from .worksheet import read_dimension
+from ..shared.ooxml import (MIN_COLUMN, MAX_COLUMN, PACKAGE_WORKSHEETS,
+ MAX_ROW, MIN_ROW, ARC_SHARED_STRINGS, ARC_APP, ARC_STYLE)
+from xml.etree.cElementTree import iterparse
+from zipfile import ZipFile
+from .. import cell
+import re
+import tempfile
+import zlib
+import zipfile
+import struct
+
+TYPE_NULL = Cell.TYPE_NULL
+MISSING_VALUE = None
+
+RE_COORDINATE = re.compile('^([A-Z]+)([0-9]+)$')
+
+SHARED_DATE = SharedDate()
+
+_COL_CONVERSION_CACHE = dict((get_column_letter(i), i) for i in range(1, 18279))
+def column_index_from_string(str_col, _col_conversion_cache=_COL_CONVERSION_CACHE):
+ # we use a function argument to get indexed name lookup
+ return _col_conversion_cache[str_col]
+del _COL_CONVERSION_CACHE
+
+RAW_ATTRIBUTES = ['row', 'column', 'coordinate', 'internal_value', 'data_type', 'style_id', 'number_format']
+
+try:
+ from collections import namedtuple
+ BaseRawCell = namedtuple('RawCell', RAW_ATTRIBUTES)
+except ImportError:
+
+ warnings.warn("""Unable to import 'namedtuple' module, this may cause memory issues when using optimized reader. Please upgrade your Python installation to 2.6+""")
+
+ class BaseRawCell(object):
+
+ def __init__(self, *args):
+ assert len(args)==len(RAW_ATTRIBUTES)
+
+ for attr, val in zip(RAW_ATTRIBUTES, args):
+ setattr(self, attr, val)
+
+ def _replace(self, **kwargs):
+
+ self.__dict__.update(kwargs)
+
+ return self
+
+
+class RawCell(BaseRawCell):
+ """Optimized version of the :class:`..cell.Cell`, using named tuples.
+
+ Useful attributes are:
+
+ * row
+ * column
+ * coordinate
+ * internal_value
+
+ You can also access if needed:
+
+ * data_type
+ * number_format
+
+ """
+
+ @property
+ def is_date(self):
+ res = (self.data_type == Cell.TYPE_NUMERIC
+ and self.number_format is not None
+ and ('d' in self.number_format
+ or 'm' in self.number_format
+ or 'y' in self.number_format
+ or 'h' in self.number_format
+ or 's' in self.number_format
+ ))
+
+ return res
+
+def iter_rows(workbook_name, sheet_name, xml_source, range_string = '', row_offset = 0, column_offset = 0):
+
+ archive = get_archive_file(workbook_name)
+
+ source = xml_source
+
+ if range_string:
+ min_col, min_row, max_col, max_row = get_range_boundaries(range_string, row_offset, column_offset)
+ else:
+ min_col, min_row, max_col, max_row = read_dimension(xml_source = source)
+ min_col = column_index_from_string(min_col)
+ max_col = column_index_from_string(max_col) + 1
+ max_row += 6
+
+ try:
+ string_table = read_string_table(archive.read(ARC_SHARED_STRINGS))
+ except KeyError:
+ string_table = {}
+
+ style_table = read_style_table(archive.read(ARC_STYLE))
+
+ source.seek(0)
+ p = iterparse(source)
+
+ return get_squared_range(p, min_col, min_row, max_col, max_row, string_table, style_table)
+
+
+def get_rows(p, min_column = MIN_COLUMN, min_row = MIN_ROW, max_column = MAX_COLUMN, max_row = MAX_ROW):
+
+ return groupby(get_cells(p, min_row, min_column, max_row, max_column), operator.attrgetter('row'))
+
+def get_cells(p, min_row, min_col, max_row, max_col, _re_coordinate=RE_COORDINATE):
+
+ for _event, element in p:
+
+ if element.tag == '{http://schemas.openxmlformats.org/spreadsheetml/2006/main}c':
+ coord = element.get('r')
+ column_str, row = _re_coordinate.match(coord).groups()
+
+ row = int(row)
+ column = column_index_from_string(column_str)
+
+ if min_col <= column <= max_col and min_row <= row <= max_row:
+ data_type = element.get('t', 'n')
+ style_id = element.get('s')
+ value = element.findtext('{http://schemas.openxmlformats.org/spreadsheetml/2006/main}v')
+ yield RawCell(row, column_str, coord, value, data_type, style_id, None)
+
+ if element.tag == '{http://schemas.openxmlformats.org/spreadsheetml/2006/main}v':
+ continue
+ element.clear()
+
+
+
+def get_range_boundaries(range_string, row = 0, column = 0):
+
+ if ':' in range_string:
+ min_range, max_range = range_string.split(':')
+ min_col, min_row = coordinate_from_string(min_range)
+ max_col, max_row = coordinate_from_string(max_range)
+
+ min_col = column_index_from_string(min_col) + column
+ max_col = column_index_from_string(max_col) + column
+ min_row += row
+ max_row += row
+
+ else:
+ min_col, min_row = coordinate_from_string(range_string)
+ min_col = column_index_from_string(min_col)
+ max_col = min_col + 1
+ max_row = min_row
+
+ return (min_col, min_row, max_col, max_row)
+
+def get_archive_file(archive_name):
+
+ return ZipFile(archive_name, 'r')
+
+def get_xml_source(archive_file, sheet_name):
+
+ return archive_file.read('%s/%s' % (PACKAGE_WORKSHEETS, sheet_name))
+
+def get_missing_cells(row, columns):
+
+ return dict([(column, RawCell(row, column, '%s%s' % (column, row), MISSING_VALUE, TYPE_NULL, None, None)) for column in columns])
+
+def get_squared_range(p, min_col, min_row, max_col, max_row, string_table, style_table):
+
+ expected_columns = [get_column_letter(ci) for ci in range(min_col, max_col)]
+
+ current_row = min_row
+ for row, cells in get_rows(p, min_row = min_row, max_row = max_row, min_column = min_col, max_column = max_col):
+ full_row = []
+ if current_row < row:
+
+ for gap_row in range(current_row, row):
+
+ dummy_cells = get_missing_cells(gap_row, expected_columns)
+
+ yield tuple([dummy_cells[column] for column in expected_columns])
+
+ current_row = row
+
+ temp_cells = list(cells)
+
+ retrieved_columns = dict([(c.column, c) for c in temp_cells])
+
+ missing_columns = list(set(expected_columns) - set(retrieved_columns.keys()))
+
+ replacement_columns = get_missing_cells(row, missing_columns)
+
+ for column in expected_columns:
+
+ if column in retrieved_columns:
+ cell = retrieved_columns[column]
+
+ if cell.style_id is not None:
+ style = style_table[int(cell.style_id)]
+ cell = cell._replace(number_format = style.number_format.format_code) #pylint: disable-msg=W0212
+ if cell.internal_value is not None:
+ if cell.data_type == Cell.TYPE_STRING:
+ cell = cell._replace(internal_value = string_table[int(cell.internal_value)]) #pylint: disable-msg=W0212
+ elif cell.data_type == Cell.TYPE_BOOL:
+ cell = cell._replace(internal_value = cell.internal_value == 'True')
+ elif cell.is_date:
+ cell = cell._replace(internal_value = SHARED_DATE.from_julian(float(cell.internal_value)))
+ elif cell.data_type == Cell.TYPE_NUMERIC:
+ cell = cell._replace(internal_value = float(cell.internal_value))
+ full_row.append(cell)
+
+ else:
+ full_row.append(replacement_columns[column])
+
+ current_row = row + 1
+
+ yield tuple(full_row)
+
+#------------------------------------------------------------------------------
+
+class IterableWorksheet(Worksheet):
+
+ def __init__(self, parent_workbook, title, workbook_name,
+ sheet_codename, xml_source):
+
+ Worksheet.__init__(self, parent_workbook, title)
+ self._workbook_name = workbook_name
+ self._sheet_codename = sheet_codename
+ self._xml_source = xml_source
+
+ def iter_rows(self, range_string = '', row_offset = 0, column_offset = 0):
+ """ Returns a squared range based on the `range_string` parameter,
+ using generators.
+
+ :param range_string: range of cells (e.g. 'A1:C4')
+ :type range_string: string
+
+ :param row: row index of the cell (e.g. 4)
+ :type row: int
+
+ :param column: column index of the cell (e.g. 3)
+ :type column: int
+
+ :rtype: generator
+
+ """
+
+ return iter_rows(workbook_name = self._workbook_name,
+ sheet_name = self._sheet_codename,
+ xml_source = self._xml_source,
+ range_string = range_string,
+ row_offset = row_offset,
+ column_offset = column_offset)
+
+ def cell(self, *args, **kwargs):
+
+ raise NotImplementedError("use 'iter_rows()' instead")
+
+ def range(self, *args, **kwargs):
+
+ raise NotImplementedError("use 'iter_rows()' instead")
+
+def unpack_worksheet(archive, filename):
+
+ temp_file = tempfile.TemporaryFile(mode='r+', prefix='openpyxl.', suffix='.unpack.temp')
+
+ zinfo = archive.getinfo(filename)
+
+ if zinfo.compress_type == zipfile.ZIP_STORED:
+ decoder = None
+ elif zinfo.compress_type == zipfile.ZIP_DEFLATED:
+ decoder = zlib.decompressobj(-zlib.MAX_WBITS)
+ else:
+ raise zipfile.BadZipFile("Unrecognized compression method")
+
+ archive.fp.seek(_get_file_offset(archive, zinfo))
+ bytes_to_read = zinfo.compress_size
+
+ while True:
+ buff = archive.fp.read(min(bytes_to_read, 102400))
+ if not buff:
+ break
+ bytes_to_read -= len(buff)
+ if decoder:
+ buff = decoder.decompress(buff)
+ temp_file.write(buff)
+
+ if decoder:
+ temp_file.write(decoder.decompress('Z'))
+
+ return temp_file
+
+def _get_file_offset(archive, zinfo):
+
+ try:
+ return zinfo.file_offset
+ except AttributeError:
+ # From http://stackoverflow.com/questions/3781261/how-to-simulate-zipfile-open-in-python-2-5
+
+ # Seek over the fixed size fields to the "file name length" field in
+ # the file header (26 bytes). Unpack this and the "extra field length"
+ # field ourselves as info.extra doesn't seem to be the correct length.
+ archive.fp.seek(zinfo.header_offset + 26)
+ file_name_len, extra_len = struct.unpack("<HH", archive.fp.read(4))
+ return zinfo.header_offset + 30 + file_name_len + extra_len
diff --git a/tablib/packages/openpyxl3/reader/worksheet.py b/tablib/packages/openpyxl3/reader/worksheet.py
index 10b355a..c1c084c 100644
--- a/tablib/packages/openpyxl3/reader/worksheet.py
+++ b/tablib/packages/openpyxl3/reader/worksheet.py
@@ -30,7 +30,8 @@ try:
from xml.etree.cElementTree import iterparse
except ImportError:
from xml.etree.ElementTree import iterparse
-from io import BytesIO as StringIO
+
+from io import StringIO
# package imports
from ..cell import Cell, coordinate_from_string
@@ -54,8 +55,12 @@ def read_dimension(xml_source):
if element.tag == '{http://schemas.openxmlformats.org/spreadsheetml/2006/main}dimension':
ref = element.get('ref')
+
+ if ':' in ref:
+ min_range, max_range = ref.split(':')
+ else:
+ min_range = max_range = ref
- min_range, max_range = ref.split(':')
min_col, min_row = coordinate_from_string(min_range)
max_col, max_row = coordinate_from_string(max_range)
@@ -66,9 +71,9 @@ def read_dimension(xml_source):
return None
-def filter_cells(pair):
- (event, element) = pair
+def filter_cells(xxx_todo_changeme):
+ (event, element) = xxx_todo_changeme
return element.tag == '{http://schemas.openxmlformats.org/spreadsheetml/2006/main}c'
def fast_parse(ws, xml_source, string_table, style_table):
diff --git a/tablib/packages/openpyxl3/shared/__init__.py b/tablib/packages/openpyxl3/shared/__init__.py
index 002fd68..c19d52c 100644
--- a/tablib/packages/openpyxl3/shared/__init__.py
+++ b/tablib/packages/openpyxl3/shared/__init__.py
@@ -23,11 +23,11 @@
# @license: http://www.opensource.org/licenses/mit-license.php
# @author: Eric Gazoni
-"""Imports for the openpyxl.shared namespace."""
+"""Imports for the . namespace."""
# package imports
-from ..shared import date_time
-from ..shared import exc
-from ..shared import ooxml
-from ..shared import password_hasher
-from ..shared import xmltools
+from . import date_time
+from . import exc
+from . import ooxml
+from . import password_hasher
+from . import xmltools
diff --git a/tablib/packages/openpyxl3/shared/date_time.py b/tablib/packages/openpyxl3/shared/date_time.py
index 7d87788..8a58cd0 100644
--- a/tablib/packages/openpyxl3/shared/date_time.py
+++ b/tablib/packages/openpyxl3/shared/date_time.py
@@ -26,7 +26,7 @@
"""Manage Excel date weirdness."""
# Python stdlib imports
-from __future__ import division
+
from math import floor
import calendar
import datetime
@@ -48,7 +48,7 @@ def datetime_to_W3CDTF(dt):
def W3CDTF_to_datetime(formatted_string):
"""Convert from a timestamp string to a datetime object."""
match = re.match(RE_W3CDTF,formatted_string)
- digits = map(int, match.groups()[:6])
+ digits = list(map(int, match.groups()[:6]))
return datetime.datetime(*digits)
diff --git a/tablib/packages/openpyxl3/style.py b/tablib/packages/openpyxl3/style.py
index 38628db..c113bd9 100644
--- a/tablib/packages/openpyxl3/style.py
+++ b/tablib/packages/openpyxl3/style.py
@@ -340,7 +340,7 @@ class NumberFormat(HashableObject):
"""Check if a format code is a standard format code."""
if format is None:
format = self._format_code
- return format in self._BUILTIN_FORMATS.values()
+ return format in list(self._BUILTIN_FORMATS.values())
def builtin_format_id(self, format):
"""Return the id of a standard style."""
diff --git a/tablib/packages/openpyxl3/tests/helper.py b/tablib/packages/openpyxl3/tests/helper.py
index a60712b..9dfbfaf 100644
--- a/tablib/packages/openpyxl3/tests/helper.py
+++ b/tablib/packages/openpyxl3/tests/helper.py
@@ -24,12 +24,12 @@
# @author: Eric Gazoni
# Python stdlib imports
-from __future__ import with_statement
+
import os
import os.path
import shutil
import difflib
-from io import BytesIO as StringIO
+from io import StringIO
from pprint import pprint
from tempfile import gettempdir
diff --git a/tablib/packages/openpyxl3/tests/test_cell.py b/tablib/packages/openpyxl3/tests/test_cell.py
index edc35c0..07f0b6f 100644
--- a/tablib/packages/openpyxl3/tests/test_cell.py
+++ b/tablib/packages/openpyxl3/tests/test_cell.py
@@ -134,7 +134,7 @@ class TestCellValueTypes():
def check_error():
eq_(self.cell.TYPE_ERROR, self.cell.data_type)
- for error_string in self.cell.ERROR_CODES.keys():
+ for error_string in list(self.cell.ERROR_CODES.keys()):
self.cell.value = error_string
yield check_error
diff --git a/tablib/packages/openpyxl3/tests/test_chart.py b/tablib/packages/openpyxl3/tests/test_chart.py
index cc3fcda..09a7bbc 100644
--- a/tablib/packages/openpyxl3/tests/test_chart.py
+++ b/tablib/packages/openpyxl3/tests/test_chart.py
@@ -1,131 +1,131 @@
-# file openpyxl/tests/test_chart.py
-
-# Copyright (c) 2010 openpyxl
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-#
-# @license: http://www.opensource.org/licenses/mit-license.php
-# @author: Eric Gazoni
-
-from nose.tools import eq_
-
-from openpyxl.tests.helper import get_xml
-from openpyxl.shared.xmltools import Element
-from openpyxl.writer.charts import ChartWriter
-from openpyxl.workbook import Workbook
-from openpyxl.chart import BarChart, ScatterChart, Serie, Reference
-from openpyxl.style import Color
-
-class TestChartWriter(object):
-
- def setUp(self):
-
- wb = Workbook()
- ws = wb.get_active_sheet()
- ws.title = 'data'
- for i in range(10):
- ws.cell(row = i, column = 0).value = i
- self.chart = BarChart()
- self.chart.title = 'TITLE'
- self.chart.add_serie(Serie(Reference(ws, (0, 0), (10, 0))))
- self.chart._series[-1].color = Color.GREEN
- self.cw = ChartWriter(self.chart)
- self.root = Element('test')
-
- def test_write_title(self):
- self.cw._write_title(self.root)
- eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:title><c:tx><c:rich><a:bodyPr /><a:lstStyle /><a:p><a:pPr><a:defRPr /></a:pPr><a:r><a:rPr lang="fr-FR" /><a:t>TITLE</a:t></a:r></a:p></c:rich></c:tx><c:layout /></c:title></test>')
-
- def test_write_xaxis(self):
-
- self.cw._write_axis(self.root, self.chart.x_axis, 'c:catAx')
- eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:catAx><c:axId val="60871424" /><c:scaling><c:orientation val="minMax" /></c:scaling><c:axPos val="b" /><c:tickLblPos val="nextTo" /><c:crossAx val="60873344" /><c:crosses val="autoZero" /><c:auto val="1" /><c:lblAlgn val="ctr" /><c:lblOffset val="100" /></c:catAx></test>')
-
- def test_write_yaxis(self):
-
- self.cw._write_axis(self.root, self.chart.y_axis, 'c:valAx')
- eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:valAx><c:axId val="60873344" /><c:scaling><c:orientation val="minMax" /><c:max val="10.0" /><c:min val="0" /></c:scaling><c:axPos val="l" /><c:majorGridlines /><c:numFmt formatCode="General" sourceLinked="1" /><c:tickLblPos val="nextTo" /><c:crossAx val="60871424" /><c:crosses val="autoZero" /><c:crossBetween val="between" /><c:majorUnit val="2.0" /></c:valAx></test>')
-
- def test_write_series(self):
-
- self.cw._write_series(self.root)
- eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:ser><c:idx val="0" /><c:order val="0" /><c:spPr><a:solidFill><a:srgbClr val="00FF00" /></a:solidFill><a:ln><a:solidFill><a:srgbClr val="00FF00" /></a:solidFill></a:ln></c:spPr><c:marker><c:symbol val="none" /></c:marker><c:val><c:numRef><c:f>data!$A$1:$A$11</c:f><c:numCache><c:formatCode>General</c:formatCode><c:ptCount val="11" /><c:pt idx="0"><c:v>0</c:v></c:pt><c:pt idx="1"><c:v>1</c:v></c:pt><c:pt idx="2"><c:v>2</c:v></c:pt><c:pt idx="3"><c:v>3</c:v></c:pt><c:pt idx="4"><c:v>4</c:v></c:pt><c:pt idx="5"><c:v>5</c:v></c:pt><c:pt idx="6"><c:v>6</c:v></c:pt><c:pt idx="7"><c:v>7</c:v></c:pt><c:pt idx="8"><c:v>8</c:v></c:pt><c:pt idx="9"><c:v>9</c:v></c:pt><c:pt idx="10"><c:v>None</c:v></c:pt></c:numCache></c:numRef></c:val></c:ser></test>')
-
- def test_write_legend(self):
-
- self.cw._write_legend(self.root)
- eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:legend><c:legendPos val="r" /><c:layout /></c:legend></test>')
-
- def test_write_print_settings(self):
-
- self.cw._write_print_settings(self.root)
- eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:printSettings><c:headerFooter /><c:pageMargins b="0.75" footer="0.3" header="0.3" l="0.7" r="0.7" t="0.75" /><c:pageSetup /></c:printSettings></test>')
-
- def test_write_chart(self):
-
- self.cw._write_chart(self.root)
- eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:chart><c:title><c:tx><c:rich><a:bodyPr /><a:lstStyle /><a:p><a:pPr><a:defRPr /></a:pPr><a:r><a:rPr lang="fr-FR" /><a:t>TITLE</a:t></a:r></a:p></c:rich></c:tx><c:layout /></c:title><c:plotArea><c:layout><c:manualLayout><c:layoutTarget val="inner" /><c:xMode val="edge" /><c:yMode val="edge" /><c:x val="1.28571428571" /><c:y val="0.2125" /><c:w val="0.6" /><c:h val="0.6" /></c:manualLayout></c:layout><c:barChart><c:barDir val="col" /><c:grouping val="clustered" /><c:ser><c:idx val="0" /><c:order val="0" /><c:spPr><a:solidFill><a:srgbClr val="00FF00" /></a:solidFill><a:ln><a:solidFill><a:srgbClr val="00FF00" /></a:solidFill></a:ln></c:spPr><c:marker><c:symbol val="none" /></c:marker><c:val><c:numRef><c:f>data!$A$1:$A$11</c:f><c:numCache><c:formatCode>General</c:formatCode><c:ptCount val="11" /><c:pt idx="0"><c:v>0</c:v></c:pt><c:pt idx="1"><c:v>1</c:v></c:pt><c:pt idx="2"><c:v>2</c:v></c:pt><c:pt idx="3"><c:v>3</c:v></c:pt><c:pt idx="4"><c:v>4</c:v></c:pt><c:pt idx="5"><c:v>5</c:v></c:pt><c:pt idx="6"><c:v>6</c:v></c:pt><c:pt idx="7"><c:v>7</c:v></c:pt><c:pt idx="8"><c:v>8</c:v></c:pt><c:pt idx="9"><c:v>9</c:v></c:pt><c:pt idx="10"><c:v>None</c:v></c:pt></c:numCache></c:numRef></c:val></c:ser><c:marker val="1" /><c:axId val="60871424" /><c:axId val="60873344" /></c:barChart><c:catAx><c:axId val="60871424" /><c:scaling><c:orientation val="minMax" /></c:scaling><c:axPos val="b" /><c:tickLblPos val="nextTo" /><c:crossAx val="60873344" /><c:crosses val="autoZero" /><c:auto val="1" /><c:lblAlgn val="ctr" /><c:lblOffset val="100" /></c:catAx><c:valAx><c:axId val="60873344" /><c:scaling><c:orientation val="minMax" /><c:max val="10.0" /><c:min val="0" /></c:scaling><c:axPos val="l" /><c:majorGridlines /><c:numFmt formatCode="General" sourceLinked="1" /><c:tickLblPos val="nextTo" /><c:crossAx val="60871424" /><c:crosses val="autoZero" /><c:crossBetween val="between" /><c:majorUnit val="2.0" /></c:valAx></c:plotArea><c:legend><c:legendPos val="r" /><c:layout /></c:legend><c:plotVisOnly val="1" /></c:chart></test>')
-
-
-class TestScatterChartWriter(object):
-
- def setUp(self):
-
- wb = Workbook()
- ws = wb.get_active_sheet()
- ws.title = 'data'
- for i in range(10):
- ws.cell(row = i, column = 0).value = i
- ws.cell(row = i, column = 1).value = i
- self.scatterchart = ScatterChart()
- self.scatterchart.add_serie(Serie(Reference(ws, (0, 0), (10, 0)),
- xvalues = Reference(ws, (0, 1), (10, 1))))
- self.cw = ChartWriter(self.scatterchart)
- self.root = Element('test')
-
- def test_write_xaxis(self):
-
- self.cw._write_axis(self.root, self.scatterchart.x_axis, 'c:valAx')
- eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:valAx><c:axId val="60871424" /><c:scaling><c:orientation val="minMax" /><c:max val="10.0" /><c:min val="0" /></c:scaling><c:axPos val="b" /><c:majorGridlines /><c:numFmt formatCode="General" sourceLinked="1" /><c:tickLblPos val="nextTo" /><c:crossAx val="60873344" /><c:crosses val="autoZero" /><c:auto val="1" /><c:lblAlgn val="ctr" /><c:lblOffset val="100" /><c:crossBetween val="midCat" /><c:majorUnit val="2.0" /></c:valAx></test>')
-
-
- def test_write_yaxis(self):
-
- self.cw._write_axis(self.root, self.scatterchart.y_axis, 'c:valAx')
- eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:valAx><c:axId val="60873344" /><c:scaling><c:orientation val="minMax" /><c:max val="10.0" /><c:min val="0" /></c:scaling><c:axPos val="l" /><c:majorGridlines /><c:numFmt formatCode="General" sourceLinked="1" /><c:tickLblPos val="nextTo" /><c:crossAx val="60871424" /><c:crosses val="autoZero" /><c:crossBetween val="midCat" /><c:majorUnit val="2.0" /></c:valAx></test>')
-
- def test_write_series(self):
-
- self.cw._write_series(self.root)
- eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:ser><c:idx val="0" /><c:order val="0" /><c:marker><c:symbol val="none" /></c:marker><c:xVal><c:numRef><c:f>data!$B$1:$B$11</c:f><c:numCache><c:formatCode>General</c:formatCode><c:ptCount val="11" /><c:pt idx="0"><c:v>0</c:v></c:pt><c:pt idx="1"><c:v>1</c:v></c:pt><c:pt idx="2"><c:v>2</c:v></c:pt><c:pt idx="3"><c:v>3</c:v></c:pt><c:pt idx="4"><c:v>4</c:v></c:pt><c:pt idx="5"><c:v>5</c:v></c:pt><c:pt idx="6"><c:v>6</c:v></c:pt><c:pt idx="7"><c:v>7</c:v></c:pt><c:pt idx="8"><c:v>8</c:v></c:pt><c:pt idx="9"><c:v>9</c:v></c:pt><c:pt idx="10"><c:v>None</c:v></c:pt></c:numCache></c:numRef></c:xVal><c:yVal><c:numRef><c:f>data!$A$1:$A$11</c:f><c:numCache><c:formatCode>General</c:formatCode><c:ptCount val="11" /><c:pt idx="0"><c:v>0</c:v></c:pt><c:pt idx="1"><c:v>1</c:v></c:pt><c:pt idx="2"><c:v>2</c:v></c:pt><c:pt idx="3"><c:v>3</c:v></c:pt><c:pt idx="4"><c:v>4</c:v></c:pt><c:pt idx="5"><c:v>5</c:v></c:pt><c:pt idx="6"><c:v>6</c:v></c:pt><c:pt idx="7"><c:v>7</c:v></c:pt><c:pt idx="8"><c:v>8</c:v></c:pt><c:pt idx="9"><c:v>9</c:v></c:pt><c:pt idx="10"><c:v>None</c:v></c:pt></c:numCache></c:numRef></c:yVal></c:ser></test>')
-
- def test_write_legend(self):
-
- self.cw._write_legend(self.root)
- eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:legend><c:legendPos val="r" /><c:layout /></c:legend></test>')
-
- def test_write_print_settings(self):
-
- self.cw._write_print_settings(self.root)
- eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:printSettings><c:headerFooter /><c:pageMargins b="0.75" footer="0.3" header="0.3" l="0.7" r="0.7" t="0.75" /><c:pageSetup /></c:printSettings></test>')
-
- def test_write_chart(self):
-
- self.cw._write_chart(self.root)
- eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:chart><c:plotArea><c:layout><c:manualLayout><c:layoutTarget val="inner" /><c:xMode val="edge" /><c:yMode val="edge" /><c:x val="1.28571428571" /><c:y val="0.2125" /><c:w val="0.6" /><c:h val="0.6" /></c:manualLayout></c:layout><c:scatterChart><c:scatterStyle val="lineMarker" /><c:ser><c:idx val="0" /><c:order val="0" /><c:marker><c:symbol val="none" /></c:marker><c:xVal><c:numRef><c:f>data!$B$1:$B$11</c:f><c:numCache><c:formatCode>General</c:formatCode><c:ptCount val="11" /><c:pt idx="0"><c:v>0</c:v></c:pt><c:pt idx="1"><c:v>1</c:v></c:pt><c:pt idx="2"><c:v>2</c:v></c:pt><c:pt idx="3"><c:v>3</c:v></c:pt><c:pt idx="4"><c:v>4</c:v></c:pt><c:pt idx="5"><c:v>5</c:v></c:pt><c:pt idx="6"><c:v>6</c:v></c:pt><c:pt idx="7"><c:v>7</c:v></c:pt><c:pt idx="8"><c:v>8</c:v></c:pt><c:pt idx="9"><c:v>9</c:v></c:pt><c:pt idx="10"><c:v>None</c:v></c:pt></c:numCache></c:numRef></c:xVal><c:yVal><c:numRef><c:f>data!$A$1:$A$11</c:f><c:numCache><c:formatCode>General</c:formatCode><c:ptCount val="11" /><c:pt idx="0"><c:v>0</c:v></c:pt><c:pt idx="1"><c:v>1</c:v></c:pt><c:pt idx="2"><c:v>2</c:v></c:pt><c:pt idx="3"><c:v>3</c:v></c:pt><c:pt idx="4"><c:v>4</c:v></c:pt><c:pt idx="5"><c:v>5</c:v></c:pt><c:pt idx="6"><c:v>6</c:v></c:pt><c:pt idx="7"><c:v>7</c:v></c:pt><c:pt idx="8"><c:v>8</c:v></c:pt><c:pt idx="9"><c:v>9</c:v></c:pt><c:pt idx="10"><c:v>None</c:v></c:pt></c:numCache></c:numRef></c:yVal></c:ser><c:marker val="1" /><c:axId val="60871424" /><c:axId val="60873344" /></c:scatterChart><c:valAx><c:axId val="60871424" /><c:scaling><c:orientation val="minMax" /><c:max val="10.0" /><c:min val="0" /></c:scaling><c:axPos val="b" /><c:majorGridlines /><c:numFmt formatCode="General" sourceLinked="1" /><c:tickLblPos val="nextTo" /><c:crossAx val="60873344" /><c:crosses val="autoZero" /><c:auto val="1" /><c:lblAlgn val="ctr" /><c:lblOffset val="100" /><c:crossBetween val="midCat" /><c:majorUnit val="2.0" /></c:valAx><c:valAx><c:axId val="60873344" /><c:scaling><c:orientation val="minMax" /><c:max val="10.0" /><c:min val="0" /></c:scaling><c:axPos val="l" /><c:majorGridlines /><c:numFmt formatCode="General" sourceLinked="1" /><c:tickLblPos val="nextTo" /><c:crossAx val="60871424" /><c:crosses val="autoZero" /><c:crossBetween val="midCat" /><c:majorUnit val="2.0" /></c:valAx></c:plotArea><c:legend><c:legendPos val="r" /><c:layout /></c:legend><c:plotVisOnly val="1" /></c:chart></test>')
+# file openpyxl/tests/test_chart.py
+
+# Copyright (c) 2010 openpyxl
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# @license: http://www.opensource.org/licenses/mit-license.php
+# @author: Eric Gazoni
+
+from nose.tools import eq_
+
+from openpyxl.tests.helper import get_xml
+from openpyxl.shared.xmltools import Element
+from openpyxl.writer.charts import ChartWriter
+from openpyxl.workbook import Workbook
+from openpyxl.chart import BarChart, ScatterChart, Serie, Reference
+from openpyxl.style import Color
+
+class TestChartWriter(object):
+
+ def setUp(self):
+
+ wb = Workbook()
+ ws = wb.get_active_sheet()
+ ws.title = 'data'
+ for i in range(10):
+ ws.cell(row = i, column = 0).value = i
+ self.chart = BarChart()
+ self.chart.title = 'TITLE'
+ self.chart.add_serie(Serie(Reference(ws, (0, 0), (10, 0))))
+ self.chart._series[-1].color = Color.GREEN
+ self.cw = ChartWriter(self.chart)
+ self.root = Element('test')
+
+ def test_write_title(self):
+ self.cw._write_title(self.root)
+ eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:title><c:tx><c:rich><a:bodyPr /><a:lstStyle /><a:p><a:pPr><a:defRPr /></a:pPr><a:r><a:rPr lang="fr-FR" /><a:t>TITLE</a:t></a:r></a:p></c:rich></c:tx><c:layout /></c:title></test>')
+
+ def test_write_xaxis(self):
+
+ self.cw._write_axis(self.root, self.chart.x_axis, 'c:catAx')
+ eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:catAx><c:axId val="60871424" /><c:scaling><c:orientation val="minMax" /></c:scaling><c:axPos val="b" /><c:tickLblPos val="nextTo" /><c:crossAx val="60873344" /><c:crosses val="autoZero" /><c:auto val="1" /><c:lblAlgn val="ctr" /><c:lblOffset val="100" /></c:catAx></test>')
+
+ def test_write_yaxis(self):
+
+ self.cw._write_axis(self.root, self.chart.y_axis, 'c:valAx')
+ eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:valAx><c:axId val="60873344" /><c:scaling><c:orientation val="minMax" /><c:max val="10.0" /><c:min val="0" /></c:scaling><c:axPos val="l" /><c:majorGridlines /><c:numFmt formatCode="General" sourceLinked="1" /><c:tickLblPos val="nextTo" /><c:crossAx val="60871424" /><c:crosses val="autoZero" /><c:crossBetween val="between" /><c:majorUnit val="2.0" /></c:valAx></test>')
+
+ def test_write_series(self):
+
+ self.cw._write_series(self.root)
+ eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:ser><c:idx val="0" /><c:order val="0" /><c:spPr><a:solidFill><a:srgbClr val="00FF00" /></a:solidFill><a:ln><a:solidFill><a:srgbClr val="00FF00" /></a:solidFill></a:ln></c:spPr><c:marker><c:symbol val="none" /></c:marker><c:val><c:numRef><c:f>data!$A$1:$A$11</c:f><c:numCache><c:formatCode>General</c:formatCode><c:ptCount val="11" /><c:pt idx="0"><c:v>0</c:v></c:pt><c:pt idx="1"><c:v>1</c:v></c:pt><c:pt idx="2"><c:v>2</c:v></c:pt><c:pt idx="3"><c:v>3</c:v></c:pt><c:pt idx="4"><c:v>4</c:v></c:pt><c:pt idx="5"><c:v>5</c:v></c:pt><c:pt idx="6"><c:v>6</c:v></c:pt><c:pt idx="7"><c:v>7</c:v></c:pt><c:pt idx="8"><c:v>8</c:v></c:pt><c:pt idx="9"><c:v>9</c:v></c:pt><c:pt idx="10"><c:v>None</c:v></c:pt></c:numCache></c:numRef></c:val></c:ser></test>')
+
+ def test_write_legend(self):
+
+ self.cw._write_legend(self.root)
+ eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:legend><c:legendPos val="r" /><c:layout /></c:legend></test>')
+
+ def test_write_print_settings(self):
+
+ self.cw._write_print_settings(self.root)
+ eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:printSettings><c:headerFooter /><c:pageMargins b="0.75" footer="0.3" header="0.3" l="0.7" r="0.7" t="0.75" /><c:pageSetup /></c:printSettings></test>')
+
+ def test_write_chart(self):
+
+ self.cw._write_chart(self.root)
+ eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:chart><c:title><c:tx><c:rich><a:bodyPr /><a:lstStyle /><a:p><a:pPr><a:defRPr /></a:pPr><a:r><a:rPr lang="fr-FR" /><a:t>TITLE</a:t></a:r></a:p></c:rich></c:tx><c:layout /></c:title><c:plotArea><c:layout><c:manualLayout><c:layoutTarget val="inner" /><c:xMode val="edge" /><c:yMode val="edge" /><c:x val="1.28571428571" /><c:y val="0.2125" /><c:w val="0.6" /><c:h val="0.6" /></c:manualLayout></c:layout><c:barChart><c:barDir val="col" /><c:grouping val="clustered" /><c:ser><c:idx val="0" /><c:order val="0" /><c:spPr><a:solidFill><a:srgbClr val="00FF00" /></a:solidFill><a:ln><a:solidFill><a:srgbClr val="00FF00" /></a:solidFill></a:ln></c:spPr><c:marker><c:symbol val="none" /></c:marker><c:val><c:numRef><c:f>data!$A$1:$A$11</c:f><c:numCache><c:formatCode>General</c:formatCode><c:ptCount val="11" /><c:pt idx="0"><c:v>0</c:v></c:pt><c:pt idx="1"><c:v>1</c:v></c:pt><c:pt idx="2"><c:v>2</c:v></c:pt><c:pt idx="3"><c:v>3</c:v></c:pt><c:pt idx="4"><c:v>4</c:v></c:pt><c:pt idx="5"><c:v>5</c:v></c:pt><c:pt idx="6"><c:v>6</c:v></c:pt><c:pt idx="7"><c:v>7</c:v></c:pt><c:pt idx="8"><c:v>8</c:v></c:pt><c:pt idx="9"><c:v>9</c:v></c:pt><c:pt idx="10"><c:v>None</c:v></c:pt></c:numCache></c:numRef></c:val></c:ser><c:marker val="1" /><c:axId val="60871424" /><c:axId val="60873344" /></c:barChart><c:catAx><c:axId val="60871424" /><c:scaling><c:orientation val="minMax" /></c:scaling><c:axPos val="b" /><c:tickLblPos val="nextTo" /><c:crossAx val="60873344" /><c:crosses val="autoZero" /><c:auto val="1" /><c:lblAlgn val="ctr" /><c:lblOffset val="100" /></c:catAx><c:valAx><c:axId val="60873344" /><c:scaling><c:orientation val="minMax" /><c:max val="10.0" /><c:min val="0" /></c:scaling><c:axPos val="l" /><c:majorGridlines /><c:numFmt formatCode="General" sourceLinked="1" /><c:tickLblPos val="nextTo" /><c:crossAx val="60871424" /><c:crosses val="autoZero" /><c:crossBetween val="between" /><c:majorUnit val="2.0" /></c:valAx></c:plotArea><c:legend><c:legendPos val="r" /><c:layout /></c:legend><c:plotVisOnly val="1" /></c:chart></test>')
+
+
+class TestScatterChartWriter(object):
+
+ def setUp(self):
+
+ wb = Workbook()
+ ws = wb.get_active_sheet()
+ ws.title = 'data'
+ for i in range(10):
+ ws.cell(row = i, column = 0).value = i
+ ws.cell(row = i, column = 1).value = i
+ self.scatterchart = ScatterChart()
+ self.scatterchart.add_serie(Serie(Reference(ws, (0, 0), (10, 0)),
+ xvalues = Reference(ws, (0, 1), (10, 1))))
+ self.cw = ChartWriter(self.scatterchart)
+ self.root = Element('test')
+
+ def test_write_xaxis(self):
+
+ self.cw._write_axis(self.root, self.scatterchart.x_axis, 'c:valAx')
+ eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:valAx><c:axId val="60871424" /><c:scaling><c:orientation val="minMax" /><c:max val="10.0" /><c:min val="0" /></c:scaling><c:axPos val="b" /><c:majorGridlines /><c:numFmt formatCode="General" sourceLinked="1" /><c:tickLblPos val="nextTo" /><c:crossAx val="60873344" /><c:crosses val="autoZero" /><c:auto val="1" /><c:lblAlgn val="ctr" /><c:lblOffset val="100" /><c:crossBetween val="midCat" /><c:majorUnit val="2.0" /></c:valAx></test>')
+
+
+ def test_write_yaxis(self):
+
+ self.cw._write_axis(self.root, self.scatterchart.y_axis, 'c:valAx')
+ eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:valAx><c:axId val="60873344" /><c:scaling><c:orientation val="minMax" /><c:max val="10.0" /><c:min val="0" /></c:scaling><c:axPos val="l" /><c:majorGridlines /><c:numFmt formatCode="General" sourceLinked="1" /><c:tickLblPos val="nextTo" /><c:crossAx val="60871424" /><c:crosses val="autoZero" /><c:crossBetween val="midCat" /><c:majorUnit val="2.0" /></c:valAx></test>')
+
+ def test_write_series(self):
+
+ self.cw._write_series(self.root)
+ eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:ser><c:idx val="0" /><c:order val="0" /><c:marker><c:symbol val="none" /></c:marker><c:xVal><c:numRef><c:f>data!$B$1:$B$11</c:f><c:numCache><c:formatCode>General</c:formatCode><c:ptCount val="11" /><c:pt idx="0"><c:v>0</c:v></c:pt><c:pt idx="1"><c:v>1</c:v></c:pt><c:pt idx="2"><c:v>2</c:v></c:pt><c:pt idx="3"><c:v>3</c:v></c:pt><c:pt idx="4"><c:v>4</c:v></c:pt><c:pt idx="5"><c:v>5</c:v></c:pt><c:pt idx="6"><c:v>6</c:v></c:pt><c:pt idx="7"><c:v>7</c:v></c:pt><c:pt idx="8"><c:v>8</c:v></c:pt><c:pt idx="9"><c:v>9</c:v></c:pt><c:pt idx="10"><c:v>None</c:v></c:pt></c:numCache></c:numRef></c:xVal><c:yVal><c:numRef><c:f>data!$A$1:$A$11</c:f><c:numCache><c:formatCode>General</c:formatCode><c:ptCount val="11" /><c:pt idx="0"><c:v>0</c:v></c:pt><c:pt idx="1"><c:v>1</c:v></c:pt><c:pt idx="2"><c:v>2</c:v></c:pt><c:pt idx="3"><c:v>3</c:v></c:pt><c:pt idx="4"><c:v>4</c:v></c:pt><c:pt idx="5"><c:v>5</c:v></c:pt><c:pt idx="6"><c:v>6</c:v></c:pt><c:pt idx="7"><c:v>7</c:v></c:pt><c:pt idx="8"><c:v>8</c:v></c:pt><c:pt idx="9"><c:v>9</c:v></c:pt><c:pt idx="10"><c:v>None</c:v></c:pt></c:numCache></c:numRef></c:yVal></c:ser></test>')
+
+ def test_write_legend(self):
+
+ self.cw._write_legend(self.root)
+ eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:legend><c:legendPos val="r" /><c:layout /></c:legend></test>')
+
+ def test_write_print_settings(self):
+
+ self.cw._write_print_settings(self.root)
+ eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:printSettings><c:headerFooter /><c:pageMargins b="0.75" footer="0.3" header="0.3" l="0.7" r="0.7" t="0.75" /><c:pageSetup /></c:printSettings></test>')
+
+ def test_write_chart(self):
+
+ self.cw._write_chart(self.root)
+ eq_(get_xml(self.root), '<?xml version=\'1.0\' encoding=\'UTF-8\'?><test><c:chart><c:plotArea><c:layout><c:manualLayout><c:layoutTarget val="inner" /><c:xMode val="edge" /><c:yMode val="edge" /><c:x val="1.28571428571" /><c:y val="0.2125" /><c:w val="0.6" /><c:h val="0.6" /></c:manualLayout></c:layout><c:scatterChart><c:scatterStyle val="lineMarker" /><c:ser><c:idx val="0" /><c:order val="0" /><c:marker><c:symbol val="none" /></c:marker><c:xVal><c:numRef><c:f>data!$B$1:$B$11</c:f><c:numCache><c:formatCode>General</c:formatCode><c:ptCount val="11" /><c:pt idx="0"><c:v>0</c:v></c:pt><c:pt idx="1"><c:v>1</c:v></c:pt><c:pt idx="2"><c:v>2</c:v></c:pt><c:pt idx="3"><c:v>3</c:v></c:pt><c:pt idx="4"><c:v>4</c:v></c:pt><c:pt idx="5"><c:v>5</c:v></c:pt><c:pt idx="6"><c:v>6</c:v></c:pt><c:pt idx="7"><c:v>7</c:v></c:pt><c:pt idx="8"><c:v>8</c:v></c:pt><c:pt idx="9"><c:v>9</c:v></c:pt><c:pt idx="10"><c:v>None</c:v></c:pt></c:numCache></c:numRef></c:xVal><c:yVal><c:numRef><c:f>data!$A$1:$A$11</c:f><c:numCache><c:formatCode>General</c:formatCode><c:ptCount val="11" /><c:pt idx="0"><c:v>0</c:v></c:pt><c:pt idx="1"><c:v>1</c:v></c:pt><c:pt idx="2"><c:v>2</c:v></c:pt><c:pt idx="3"><c:v>3</c:v></c:pt><c:pt idx="4"><c:v>4</c:v></c:pt><c:pt idx="5"><c:v>5</c:v></c:pt><c:pt idx="6"><c:v>6</c:v></c:pt><c:pt idx="7"><c:v>7</c:v></c:pt><c:pt idx="8"><c:v>8</c:v></c:pt><c:pt idx="9"><c:v>9</c:v></c:pt><c:pt idx="10"><c:v>None</c:v></c:pt></c:numCache></c:numRef></c:yVal></c:ser><c:marker val="1" /><c:axId val="60871424" /><c:axId val="60873344" /></c:scatterChart><c:valAx><c:axId val="60871424" /><c:scaling><c:orientation val="minMax" /><c:max val="10.0" /><c:min val="0" /></c:scaling><c:axPos val="b" /><c:majorGridlines /><c:numFmt formatCode="General" sourceLinked="1" /><c:tickLblPos val="nextTo" /><c:crossAx val="60873344" /><c:crosses val="autoZero" /><c:auto val="1" /><c:lblAlgn val="ctr" /><c:lblOffset val="100" /><c:crossBetween val="midCat" /><c:majorUnit val="2.0" /></c:valAx><c:valAx><c:axId val="60873344" /><c:scaling><c:orientation val="minMax" /><c:max val="10.0" /><c:min val="0" /></c:scaling><c:axPos val="l" /><c:majorGridlines /><c:numFmt formatCode="General" sourceLinked="1" /><c:tickLblPos val="nextTo" /><c:crossAx val="60871424" /><c:crosses val="autoZero" /><c:crossBetween val="midCat" /><c:majorUnit val="2.0" /></c:valAx></c:plotArea><c:legend><c:legendPos val="r" /><c:layout /></c:legend><c:plotVisOnly val="1" /></c:chart></test>')
diff --git a/tablib/packages/openpyxl3/tests/test_iter.py b/tablib/packages/openpyxl3/tests/test_iter.py
index b34ab95..899f8d7 100644
--- a/tablib/packages/openpyxl3/tests/test_iter.py
+++ b/tablib/packages/openpyxl3/tests/test_iter.py
@@ -1,112 +1,112 @@
-# file openpyxl/tests/test_iter.py
-
-# Copyright (c) 2010 openpyxl
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-#
-# @license: http://www.opensource.org/licenses/mit-license.php
-# @author: Eric Gazoni
-
-from nose.tools import eq_, raises, assert_raises
-import os.path as osp
-from openpyxl.tests.helper import DATADIR
-from openpyxl.reader.iter_worksheet import get_range_boundaries
-from openpyxl.reader.excel import load_workbook
-import datetime
-
-class TestWorksheet(object):
-
- workbook_name = osp.join(DATADIR, 'genuine', 'empty.xlsx')
-
-class TestText(TestWorksheet):
- sheet_name = 'Sheet1 - Text'
-
- expected = [['This is cell A1 in Sheet 1', None, None, None, None, None, None],
- [None, None, None, None, None, None, None],
- [None, None, None, None, None, None, None],
- [None, None, None, None, None, None, None],
- [None, None, None, None, None, None, 'This is cell G5'], ]
-
- def test_read_fast_integrated(self):
-
- wb = load_workbook(filename = self.workbook_name, use_iterators = True)
- ws = wb.get_sheet_by_name(name = self.sheet_name)
-
- for row, expected_row in zip(ws.iter_rows(), self.expected):
-
- row_values = [x.internal_value for x in row]
-
- eq_(row_values, expected_row)
-
-
- def test_get_boundaries_range(self):
-
- eq_(get_range_boundaries('C1:C4'), (3, 1, 3, 4))
-
- def test_get_boundaries_one(self):
-
-
- eq_(get_range_boundaries('C1'), (3, 1, 4, 1))
-
- def test_read_single_cell_range(self):
-
- wb = load_workbook(filename = self.workbook_name, use_iterators = True)
- ws = wb.get_sheet_by_name(name = self.sheet_name)
-
- eq_('This is cell A1 in Sheet 1', list(ws.iter_rows('A1'))[0][0].internal_value)
-
-class TestIntegers(TestWorksheet):
-
- sheet_name = 'Sheet2 - Numbers'
-
- expected = [[x + 1] for x in range(30)]
-
- query_range = 'D1:E30'
-
- def test_read_fast_integrated(self):
-
- wb = load_workbook(filename = self.workbook_name, use_iterators = True)
- ws = wb.get_sheet_by_name(name = self.sheet_name)
-
- for row, expected_row in zip(ws.iter_rows(self.query_range), self.expected):
-
- row_values = [x.internal_value for x in row]
-
- eq_(row_values, expected_row)
-
-class TestFloats(TestWorksheet):
-
- sheet_name = 'Sheet2 - Numbers'
- query_range = 'K1:L30'
- expected = expected = [[(x + 1) / 100.0] for x in range(30)]
-
-class TestDates(TestWorksheet):
-
- sheet_name = 'Sheet4 - Dates'
-
- def test_read_single_cell_date(self):
-
- wb = load_workbook(filename = self.workbook_name, use_iterators = True)
- ws = wb.get_sheet_by_name(name = self.sheet_name)
-
- eq_(datetime.datetime(1973, 5, 20), list(ws.iter_rows('A1'))[0][0].internal_value)
- eq_(datetime.datetime(1973, 5, 20, 9, 15, 2), list(ws.iter_rows('C1'))[0][0].internal_value)
-
-
-
+# file openpyxl/tests/test_iter.py
+
+# Copyright (c) 2010 openpyxl
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# @license: http://www.opensource.org/licenses/mit-license.php
+# @author: Eric Gazoni
+
+from nose.tools import eq_, raises, assert_raises
+import os.path as osp
+from openpyxl.tests.helper import DATADIR
+from openpyxl.reader.iter_worksheet import get_range_boundaries
+from openpyxl.reader.excel import load_workbook
+import datetime
+
+class TestWorksheet(object):
+
+ workbook_name = osp.join(DATADIR, 'genuine', 'empty.xlsx')
+
+class TestText(TestWorksheet):
+ sheet_name = 'Sheet1 - Text'
+
+ expected = [['This is cell A1 in Sheet 1', None, None, None, None, None, None],
+ [None, None, None, None, None, None, None],
+ [None, None, None, None, None, None, None],
+ [None, None, None, None, None, None, None],
+ [None, None, None, None, None, None, 'This is cell G5'], ]
+
+ def test_read_fast_integrated(self):
+
+ wb = load_workbook(filename = self.workbook_name, use_iterators = True)
+ ws = wb.get_sheet_by_name(name = self.sheet_name)
+
+ for row, expected_row in zip(ws.iter_rows(), self.expected):
+
+ row_values = [x.internal_value for x in row]
+
+ eq_(row_values, expected_row)
+
+
+ def test_get_boundaries_range(self):
+
+ eq_(get_range_boundaries('C1:C4'), (3, 1, 3, 4))
+
+ def test_get_boundaries_one(self):
+
+
+ eq_(get_range_boundaries('C1'), (3, 1, 4, 1))
+
+ def test_read_single_cell_range(self):
+
+ wb = load_workbook(filename = self.workbook_name, use_iterators = True)
+ ws = wb.get_sheet_by_name(name = self.sheet_name)
+
+ eq_('This is cell A1 in Sheet 1', list(ws.iter_rows('A1'))[0][0].internal_value)
+
+class TestIntegers(TestWorksheet):
+
+ sheet_name = 'Sheet2 - Numbers'
+
+ expected = [[x + 1] for x in range(30)]
+
+ query_range = 'D1:E30'
+
+ def test_read_fast_integrated(self):
+
+ wb = load_workbook(filename = self.workbook_name, use_iterators = True)
+ ws = wb.get_sheet_by_name(name = self.sheet_name)
+
+ for row, expected_row in zip(ws.iter_rows(self.query_range), self.expected):
+
+ row_values = [x.internal_value for x in row]
+
+ eq_(row_values, expected_row)
+
+class TestFloats(TestWorksheet):
+
+ sheet_name = 'Sheet2 - Numbers'
+ query_range = 'K1:L30'
+ expected = expected = [[(x + 1) / 100.0] for x in range(30)]
+
+class TestDates(TestWorksheet):
+
+ sheet_name = 'Sheet4 - Dates'
+
+ def test_read_single_cell_date(self):
+
+ wb = load_workbook(filename = self.workbook_name, use_iterators = True)
+ ws = wb.get_sheet_by_name(name = self.sheet_name)
+
+ eq_(datetime.datetime(1973, 5, 20), list(ws.iter_rows('A1'))[0][0].internal_value)
+ eq_(datetime.datetime(1973, 5, 20, 9, 15, 2), list(ws.iter_rows('C1'))[0][0].internal_value)
+
+
+
diff --git a/tablib/packages/openpyxl3/tests/test_meta.py b/tablib/packages/openpyxl3/tests/test_meta.py
index 3aefdcf..06051ad 100644
--- a/tablib/packages/openpyxl3/tests/test_meta.py
+++ b/tablib/packages/openpyxl3/tests/test_meta.py
@@ -24,7 +24,7 @@
# @author: Eric Gazoni
# Python stdlib imports
-from __future__ import with_statement
+
import os.path
# package imports
diff --git a/tablib/packages/openpyxl3/tests/test_named_range.py b/tablib/packages/openpyxl3/tests/test_named_range.py
index a56ed86..c6d9d58 100644
--- a/tablib/packages/openpyxl3/tests/test_named_range.py
+++ b/tablib/packages/openpyxl3/tests/test_named_range.py
@@ -24,7 +24,7 @@
# @author: Eric Gazoni
# Python stdlib imports
-from __future__ import with_statement
+
import os.path
# 3rd-party imports
diff --git a/tablib/packages/openpyxl3/tests/test_number_format.py b/tablib/packages/openpyxl3/tests/test_number_format.py
index 2f5c9da..54b0b88 100644
--- a/tablib/packages/openpyxl3/tests/test_number_format.py
+++ b/tablib/packages/openpyxl3/tests/test_number_format.py
@@ -24,7 +24,7 @@
# @author: Eric Gazoni
# Python stdlib imports
-from __future__ import with_statement
+
from datetime import datetime, date
# 3rd party imports
@@ -57,7 +57,7 @@ class TestNumberFormat(object):
date_pairs= (
(40167, datetime(2009, 12, 20)),
- (21980, datetime(1960, 03, 05)),
+ (21980, datetime(1960, 0o3, 0o5)),
)
for count, dt in date_pairs:
@@ -128,7 +128,7 @@ class TestNumberFormat(object):
def check_bad_date(year, month, day):
assert_raises(ValueError, self.sd.to_julian, year, month, day)
- bad_dates = ((1776, 07, 04), (1899, 12, 31), )
+ bad_dates = ((1776, 0o7, 0o4), (1899, 12, 31), )
for year, month, day in bad_dates:
yield check_bad_date, year, month, day
diff --git a/tablib/packages/openpyxl3/tests/test_props.py b/tablib/packages/openpyxl3/tests/test_props.py
index 1c5adb6..07d447c 100644
--- a/tablib/packages/openpyxl3/tests/test_props.py
+++ b/tablib/packages/openpyxl3/tests/test_props.py
Binary files differ
diff --git a/tablib/packages/openpyxl3/tests/test_read.py b/tablib/packages/openpyxl3/tests/test_read.py
index eb6ab07..1240164 100644
--- a/tablib/packages/openpyxl3/tests/test_read.py
+++ b/tablib/packages/openpyxl3/tests/test_read.py
@@ -24,7 +24,7 @@
# @author: Eric Gazoni
# Python stdlib imports
-from __future__ import with_statement
+
import os.path
# 3rd party imports
diff --git a/tablib/packages/openpyxl3/tests/test_strings.py b/tablib/packages/openpyxl3/tests/test_strings.py
index bf3cc57..7dbf17a 100644
--- a/tablib/packages/openpyxl3/tests/test_strings.py
+++ b/tablib/packages/openpyxl3/tests/test_strings.py
@@ -24,7 +24,7 @@
# @author: Eric Gazoni
# Python stdlib imports
-from __future__ import with_statement
+
import os.path
# 3rd party imports
diff --git a/tablib/packages/openpyxl3/tests/test_style.py b/tablib/packages/openpyxl3/tests/test_style.py
index a11ea43..4c8962c 100644
--- a/tablib/packages/openpyxl3/tests/test_style.py
+++ b/tablib/packages/openpyxl3/tests/test_style.py
@@ -24,7 +24,7 @@
# @author: Eric Gazoni
# Python stdlib imports
-from __future__ import with_statement
+
import os.path
import datetime
diff --git a/tablib/packages/openpyxl3/tests/test_write.py b/tablib/packages/openpyxl3/tests/test_write.py
index 51e3c15..74363cb 100644
--- a/tablib/packages/openpyxl3/tests/test_write.py
+++ b/tablib/packages/openpyxl3/tests/test_write.py
@@ -24,8 +24,8 @@
# @author: Eric Gazoni
# Python stdlib imports
-from __future__ import with_statement
-from io import BytesIO as StringIO
+
+from io import StringIO
import os.path
# 3rd party imports
diff --git a/tablib/packages/openpyxl3/worksheet.py b/tablib/packages/openpyxl3/worksheet.py
index 2eb6499..6cdda6b 100644
--- a/tablib/packages/openpyxl3/worksheet.py
+++ b/tablib/packages/openpyxl3/worksheet.py
@@ -187,7 +187,7 @@ class Worksheet(object):
"""Represents a worksheet.
Do not create worksheets yourself,
- use :func:`openpyxl.workbook.Workbook.create_sheet` instead
+ use :func:`.workbook.Workbook.create_sheet` instead
"""
BREAK_NONE = 0
@@ -241,7 +241,7 @@ class Worksheet(object):
def get_cell_collection(self):
"""Return an unordered list of the cells in this worksheet."""
- return self._cells.values()
+ return list(self._cells.values())
def _set_title(self, value):
"""Set a sheet title, ensuring it is valid."""
@@ -325,7 +325,7 @@ class Worksheet(object):
:raise: InsufficientCoordinatesException when coordinate or (row and column) are not given
- :rtype: :class:`openpyxl.cell.Cell`
+ :rtype: :class:`.cell.Cell`
"""
if not coordinate:
@@ -390,7 +390,7 @@ class Worksheet(object):
:param column: number of columns to offset
:type column: int
- :rtype: tuples of tuples of :class:`openpyxl.cell.Cell`
+ :rtype: tuples of tuples of :class:`.cell.Cell`
"""
if ':' in range_string:
diff --git a/tablib/packages/openpyxl3/writer/charts.py b/tablib/packages/openpyxl3/writer/charts.py
index c0dfadb..420328d 100644
--- a/tablib/packages/openpyxl3/writer/charts.py
+++ b/tablib/packages/openpyxl3/writer/charts.py
@@ -1,261 +1,262 @@
-# coding=UTF-8
-'''
-Copyright (c) 2010 openpyxl
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-@license: http://www.opensource.org/licenses/mit-license.php
-@author: Eric Gazoni
-'''
-
-from ..shared.xmltools import Element, SubElement, get_document_content
-from ..chart import Chart, ErrorBar
-
-class ChartWriter(object):
-
- def __init__(self, chart):
- self.chart = chart
-
- def write(self):
- """ write a chart """
-
- root = Element('c:chartSpace',
- {'xmlns:c':"http://schemas.openxmlformats.org/drawingml/2006/chart",
- 'xmlns:a':"http://schemas.openxmlformats.org/drawingml/2006/main",
- 'xmlns:r':"http://schemas.openxmlformats.org/officeDocument/2006/relationships"})
-
- SubElement(root, 'c:lang', {'val':self.chart.lang})
- self._write_chart(root)
- self._write_print_settings(root)
- self._write_shapes(root)
-
- return get_document_content(root)
-
- def _write_chart(self, root):
-
- chart = self.chart
-
- ch = SubElement(root, 'c:chart')
- self._write_title(ch)
- plot_area = SubElement(ch, 'c:plotArea')
- layout = SubElement(plot_area, 'c:layout')
- mlayout = SubElement(layout, 'c:manualLayout')
- SubElement(mlayout, 'c:layoutTarget', {'val':'inner'})
- SubElement(mlayout, 'c:xMode', {'val':'edge'})
- SubElement(mlayout, 'c:yMode', {'val':'edge'})
- SubElement(mlayout, 'c:x', {'val':str(chart._get_margin_left())})
- SubElement(mlayout, 'c:y', {'val':str(chart._get_margin_top())})
- SubElement(mlayout, 'c:w', {'val':str(chart.width)})
- SubElement(mlayout, 'c:h', {'val':str(chart.height)})
-
- if chart.type == Chart.SCATTER_CHART:
- subchart = SubElement(plot_area, 'c:scatterChart')
- SubElement(subchart, 'c:scatterStyle', {'val':str('lineMarker')})
- else:
- if chart.type == Chart.BAR_CHART:
- subchart = SubElement(plot_area, 'c:barChart')
- SubElement(subchart, 'c:barDir', {'val':'col'})
- else:
- subchart = SubElement(plot_area, 'c:lineChart')
-
- SubElement(subchart, 'c:grouping', {'val':chart.grouping})
-
- self._write_series(subchart)
-
- SubElement(subchart, 'c:marker', {'val':'1'})
- SubElement(subchart, 'c:axId', {'val':str(chart.x_axis.id)})
- SubElement(subchart, 'c:axId', {'val':str(chart.y_axis.id)})
-
- if chart.type == Chart.SCATTER_CHART:
- self._write_axis(plot_area, chart.x_axis, 'c:valAx')
- else:
- self._write_axis(plot_area, chart.x_axis, 'c:catAx')
- self._write_axis(plot_area, chart.y_axis, 'c:valAx')
-
- self._write_legend(ch)
-
- SubElement(ch, 'c:plotVisOnly', {'val':'1'})
-
- def _write_title(self, chart):
- if self.chart.title != '':
- title = SubElement(chart, 'c:title')
- tx = SubElement(title, 'c:tx')
- rich = SubElement(tx, 'c:rich')
- SubElement(rich, 'a:bodyPr')
- SubElement(rich, 'a:lstStyle')
- p = SubElement(rich, 'a:p')
- pPr = SubElement(p, 'a:pPr')
- SubElement(pPr, 'a:defRPr')
- r = SubElement(p, 'a:r')
- SubElement(r, 'a:rPr', {'lang':self.chart.lang})
- t = SubElement(r, 'a:t').text = self.chart.title
- SubElement(title, 'c:layout')
-
- def _write_axis(self, plot_area, axis, label):
-
- ax = SubElement(plot_area, label)
- SubElement(ax, 'c:axId', {'val':str(axis.id)})
-
- scaling = SubElement(ax, 'c:scaling')
- SubElement(scaling, 'c:orientation', {'val':axis.orientation})
- if label == 'c:valAx':
- SubElement(scaling, 'c:max', {'val':str(axis.max)})
- SubElement(scaling, 'c:min', {'val':str(axis.min)})
-
- SubElement(ax, 'c:axPos', {'val':axis.position})
- if label == 'c:valAx':
- SubElement(ax, 'c:majorGridlines')
- SubElement(ax, 'c:numFmt', {'formatCode':"General", 'sourceLinked':'1'})
- SubElement(ax, 'c:tickLblPos', {'val':axis.tick_label_position})
- SubElement(ax, 'c:crossAx', {'val':str(axis.cross)})
- SubElement(ax, 'c:crosses', {'val':axis.crosses})
- if axis.auto:
- SubElement(ax, 'c:auto', {'val':'1'})
- if axis.label_align:
- SubElement(ax, 'c:lblAlgn', {'val':axis.label_align})
- if axis.label_offset:
- SubElement(ax, 'c:lblOffset', {'val':str(axis.label_offset)})
- if label == 'c:valAx':
- if self.chart.type == Chart.SCATTER_CHART:
- SubElement(ax, 'c:crossBetween', {'val':'midCat'})
- else:
- SubElement(ax, 'c:crossBetween', {'val':'between'})
- SubElement(ax, 'c:majorUnit', {'val':str(axis.unit)})
-
- def _write_series(self, subchart):
-
- for i, serie in enumerate(self.chart._series):
- ser = SubElement(subchart, 'c:ser')
- SubElement(ser, 'c:idx', {'val':str(i)})
- SubElement(ser, 'c:order', {'val':str(i)})
-
- if serie.legend:
- tx = SubElement(ser, 'c:tx')
- self._write_serial(tx, serie.legend)
-
- if serie.color:
- sppr = SubElement(ser, 'c:spPr')
- if self.chart.type == Chart.BAR_CHART:
- # fill color
- fillc = SubElement(sppr, 'a:solidFill')
- SubElement(fillc, 'a:srgbClr', {'val':serie.color})
- # edge color
- ln = SubElement(sppr, 'a:ln')
- fill = SubElement(ln, 'a:solidFill')
- SubElement(fill, 'a:srgbClr', {'val':serie.color})
-
- if serie.error_bar:
- self._write_error_bar(ser, serie)
-
- marker = SubElement(ser, 'c:marker')
- SubElement(marker, 'c:symbol', {'val':serie.marker})
-
- if serie.labels:
- cat = SubElement(ser, 'c:cat')
- self._write_serial(cat, serie.labels)
-
- if self.chart.type == Chart.SCATTER_CHART:
- if serie.xvalues:
- xval = SubElement(ser, 'c:xVal')
- self._write_serial(xval, serie.xvalues)
-
- yval = SubElement(ser, 'c:yVal')
- self._write_serial(yval, serie.values)
- else:
- val = SubElement(ser, 'c:val')
- self._write_serial(val, serie.values)
-
- def _write_serial(self, node, serie, literal=False):
-
- cache = serie._get_cache()
- if isinstance(cache[0], str):
- typ = 'str'
- else:
- typ = 'num'
-
- if not literal:
- if typ == 'num':
- ref = SubElement(node, 'c:numRef')
- else:
- ref = SubElement(node, 'c:strRef')
- SubElement(ref, 'c:f').text = serie._get_ref()
- if typ == 'num':
- data = SubElement(ref, 'c:numCache')
- else:
- data = SubElement(ref, 'c:strCache')
- else:
- data = SubElement(node, 'c:numLit')
-
- if typ == 'num':
- SubElement(data, 'c:formatCode').text = 'General'
- if literal:
- values = (1,)
- else:
- values = cache
-
- SubElement(data, 'c:ptCount', {'val':str(len(values))})
- for j, val in enumerate(values):
- point = SubElement(data, 'c:pt', {'idx':str(j)})
- SubElement(point, 'c:v').text = str(val)
-
- def _write_error_bar(self, node, serie):
-
- flag = {ErrorBar.PLUS_MINUS:'both',
- ErrorBar.PLUS:'plus',
- ErrorBar.MINUS:'minus'}
-
- eb = SubElement(node, 'c:errBars')
- SubElement(eb, 'c:errBarType', {'val':flag[serie.error_bar.type]})
- SubElement(eb, 'c:errValType', {'val':'cust'})
-
- plus = SubElement(eb, 'c:plus')
- self._write_serial(plus, serie.error_bar.values,
- literal=(serie.error_bar.type==ErrorBar.MINUS))
-
- minus = SubElement(eb, 'c:minus')
- self._write_serial(minus, serie.error_bar.values,
- literal=(serie.error_bar.type==ErrorBar.PLUS))
-
- def _write_legend(self, chart):
-
- legend = SubElement(chart, 'c:legend')
- SubElement(legend, 'c:legendPos', {'val':self.chart.legend.position})
- SubElement(legend, 'c:layout')
-
- def _write_print_settings(self, root):
-
- settings = SubElement(root, 'c:printSettings')
- SubElement(settings, 'c:headerFooter')
- margins = dict([(k, str(v)) for (k,v) in self.chart.print_margins.items()])
- SubElement(settings, 'c:pageMargins', margins)
- SubElement(settings, 'c:pageSetup')
-
- def _write_shapes(self, root):
-
- if self.chart._shapes:
- SubElement(root, 'c:userShapes', {'r:id':'rId1'})
-
- def write_rels(self, drawing_id):
-
- root = Element('Relationships', {'xmlns' : 'http://schemas.openxmlformats.org/package/2006/relationships'})
- attrs = {'Id' : 'rId1',
- 'Type' : 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartUserShapes',
- 'Target' : '../drawings/drawing%s.xml' % drawing_id }
- SubElement(root, 'Relationship', attrs)
- return get_document_content(root)
+# coding=UTF-8
+'''
+Copyright (c) 2010 openpyxl
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+@license: http://www.opensource.org/licenses/mit-license.php
+@author: Eric Gazoni
+'''
+
+from ..shared.xmltools import Element, SubElement, get_document_content
+from ..chart import Chart, ErrorBar
+
+
+class ChartWriter(object):
+
+ def __init__(self, chart):
+ self.chart = chart
+
+ def write(self):
+ """ write a chart """
+
+ root = Element('c:chartSpace',
+ {'xmlns:c':"http://schemas.openxmlformats.org/drawingml/2006/chart",
+ 'xmlns:a':"http://schemas.openxmlformats.org/drawingml/2006/main",
+ 'xmlns:r':"http://schemas.openxmlformats.org/officeDocument/2006/relationships"})
+
+ SubElement(root, 'c:lang', {'val':self.chart.lang})
+ self._write_chart(root)
+ self._write_print_settings(root)
+ self._write_shapes(root)
+
+ return get_document_content(root)
+
+ def _write_chart(self, root):
+
+ chart = self.chart
+
+ ch = SubElement(root, 'c:chart')
+ self._write_title(ch)
+ plot_area = SubElement(ch, 'c:plotArea')
+ layout = SubElement(plot_area, 'c:layout')
+ mlayout = SubElement(layout, 'c:manualLayout')
+ SubElement(mlayout, 'c:layoutTarget', {'val':'inner'})
+ SubElement(mlayout, 'c:xMode', {'val':'edge'})
+ SubElement(mlayout, 'c:yMode', {'val':'edge'})
+ SubElement(mlayout, 'c:x', {'val':str(chart._get_margin_left())})
+ SubElement(mlayout, 'c:y', {'val':str(chart._get_margin_top())})
+ SubElement(mlayout, 'c:w', {'val':str(chart.width)})
+ SubElement(mlayout, 'c:h', {'val':str(chart.height)})
+
+ if chart.type == Chart.SCATTER_CHART:
+ subchart = SubElement(plot_area, 'c:scatterChart')
+ SubElement(subchart, 'c:scatterStyle', {'val':str('lineMarker')})
+ else:
+ if chart.type == Chart.BAR_CHART:
+ subchart = SubElement(plot_area, 'c:barChart')
+ SubElement(subchart, 'c:barDir', {'val':'col'})
+ else:
+ subchart = SubElement(plot_area, 'c:lineChart')
+
+ SubElement(subchart, 'c:grouping', {'val':chart.grouping})
+
+ self._write_series(subchart)
+
+ SubElement(subchart, 'c:marker', {'val':'1'})
+ SubElement(subchart, 'c:axId', {'val':str(chart.x_axis.id)})
+ SubElement(subchart, 'c:axId', {'val':str(chart.y_axis.id)})
+
+ if chart.type == Chart.SCATTER_CHART:
+ self._write_axis(plot_area, chart.x_axis, 'c:valAx')
+ else:
+ self._write_axis(plot_area, chart.x_axis, 'c:catAx')
+ self._write_axis(plot_area, chart.y_axis, 'c:valAx')
+
+ self._write_legend(ch)
+
+ SubElement(ch, 'c:plotVisOnly', {'val':'1'})
+
+ def _write_title(self, chart):
+ if self.chart.title != '':
+ title = SubElement(chart, 'c:title')
+ tx = SubElement(title, 'c:tx')
+ rich = SubElement(tx, 'c:rich')
+ SubElement(rich, 'a:bodyPr')
+ SubElement(rich, 'a:lstStyle')
+ p = SubElement(rich, 'a:p')
+ pPr = SubElement(p, 'a:pPr')
+ SubElement(pPr, 'a:defRPr')
+ r = SubElement(p, 'a:r')
+ SubElement(r, 'a:rPr', {'lang':self.chart.lang})
+ t = SubElement(r, 'a:t').text = self.chart.title
+ SubElement(title, 'c:layout')
+
+ def _write_axis(self, plot_area, axis, label):
+
+ ax = SubElement(plot_area, label)
+ SubElement(ax, 'c:axId', {'val':str(axis.id)})
+
+ scaling = SubElement(ax, 'c:scaling')
+ SubElement(scaling, 'c:orientation', {'val':axis.orientation})
+ if label == 'c:valAx':
+ SubElement(scaling, 'c:max', {'val':str(axis.max)})
+ SubElement(scaling, 'c:min', {'val':str(axis.min)})
+
+ SubElement(ax, 'c:axPos', {'val':axis.position})
+ if label == 'c:valAx':
+ SubElement(ax, 'c:majorGridlines')
+ SubElement(ax, 'c:numFmt', {'formatCode':"General", 'sourceLinked':'1'})
+ SubElement(ax, 'c:tickLblPos', {'val':axis.tick_label_position})
+ SubElement(ax, 'c:crossAx', {'val':str(axis.cross)})
+ SubElement(ax, 'c:crosses', {'val':axis.crosses})
+ if axis.auto:
+ SubElement(ax, 'c:auto', {'val':'1'})
+ if axis.label_align:
+ SubElement(ax, 'c:lblAlgn', {'val':axis.label_align})
+ if axis.label_offset:
+ SubElement(ax, 'c:lblOffset', {'val':str(axis.label_offset)})
+ if label == 'c:valAx':
+ if self.chart.type == Chart.SCATTER_CHART:
+ SubElement(ax, 'c:crossBetween', {'val':'midCat'})
+ else:
+ SubElement(ax, 'c:crossBetween', {'val':'between'})
+ SubElement(ax, 'c:majorUnit', {'val':str(axis.unit)})
+
+ def _write_series(self, subchart):
+
+ for i, serie in enumerate(self.chart._series):
+ ser = SubElement(subchart, 'c:ser')
+ SubElement(ser, 'c:idx', {'val':str(i)})
+ SubElement(ser, 'c:order', {'val':str(i)})
+
+ if serie.legend:
+ tx = SubElement(ser, 'c:tx')
+ self._write_serial(tx, serie.legend)
+
+ if serie.color:
+ sppr = SubElement(ser, 'c:spPr')
+ if self.chart.type == Chart.BAR_CHART:
+ # fill color
+ fillc = SubElement(sppr, 'a:solidFill')
+ SubElement(fillc, 'a:srgbClr', {'val':serie.color})
+ # edge color
+ ln = SubElement(sppr, 'a:ln')
+ fill = SubElement(ln, 'a:solidFill')
+ SubElement(fill, 'a:srgbClr', {'val':serie.color})
+
+ if serie.error_bar:
+ self._write_error_bar(ser, serie)
+
+ marker = SubElement(ser, 'c:marker')
+ SubElement(marker, 'c:symbol', {'val':serie.marker})
+
+ if serie.labels:
+ cat = SubElement(ser, 'c:cat')
+ self._write_serial(cat, serie.labels)
+
+ if self.chart.type == Chart.SCATTER_CHART:
+ if serie.xvalues:
+ xval = SubElement(ser, 'c:xVal')
+ self._write_serial(xval, serie.xvalues)
+
+ yval = SubElement(ser, 'c:yVal')
+ self._write_serial(yval, serie.values)
+ else:
+ val = SubElement(ser, 'c:val')
+ self._write_serial(val, serie.values)
+
+ def _write_serial(self, node, serie, literal=False):
+
+ cache = serie._get_cache()
+ if isinstance(cache[0], str):
+ typ = 'str'
+ else:
+ typ = 'num'
+
+ if not literal:
+ if typ == 'num':
+ ref = SubElement(node, 'c:numRef')
+ else:
+ ref = SubElement(node, 'c:strRef')
+ SubElement(ref, 'c:f').text = serie._get_ref()
+ if typ == 'num':
+ data = SubElement(ref, 'c:numCache')
+ else:
+ data = SubElement(ref, 'c:strCache')
+ else:
+ data = SubElement(node, 'c:numLit')
+
+ if typ == 'num':
+ SubElement(data, 'c:formatCode').text = 'General'
+ if literal:
+ values = (1,)
+ else:
+ values = cache
+
+ SubElement(data, 'c:ptCount', {'val':str(len(values))})
+ for j, val in enumerate(values):
+ point = SubElement(data, 'c:pt', {'idx':str(j)})
+ SubElement(point, 'c:v').text = str(val)
+
+ def _write_error_bar(self, node, serie):
+
+ flag = {ErrorBar.PLUS_MINUS:'both',
+ ErrorBar.PLUS:'plus',
+ ErrorBar.MINUS:'minus'}
+
+ eb = SubElement(node, 'c:errBars')
+ SubElement(eb, 'c:errBarType', {'val':flag[serie.error_bar.type]})
+ SubElement(eb, 'c:errValType', {'val':'cust'})
+
+ plus = SubElement(eb, 'c:plus')
+ self._write_serial(plus, serie.error_bar.values,
+ literal=(serie.error_bar.type==ErrorBar.MINUS))
+
+ minus = SubElement(eb, 'c:minus')
+ self._write_serial(minus, serie.error_bar.values,
+ literal=(serie.error_bar.type==ErrorBar.PLUS))
+
+ def _write_legend(self, chart):
+
+ legend = SubElement(chart, 'c:legend')
+ SubElement(legend, 'c:legendPos', {'val':self.chart.legend.position})
+ SubElement(legend, 'c:layout')
+
+ def _write_print_settings(self, root):
+
+ settings = SubElement(root, 'c:printSettings')
+ SubElement(settings, 'c:headerFooter')
+ margins = dict([(k, str(v)) for (k,v) in self.chart.print_margins.items()])
+ SubElement(settings, 'c:pageMargins', margins)
+ SubElement(settings, 'c:pageSetup')
+
+ def _write_shapes(self, root):
+
+ if self.chart._shapes:
+ SubElement(root, 'c:userShapes', {'r:id':'rId1'})
+
+ def write_rels(self, drawing_id):
+
+ root = Element('Relationships', {'xmlns' : 'http://schemas.openxmlformats.org/package/2006/relationships'})
+ attrs = {'Id' : 'rId1',
+ 'Type' : 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartUserShapes',
+ 'Target' : '../drawings/drawing%s.xml' % drawing_id }
+ SubElement(root, 'Relationship', attrs)
+ return get_document_content(root)
diff --git a/tablib/packages/openpyxl3/writer/dump_worksheet.py b/tablib/packages/openpyxl3/writer/dump_worksheet.py
index 521cae0..36d68d4 100644
--- a/tablib/packages/openpyxl3/writer/dump_worksheet.py
+++ b/tablib/packages/openpyxl3/writer/dump_worksheet.py
@@ -66,7 +66,7 @@ class DumpWorksheet(Worksheet):
"""
.. warning::
- You shouldn't initialize this yourself, use :class:`openpyxl.workbook.Workbook` constructor instead,
+ You shouldn't initialize this yourself, use :class:`..workbook.Workbook` constructor instead,
with `optimized_write = True`.
"""
@@ -77,9 +77,9 @@ class DumpWorksheet(Worksheet):
self._max_col = 0
self._max_row = 0
self._parent = parent_workbook
- self._fileobj_header = NamedTemporaryFile(mode='r+', prefix='openpyxl.', suffix='.header', delete=False)
- self._fileobj_content = NamedTemporaryFile(mode='r+', prefix='openpyxl.', suffix='.content', delete=False)
- self._fileobj = NamedTemporaryFile(mode='w', prefix='openpyxl.', delete=False)
+ self._fileobj_header = NamedTemporaryFile(mode='r+', prefix='..', suffix='.header', delete=False)
+ self._fileobj_content = NamedTemporaryFile(mode='r+', prefix='..', suffix='.content', delete=False)
+ self._fileobj = NamedTemporaryFile(mode='w', prefix='..', delete=False)
self.doc = XMLGenerator(self._fileobj_content, 'utf-8')
self.header = XMLGenerator(self._fileobj_header, 'utf-8')
self.title = 'Sheet'
diff --git a/tablib/packages/openpyxl3/writer/excel.py b/tablib/packages/openpyxl3/writer/excel.py
index f09746f..a19666d 100644
--- a/tablib/packages/openpyxl3/writer/excel.py
+++ b/tablib/packages/openpyxl3/writer/excel.py
@@ -27,22 +27,22 @@
# Python stdlib imports
from zipfile import ZipFile, ZIP_DEFLATED
-from io import BytesIO as StringIO
+from io import StringIO
# package imports
from ..shared.ooxml import ARC_SHARED_STRINGS, ARC_CONTENT_TYPES, \
ARC_ROOT_RELS, ARC_WORKBOOK_RELS, ARC_APP, ARC_CORE, ARC_THEME, \
ARC_STYLE, ARC_WORKBOOK, \
PACKAGE_WORKSHEETS, PACKAGE_DRAWINGS, PACKAGE_CHARTS
-from ..writer.strings import create_string_table, write_string_table
-from ..writer.workbook import write_content_types, write_root_rels, \
+from .strings import create_string_table, write_string_table
+from .workbook import write_content_types, write_root_rels, \
write_workbook_rels, write_properties_app, write_properties_core, \
write_workbook
-from ..writer.theme import write_theme
-from ..writer.styles import StyleWriter
-from ..writer.drawings import DrawingWriter, ShapeWriter
-from ..writer.charts import ChartWriter
-from ..writer.worksheet import write_worksheet, write_worksheet_rels
+from .theme import write_theme
+from .styles import StyleWriter
+from .drawings import DrawingWriter, ShapeWriter
+from .charts import ChartWriter
+from .worksheet import write_worksheet, write_worksheet_rels
class ExcelWriter(object):
diff --git a/tablib/packages/openpyxl3/writer/strings.py b/tablib/packages/openpyxl3/writer/strings.py
index f3e882e..706c2b6 100644
--- a/tablib/packages/openpyxl3/writer/strings.py
+++ b/tablib/packages/openpyxl3/writer/strings.py
@@ -26,7 +26,7 @@
"""Write the shared string table."""
# Python stdlib imports
-from io import BytesIO as StringIO
+from io import StringIO
# package imports
from ..shared.xmltools import start_tag, end_tag, tag, XMLGenerator
@@ -49,7 +49,7 @@ def write_string_table(string_table):
start_tag(doc, 'sst', {'xmlns':
'http://schemas.openxmlformats.org/spreadsheetml/2006/main',
'uniqueCount': '%d' % len(string_table)})
- strings_to_write = sorted(string_table.items(),
+ strings_to_write = sorted(iter(string_table.items()),
key=lambda pair: pair[1])
for key in [pair[0] for pair in strings_to_write]:
start_tag(doc, 'si')
diff --git a/tablib/packages/openpyxl3/writer/styles.py b/tablib/packages/openpyxl3/writer/styles.py
index 7e3fb64..3d73382 100644
--- a/tablib/packages/openpyxl3/writer/styles.py
+++ b/tablib/packages/openpyxl3/writer/styles.py
@@ -40,11 +40,11 @@ class StyleWriter(object):
def _get_style_list(self, workbook):
crc = {}
for worksheet in workbook.worksheets:
- for style in worksheet._styles.values():
+ for style in list(worksheet._styles.values()):
crc[hash(style)] = style
self.style_table = dict([(style, i+1) \
- for i, style in enumerate(crc.values())])
- sorted_styles = sorted(self.style_table.items(), \
+ for i, style in enumerate(list(crc.values()))])
+ sorted_styles = sorted(iter(self.style_table.items()), \
key = lambda pair:pair[1])
return [s[0] for s in sorted_styles]
diff --git a/tablib/packages/openpyxl3/writer/worksheet.py b/tablib/packages/openpyxl3/writer/worksheet.py
index b7633f8..21d9e9b 100644
--- a/tablib/packages/openpyxl3/writer/worksheet.py
+++ b/tablib/packages/openpyxl3/writer/worksheet.py
@@ -26,7 +26,7 @@
"""Write worksheets to xml representations."""
# Python stdlib imports
-from io import BytesIO as StringIO # cStringIO doesn't handle unicode
+from io import StringIO # cStringIO doesn't handle unicode
# package imports
from ..cell import coordinate_from_string, column_index_from_string