mirror of
https://github.com/kennethreitz/tablib.git
synced 2026-06-05 15:00:19 +00:00
Convert openpyxl to relative imports
This commit is contained in:
@@ -26,14 +26,14 @@
|
||||
"""Imports for the openpyxl package."""
|
||||
|
||||
# package imports
|
||||
from openpyxl import cell
|
||||
from openpyxl import namedrange
|
||||
from openpyxl import style
|
||||
from openpyxl import workbook
|
||||
from openpyxl import worksheet
|
||||
from openpyxl import reader
|
||||
from openpyxl import shared
|
||||
from openpyxl import writer
|
||||
from . import cell
|
||||
from . import namedrange
|
||||
from . import style
|
||||
from . import workbook
|
||||
from . import worksheet
|
||||
from . import reader
|
||||
from . import shared
|
||||
from . import writer
|
||||
|
||||
# constants
|
||||
|
||||
|
||||
@@ -38,10 +38,10 @@ import datetime
|
||||
import re
|
||||
|
||||
# package imports
|
||||
from openpyxl.shared.date_time import SharedDate
|
||||
from openpyxl.shared.exc import CellCoordinatesException, \
|
||||
from .shared.date_time import SharedDate
|
||||
from .shared.exc import CellCoordinatesException, \
|
||||
ColumnStringIndexException, DataTypeException
|
||||
from openpyxl.style import NumberFormat
|
||||
from .style import NumberFormat
|
||||
|
||||
# constants
|
||||
COORD_RE = re.compile('^[$]?([A-Z]+)[$]?(\d+)$')
|
||||
@@ -70,12 +70,12 @@ def absolute_coordinate(coord_string):
|
||||
|
||||
def column_index_from_string(column, fast = False):
|
||||
"""Convert a column letter into a column number (e.g. B -> 2)
|
||||
|
||||
|
||||
Excel only supports 1-3 letter column names from A -> ZZZ, so we
|
||||
restrict our column names to 1-3 characters, each in the range A-Z.
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
|
||||
Fast mode is faster but does not check that all letters are capitals between A and Z
|
||||
|
||||
"""
|
||||
@@ -349,7 +349,7 @@ class Cell(object):
|
||||
:rtype: string
|
||||
"""
|
||||
return '%s%s' % (self.column, self.row)
|
||||
|
||||
|
||||
@property
|
||||
def address(self):
|
||||
"""Return the coordinate string for this cell (e.g. 'B12')
|
||||
@@ -376,7 +376,7 @@ class Cell(object):
|
||||
|
||||
def is_date(self):
|
||||
"""Returns whether the value is *probably* a date or not
|
||||
|
||||
|
||||
:rtype: bool
|
||||
"""
|
||||
return (self.has_style
|
||||
|
||||
@@ -25,20 +25,20 @@ THE SOFTWARE.
|
||||
|
||||
import math
|
||||
|
||||
from openpyxl.style import NumberFormat
|
||||
from openpyxl.drawing import Drawing, Shape
|
||||
from openpyxl.shared.units import pixels_to_EMU, short_color
|
||||
from openpyxl.cell import get_column_letter
|
||||
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',
|
||||
@@ -47,11 +47,11 @@ class Axis(object):
|
||||
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
|
||||
@@ -62,11 +62,11 @@ class Axis(object):
|
||||
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
|
||||
@@ -82,7 +82,7 @@ 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
|
||||
@@ -93,10 +93,10 @@ class Reference(object):
|
||||
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,
|
||||
@@ -104,11 +104,11 @@ class Reference(object):
|
||||
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):
|
||||
@@ -118,15 +118,15 @@ class Reference(object):
|
||||
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
|
||||
@@ -134,13 +134,13 @@ class Serie(object):
|
||||
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):
|
||||
@@ -152,43 +152,43 @@ class Serie(object):
|
||||
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
|
||||
@@ -198,46 +198,46 @@ class Chart(object):
|
||||
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)))
|
||||
|
||||
@@ -265,14 +265,14 @@ class Chart(object):
|
||||
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 """
|
||||
|
||||
@@ -297,44 +297,44 @@ class Chart(object):
|
||||
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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -24,11 +24,11 @@ THE SOFTWARE.
|
||||
'''
|
||||
|
||||
import math
|
||||
from openpyxl.style import Color
|
||||
from openpyxl.shared.units import pixels_to_EMU, EMU_to_pixels, short_color
|
||||
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'
|
||||
@@ -46,17 +46,17 @@ class Shadow(object):
|
||||
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
|
||||
""" 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))
|
||||
@@ -67,38 +67,38 @@ class Drawing(object):
|
||||
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)
|
||||
@@ -106,28 +106,28 @@ class Drawing(object):
|
||||
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"
|
||||
@@ -317,9 +317,9 @@ class Shape(object):
|
||||
"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
|
||||
@@ -328,47 +328,47 @@ class Shape(object):
|
||||
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
|
||||
@@ -376,27 +376,26 @@ class Shape(object):
|
||||
|
||||
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),
|
||||
|
||||
return (_norm_pct(x_start), _norm_pct(y_start),
|
||||
_norm_pct(x_end), _norm_pct(y_end))
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
import re
|
||||
|
||||
# package imports
|
||||
from openpyxl.shared.exc import NamedRangeException
|
||||
from .shared.exc import NamedRangeException
|
||||
|
||||
# constants
|
||||
NAMED_RANGE_RE = re.compile("'?([^']*)'?!((\$([A-Za-z]+))?\$([0-9]+)(:(\$([A-Za-z]+))?(\$([0-9]+)))?)$")
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
"""Imports for the openpyxl.reader namespace."""
|
||||
|
||||
# package imports
|
||||
from openpyxl.reader import excel
|
||||
from openpyxl.reader import strings
|
||||
from openpyxl.reader import style
|
||||
from openpyxl.reader import workbook
|
||||
from openpyxl.reader import worksheet
|
||||
from ..reader import excel
|
||||
from ..reader import strings
|
||||
from ..reader import style
|
||||
from ..reader import workbook
|
||||
from ..reader import worksheet
|
||||
|
||||
@@ -29,32 +29,32 @@
|
||||
from zipfile import ZipFile, ZIP_DEFLATED, BadZipfile
|
||||
|
||||
# package imports
|
||||
from openpyxl.shared.exc import OpenModeError, InvalidFileException
|
||||
from openpyxl.shared.ooxml import ARC_SHARED_STRINGS, ARC_CORE, ARC_APP, \
|
||||
from ..shared.exc import OpenModeError, InvalidFileException
|
||||
from ..shared.ooxml import ARC_SHARED_STRINGS, ARC_CORE, ARC_APP, \
|
||||
ARC_WORKBOOK, PACKAGE_WORKSHEETS, ARC_STYLE
|
||||
from openpyxl.workbook import Workbook
|
||||
from openpyxl.reader.strings import read_string_table
|
||||
from openpyxl.reader.style import read_style_table
|
||||
from openpyxl.reader.workbook import read_sheets_titles, read_named_ranges, \
|
||||
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, \
|
||||
read_properties_core, get_sheet_ids
|
||||
from openpyxl.reader.worksheet import read_worksheet
|
||||
from openpyxl.reader.iter_worksheet import unpack_worksheet
|
||||
from ..reader.worksheet import read_worksheet
|
||||
from ..reader.iter_worksheet import unpack_worksheet
|
||||
|
||||
def load_workbook(filename, use_iterators = False):
|
||||
"""Open the given filename and return the workbook
|
||||
|
||||
:param filename: the path to open
|
||||
:type filename: string
|
||||
|
||||
|
||||
:param use_iterators: use lazy load for cells
|
||||
:type use_iterators: bool
|
||||
|
||||
:rtype: :class:`openpyxl.workbook.Workbook`
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
|
||||
When using lazy load, all worksheets will be :class:`openpyxl.reader.iter_worksheet.IterableWorksheet`
|
||||
and the returned workbook will be read-only.
|
||||
and the returned workbook will be read-only.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
# @license: http://www.opensource.org/licenses/mit-license.php
|
||||
# @author: Eric Gazoni
|
||||
|
||||
""" Iterators-based worksheet reader
|
||||
""" Iterators-based worksheet reader
|
||||
*Still very raw*
|
||||
"""
|
||||
|
||||
@@ -32,18 +32,18 @@ import warnings
|
||||
import operator
|
||||
from functools import partial
|
||||
from itertools import ifilter, groupby
|
||||
from openpyxl.worksheet import Worksheet
|
||||
from openpyxl.cell import coordinate_from_string, get_column_letter, Cell
|
||||
from openpyxl.reader.excel import get_sheet_ids
|
||||
from openpyxl.reader.strings import read_string_table
|
||||
from openpyxl.reader.style import read_style_table, NumberFormat
|
||||
from openpyxl.shared.date_time import SharedDate
|
||||
from openpyxl.reader.worksheet import read_dimension
|
||||
from openpyxl.shared.ooxml import (MIN_COLUMN, MAX_COLUMN, PACKAGE_WORKSHEETS,
|
||||
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
|
||||
import openpyxl.cell
|
||||
from .. import cell
|
||||
import re
|
||||
import tempfile
|
||||
import zlib
|
||||
@@ -51,7 +51,7 @@ import zipfile
|
||||
import struct
|
||||
|
||||
TYPE_NULL = Cell.TYPE_NULL
|
||||
MISSING_VALUE = None
|
||||
MISSING_VALUE = None
|
||||
|
||||
RE_COORDINATE = re.compile('^([A-Z]+)([0-9]+)$')
|
||||
|
||||
@@ -108,11 +108,11 @@ class RawCell(BaseRawCell):
|
||||
def is_date(self):
|
||||
res = (self.data_type == Cell.TYPE_NUMERIC
|
||||
and self.number_format is not None
|
||||
and ('d' in self.number_format
|
||||
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
|
||||
or 's' in self.number_format
|
||||
))
|
||||
|
||||
return res
|
||||
@@ -121,7 +121,7 @@ def iter_rows(workbook_name, sheet_name, xml_source, range_string = '', row_offs
|
||||
|
||||
archive = get_archive_file(workbook_name)
|
||||
|
||||
source = xml_source
|
||||
source = xml_source
|
||||
|
||||
if range_string:
|
||||
min_col, min_row, max_col, max_row = get_range_boundaries(range_string, row_offset, column_offset)
|
||||
@@ -187,7 +187,7 @@ def get_range_boundaries(range_string, row = 0, column = 0):
|
||||
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
|
||||
max_row = min_row
|
||||
|
||||
return (min_col, min_row, max_col, max_row)
|
||||
|
||||
@@ -215,7 +215,7 @@ def get_squared_range(p, min_col, min_row, max_col, max_row, string_table, style
|
||||
for gap_row in xrange(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
|
||||
@@ -254,11 +254,11 @@ def get_squared_range(p, min_col, min_row, max_col, max_row, string_table, style
|
||||
|
||||
yield tuple(full_row)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
class IterableWorksheet(Worksheet):
|
||||
|
||||
def __init__(self, parent_workbook, title, workbook_name,
|
||||
def __init__(self, parent_workbook, title, workbook_name,
|
||||
sheet_codename, xml_source):
|
||||
|
||||
Worksheet.__init__(self, parent_workbook, title)
|
||||
@@ -267,20 +267,20 @@ class IterableWorksheet(Worksheet):
|
||||
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,
|
||||
""" 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,
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
"""Read the shared strings table."""
|
||||
|
||||
# package imports
|
||||
from openpyxl.shared.xmltools import fromstring, QName
|
||||
from openpyxl.shared.ooxml import NAMESPACES
|
||||
from ..shared.xmltools import fromstring, QName
|
||||
from ..shared.ooxml import NAMESPACES
|
||||
|
||||
|
||||
def read_string_table(xml_source):
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
"""Read shared style definitions"""
|
||||
|
||||
# package imports
|
||||
from openpyxl.shared.xmltools import fromstring, QName
|
||||
from openpyxl.shared.exc import MissingNumberFormat
|
||||
from openpyxl.style import Style, NumberFormat
|
||||
from ..shared.xmltools import fromstring, QName
|
||||
from ..shared.exc import MissingNumberFormat
|
||||
from ..style import Style, NumberFormat
|
||||
|
||||
|
||||
def read_style_table(xml_source):
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
"""Read in global settings to be maintained by the workbook object."""
|
||||
|
||||
# package imports
|
||||
from openpyxl.shared.xmltools import fromstring, QName
|
||||
from openpyxl.shared.ooxml import NAMESPACES
|
||||
from openpyxl.workbook import DocumentProperties
|
||||
from openpyxl.shared.date_time import W3CDTF_to_datetime
|
||||
from openpyxl.namedrange import NamedRange, split_named_range
|
||||
from ..shared.xmltools import fromstring, QName
|
||||
from ..shared.ooxml import NAMESPACES
|
||||
from ..workbook import DocumentProperties
|
||||
from ..shared.date_time import W3CDTF_to_datetime
|
||||
from ..namedrange import NamedRange, split_named_range
|
||||
|
||||
import datetime
|
||||
|
||||
|
||||
@@ -34,12 +34,12 @@ from itertools import ifilter
|
||||
from StringIO import StringIO
|
||||
|
||||
# package imports
|
||||
from openpyxl.cell import Cell, coordinate_from_string
|
||||
from openpyxl.worksheet import Worksheet
|
||||
from ..cell import Cell, coordinate_from_string
|
||||
from ..worksheet import Worksheet
|
||||
|
||||
def _get_xml_iter(xml_source):
|
||||
|
||||
if not hasattr(xml_source, 'name'):
|
||||
if not hasattr(xml_source, 'name'):
|
||||
return StringIO(xml_source)
|
||||
else:
|
||||
xml_source.seek(0)
|
||||
@@ -47,7 +47,7 @@ def _get_xml_iter(xml_source):
|
||||
|
||||
def read_dimension(xml_source):
|
||||
|
||||
source = _get_xml_iter(xml_source)
|
||||
source = _get_xml_iter(xml_source)
|
||||
|
||||
it = iterparse(source)
|
||||
|
||||
@@ -73,7 +73,7 @@ def filter_cells((event, element)):
|
||||
|
||||
def fast_parse(ws, xml_source, string_table, style_table):
|
||||
|
||||
source = _get_xml_iter(xml_source)
|
||||
source = _get_xml_iter(xml_source)
|
||||
|
||||
it = iterparse(source)
|
||||
|
||||
@@ -98,13 +98,13 @@ def fast_parse(ws, xml_source, string_table, style_table):
|
||||
# to avoid memory exhaustion, clear the item after use
|
||||
element.clear()
|
||||
|
||||
from openpyxl.reader.iter_worksheet import IterableWorksheet
|
||||
from ..reader.iter_worksheet import IterableWorksheet
|
||||
|
||||
def read_worksheet(xml_source, parent, preset_title, string_table,
|
||||
style_table, workbook_name = None, sheet_codename = None):
|
||||
"""Read an xml worksheet"""
|
||||
if workbook_name and sheet_codename:
|
||||
ws = IterableWorksheet(parent, preset_title, workbook_name,
|
||||
ws = IterableWorksheet(parent, preset_title, workbook_name,
|
||||
sheet_codename, xml_source)
|
||||
else:
|
||||
ws = Worksheet(parent, preset_title)
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
"""Imports for the openpyxl.shared namespace."""
|
||||
|
||||
# package imports
|
||||
from openpyxl.shared import date_time
|
||||
from openpyxl.shared import exc
|
||||
from openpyxl.shared import ooxml
|
||||
from openpyxl.shared import password_hasher
|
||||
from openpyxl.shared import xmltools
|
||||
from . import date_time
|
||||
from . import exc
|
||||
from . import ooxml
|
||||
from . import password_hasher
|
||||
from . import xmltools
|
||||
|
||||
@@ -41,7 +41,7 @@ except ImportError:
|
||||
QName, fromstring, tostring
|
||||
|
||||
# package imports
|
||||
from openpyxl import __name__ as prefix
|
||||
from .. import __name__ as prefix
|
||||
|
||||
|
||||
def get_document_content(xml_node):
|
||||
|
||||
@@ -32,13 +32,13 @@ import datetime
|
||||
import os
|
||||
|
||||
# package imports
|
||||
from openpyxl.worksheet import Worksheet
|
||||
from openpyxl.writer.dump_worksheet import DumpWorksheet, save_dump
|
||||
from openpyxl.writer.strings import StringTableBuilder
|
||||
from openpyxl.namedrange import NamedRange
|
||||
from openpyxl.style import Style
|
||||
from openpyxl.writer.excel import save_workbook
|
||||
from openpyxl.shared.exc import ReadOnlyWorkbookException
|
||||
from .worksheet import Worksheet
|
||||
from .writer.dump_worksheet import DumpWorksheet, save_dump
|
||||
from .writer.strings import StringTableBuilder
|
||||
from .namedrange import NamedRange
|
||||
from .style import Style
|
||||
from .writer.excel import save_workbook
|
||||
from .shared.exc import ReadOnlyWorkbookException
|
||||
|
||||
|
||||
class DocumentProperties(object):
|
||||
|
||||
@@ -29,15 +29,15 @@
|
||||
import re
|
||||
|
||||
# package imports
|
||||
import openpyxl.cell
|
||||
from openpyxl.cell import coordinate_from_string, \
|
||||
from . import cell
|
||||
from .cell import coordinate_from_string, \
|
||||
column_index_from_string, get_column_letter
|
||||
from openpyxl.shared.exc import SheetTitleException, \
|
||||
from .shared.exc import SheetTitleException, \
|
||||
InsufficientCoordinatesException, CellCoordinatesException, \
|
||||
NamedRangeException
|
||||
from openpyxl.shared.password_hasher import hash_password
|
||||
from openpyxl.style import Style, DEFAULTS as DEFAULTS_STYLE
|
||||
from openpyxl.drawing import Drawing
|
||||
from .shared.password_hasher import hash_password
|
||||
from .style import Style, DEFAULTS as DEFAULTS_STYLE
|
||||
from .drawing import Drawing
|
||||
|
||||
_DEFAULTS_STYLE_HASH = hash(DEFAULTS_STYLE)
|
||||
|
||||
@@ -344,7 +344,7 @@ class Worksheet(object):
|
||||
|
||||
if not coordinate in self._cells:
|
||||
column, row = coordinate_from_string(coordinate)
|
||||
new_cell = openpyxl.cell.Cell(self, column, row)
|
||||
new_cell = cell.Cell(self, column, row)
|
||||
self._cells[coordinate] = new_cell
|
||||
if column not in self.column_dimensions:
|
||||
self.column_dimensions[column] = ColumnDimension(column)
|
||||
@@ -354,7 +354,7 @@ class Worksheet(object):
|
||||
|
||||
def get_highest_row(self):
|
||||
"""Returns the maximum row index containing data
|
||||
|
||||
|
||||
:rtype: int
|
||||
"""
|
||||
if self.row_dimensions:
|
||||
@@ -364,7 +364,7 @@ class Worksheet(object):
|
||||
|
||||
def get_highest_column(self):
|
||||
"""Get the largest value for column currently stored.
|
||||
|
||||
|
||||
:rtype: int
|
||||
"""
|
||||
if self.column_dimensions:
|
||||
@@ -475,21 +475,21 @@ class Worksheet(object):
|
||||
|
||||
def append(self, list_or_dict):
|
||||
"""Appends a group of values at the bottom of the current sheet.
|
||||
|
||||
|
||||
* If it's a list: all values are added in order, starting from the first column
|
||||
* If it's a dict: values are assigned to the columns indicated by the keys (numbers or letters)
|
||||
|
||||
|
||||
:param list_or_dict: list or dict containing values to append
|
||||
:type list_or_dict: list/tuple or dict
|
||||
|
||||
|
||||
Usage:
|
||||
|
||||
|
||||
* append(['This is A1', 'This is B1', 'This is C1'])
|
||||
* **or** append({'A' : 'This is A1', 'C' : 'This is C1'})
|
||||
* **or** append({0 : 'This is A1', 2 : 'This is C1'})
|
||||
|
||||
|
||||
:raise: TypeError when list_or_dict is neither a list/tuple nor a dict
|
||||
|
||||
|
||||
"""
|
||||
|
||||
row_idx = len(self.row_dimensions)
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
"""Imports for the openpyxl.writer namespace."""
|
||||
|
||||
# package imports
|
||||
from openpyxl.writer import excel
|
||||
from openpyxl.writer import strings
|
||||
from openpyxl.writer import styles
|
||||
from openpyxl.writer import theme
|
||||
from openpyxl.writer import workbook
|
||||
from openpyxl.writer import worksheet
|
||||
from . import excel
|
||||
from . import strings
|
||||
from . import styles
|
||||
from . import theme
|
||||
from . import workbook
|
||||
from . import worksheet
|
||||
|
||||
@@ -24,33 +24,33 @@ THE SOFTWARE.
|
||||
@author: Eric Gazoni
|
||||
'''
|
||||
|
||||
from openpyxl.shared.xmltools import Element, SubElement, get_document_content
|
||||
from openpyxl.chart import Chart, ErrorBar
|
||||
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',
|
||||
|
||||
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')
|
||||
@@ -63,7 +63,7 @@ class ChartWriter(object):
|
||||
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')})
|
||||
@@ -73,23 +73,23 @@ class ChartWriter(object):
|
||||
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):
|
||||
@@ -108,16 +108,16 @@ class ChartWriter(object):
|
||||
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')
|
||||
@@ -137,18 +137,18 @@ class ChartWriter(object):
|
||||
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:
|
||||
@@ -159,17 +159,17 @@ class ChartWriter(object):
|
||||
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')
|
||||
@@ -180,7 +180,7 @@ class ChartWriter(object):
|
||||
else:
|
||||
val = SubElement(ser, 'c:val')
|
||||
self._write_serial(val, serie.values)
|
||||
|
||||
|
||||
def _write_serial(self, node, serie, literal=False):
|
||||
|
||||
cache = serie._get_cache()
|
||||
@@ -188,7 +188,7 @@ class ChartWriter(object):
|
||||
typ = 'str'
|
||||
else:
|
||||
typ = 'num'
|
||||
|
||||
|
||||
if not literal:
|
||||
if typ == 'num':
|
||||
ref = SubElement(node, 'c:numRef')
|
||||
@@ -208,51 +208,51 @@ class ChartWriter(object):
|
||||
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',
|
||||
|
||||
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.iteritems()])
|
||||
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',
|
||||
|
||||
@@ -24,7 +24,7 @@ THE SOFTWARE.
|
||||
@author: Eric Gazoni
|
||||
'''
|
||||
|
||||
from openpyxl.shared.xmltools import Element, SubElement, get_document_content
|
||||
from ..shared.xmltools import Element, SubElement, get_document_content
|
||||
|
||||
|
||||
class DrawingWriter(object):
|
||||
|
||||
@@ -28,19 +28,19 @@
|
||||
import datetime
|
||||
import os
|
||||
|
||||
from openpyxl.cell import column_index_from_string, get_column_letter, Cell
|
||||
from openpyxl.worksheet import Worksheet
|
||||
from openpyxl.shared.xmltools import XMLGenerator, get_document_content, \
|
||||
from ..cell import column_index_from_string, get_column_letter, Cell
|
||||
from ..worksheet import Worksheet
|
||||
from ..shared.xmltools import XMLGenerator, get_document_content, \
|
||||
start_tag, end_tag, tag
|
||||
from openpyxl.shared.date_time import SharedDate
|
||||
from openpyxl.shared.ooxml import MAX_COLUMN, MAX_ROW
|
||||
from ..shared.date_time import SharedDate
|
||||
from ..shared.ooxml import MAX_COLUMN, MAX_ROW
|
||||
from tempfile import NamedTemporaryFile
|
||||
from openpyxl.writer.excel import ExcelWriter
|
||||
from openpyxl.writer.strings import write_string_table
|
||||
from openpyxl.writer.styles import StyleWriter
|
||||
from openpyxl.style import Style, NumberFormat
|
||||
from ..writer.excel import ExcelWriter
|
||||
from ..writer.strings import write_string_table
|
||||
from ..writer.styles import StyleWriter
|
||||
from ..style import Style, NumberFormat
|
||||
|
||||
from openpyxl.shared.ooxml import ARC_SHARED_STRINGS, ARC_CONTENT_TYPES, \
|
||||
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
|
||||
@@ -58,7 +58,7 @@ STYLES = {'datetime' : {'type':Cell.TYPE_NUMERIC,
|
||||
}
|
||||
|
||||
DATETIME_STYLE = Style()
|
||||
DATETIME_STYLE.number_format.format_code = NumberFormat.FORMAT_DATE_YYYYMMDD2
|
||||
DATETIME_STYLE.number_format.format_code = NumberFormat.FORMAT_DATE_YYYYMMDD2
|
||||
BOUNDING_BOX_PLACEHOLDER = 'A1:%s%d' % (get_column_letter(MAX_COLUMN), MAX_ROW)
|
||||
|
||||
class DumpWorksheet(Worksheet):
|
||||
@@ -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:`openpyxl.workbook.Workbook` constructor instead,
|
||||
with `optimized_write = True`.
|
||||
"""
|
||||
|
||||
@@ -101,7 +101,7 @@ class DumpWorksheet(Worksheet):
|
||||
'xmlns:r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'})
|
||||
start_tag(doc, 'sheetPr')
|
||||
tag(doc, 'outlinePr',
|
||||
{'summaryBelow': '1',
|
||||
{'summaryBelow': '1',
|
||||
'summaryRight': '1'})
|
||||
end_tag(doc, 'sheetPr')
|
||||
tag(doc, 'dimension', {'ref': 'A1:%s' % (self.get_dimensions())})
|
||||
@@ -141,7 +141,7 @@ class DumpWorksheet(Worksheet):
|
||||
self._fileobj.flush()
|
||||
|
||||
def _close_header(self):
|
||||
|
||||
|
||||
doc = self.header
|
||||
#doc.endDocument()
|
||||
|
||||
@@ -159,7 +159,7 @@ class DumpWorksheet(Worksheet):
|
||||
return 'A1'
|
||||
else:
|
||||
return '%s%d' % (get_column_letter(self._max_col), (self._max_row))
|
||||
|
||||
|
||||
def append(self, row):
|
||||
|
||||
"""
|
||||
@@ -185,7 +185,7 @@ class DumpWorksheet(Worksheet):
|
||||
if cell is None:
|
||||
continue
|
||||
|
||||
coordinate = '%s%d' % (get_column_letter(col_idx+1), row_idx)
|
||||
coordinate = '%s%d' % (get_column_letter(col_idx+1), row_idx)
|
||||
attributes = {'r': coordinate}
|
||||
|
||||
if isinstance(cell, bool):
|
||||
@@ -211,7 +211,7 @@ class DumpWorksheet(Worksheet):
|
||||
tag(doc, 'v')
|
||||
else:
|
||||
tag(doc, 'v', body = '%s' % cell)
|
||||
|
||||
|
||||
end_tag(doc, 'c')
|
||||
|
||||
|
||||
@@ -253,4 +253,4 @@ class StyleDumpWriter(StyleWriter):
|
||||
|
||||
def _get_style_list(self, workbook):
|
||||
return []
|
||||
|
||||
|
||||
|
||||
@@ -30,19 +30,19 @@ from zipfile import ZipFile, ZIP_DEFLATED
|
||||
from StringIO import StringIO
|
||||
|
||||
# package imports
|
||||
from openpyxl.shared.ooxml import ARC_SHARED_STRINGS, ARC_CONTENT_TYPES, \
|
||||
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 openpyxl.writer.strings import create_string_table, write_string_table
|
||||
from openpyxl.writer.workbook import write_content_types, write_root_rels, \
|
||||
from ..writer.strings import create_string_table, write_string_table
|
||||
from ..writer.workbook import write_content_types, write_root_rels, \
|
||||
write_workbook_rels, write_properties_app, write_properties_core, \
|
||||
write_workbook
|
||||
from openpyxl.writer.theme import write_theme
|
||||
from openpyxl.writer.styles import StyleWriter
|
||||
from openpyxl.writer.drawings import DrawingWriter, ShapeWriter
|
||||
from openpyxl.writer.charts import ChartWriter
|
||||
from openpyxl.writer.worksheet import write_worksheet, write_worksheet_rels
|
||||
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
|
||||
|
||||
|
||||
class ExcelWriter(object):
|
||||
@@ -56,7 +56,7 @@ class ExcelWriter(object):
|
||||
"""Write the various xml files into the zip archive."""
|
||||
# cleanup all worksheets
|
||||
shared_string_table = self._write_string_table(archive)
|
||||
|
||||
|
||||
archive.writestr(ARC_CONTENT_TYPES, write_content_types(self.workbook))
|
||||
archive.writestr(ARC_ROOT_RELS, write_root_rels(self.workbook))
|
||||
archive.writestr(ARC_WORKBOOK_RELS, write_workbook_rels(self.workbook))
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
from StringIO import StringIO
|
||||
|
||||
# package imports
|
||||
from openpyxl.shared.xmltools import start_tag, end_tag, tag, XMLGenerator
|
||||
from ..shared.xmltools import start_tag, end_tag, tag, XMLGenerator
|
||||
|
||||
|
||||
def create_string_table(workbook):
|
||||
|
||||
@@ -26,17 +26,17 @@
|
||||
"""Write the shared style table."""
|
||||
|
||||
# package imports
|
||||
from openpyxl.shared.xmltools import Element, SubElement
|
||||
from openpyxl.shared.xmltools import get_document_content
|
||||
from openpyxl import style
|
||||
from ..shared.xmltools import Element, SubElement
|
||||
from ..shared.xmltools import get_document_content
|
||||
from .. import style
|
||||
|
||||
class StyleWriter(object):
|
||||
|
||||
|
||||
def __init__(self, workbook):
|
||||
self._style_list = self._get_style_list(workbook)
|
||||
self._root = Element('styleSheet',
|
||||
self._root = Element('styleSheet',
|
||||
{'xmlns':'http://schemas.openxmlformats.org/spreadsheetml/2006/main'})
|
||||
|
||||
|
||||
def _get_style_list(self, workbook):
|
||||
crc = {}
|
||||
for worksheet in workbook.worksheets:
|
||||
@@ -51,7 +51,7 @@ class StyleWriter(object):
|
||||
def get_style_by_hash(self):
|
||||
return dict([(hash(style), id) \
|
||||
for style, id in self.style_table.iteritems()])
|
||||
|
||||
|
||||
def write_table(self):
|
||||
number_format_table = self._write_number_formats()
|
||||
fonts_table = self._write_fonts()
|
||||
@@ -71,7 +71,7 @@ class StyleWriter(object):
|
||||
"""
|
||||
|
||||
fonts = SubElement(self._root, 'fonts')
|
||||
|
||||
|
||||
# default
|
||||
font_node = SubElement(fonts, 'font')
|
||||
SubElement(font_node, 'sz', {'val':'11'})
|
||||
@@ -79,7 +79,7 @@ class StyleWriter(object):
|
||||
SubElement(font_node, 'name', {'val':'Calibri'})
|
||||
SubElement(font_node, 'family', {'val':'2'})
|
||||
SubElement(font_node, 'scheme', {'val':'minor'})
|
||||
|
||||
|
||||
# others
|
||||
table = {}
|
||||
index = 1
|
||||
@@ -97,7 +97,7 @@ class StyleWriter(object):
|
||||
if st.font.italic:
|
||||
SubElement(font_node, 'i')
|
||||
index += 1
|
||||
|
||||
|
||||
fonts.attrib["count"] = str(index)
|
||||
return table
|
||||
|
||||
@@ -122,7 +122,7 @@ class StyleWriter(object):
|
||||
if hash(st.fill.end_color) != hash(style.DEFAULTS.fill.end_color):
|
||||
SubElement(node, 'bgColor', {'rgb':str(st.fill.start_color.index)})
|
||||
index += 1
|
||||
|
||||
|
||||
fills.attrib["count"] = str(index)
|
||||
return table
|
||||
|
||||
@@ -136,7 +136,7 @@ class StyleWriter(object):
|
||||
SubElement(border, 'top')
|
||||
SubElement(border, 'bottom')
|
||||
SubElement(border, 'diagonal')
|
||||
|
||||
|
||||
# others
|
||||
table = {}
|
||||
index = 1
|
||||
@@ -150,40 +150,40 @@ class StyleWriter(object):
|
||||
node = SubElement(border, side, {'style':obj.border_style})
|
||||
SubElement(node, 'color', {'rgb':str(obj.color.index)})
|
||||
index += 1
|
||||
|
||||
|
||||
borders.attrib["count"] = str(index)
|
||||
return table
|
||||
|
||||
def _write_cell_style_xfs(self):
|
||||
cell_style_xfs = SubElement(self._root, 'cellStyleXfs', {'count':'1'})
|
||||
xf = SubElement(cell_style_xfs, 'xf',
|
||||
xf = SubElement(cell_style_xfs, 'xf',
|
||||
{'numFmtId':"0", 'fontId':"0", 'fillId':"0", 'borderId':"0"})
|
||||
|
||||
|
||||
def _write_cell_xfs(self, number_format_table, fonts_table, fills_table, borders_table):
|
||||
""" write styles combinations based on ids found in tables """
|
||||
|
||||
|
||||
# writing the cellXfs
|
||||
cell_xfs = SubElement(self._root, 'cellXfs',
|
||||
cell_xfs = SubElement(self._root, 'cellXfs',
|
||||
{'count':'%d' % (len(self._style_list) + 1)})
|
||||
|
||||
|
||||
# default
|
||||
def _get_default_vals():
|
||||
return dict(numFmtId='0', fontId='0', fillId='0',
|
||||
return dict(numFmtId='0', fontId='0', fillId='0',
|
||||
xfId='0', borderId='0')
|
||||
|
||||
|
||||
SubElement(cell_xfs, 'xf', _get_default_vals())
|
||||
|
||||
|
||||
for st in self._style_list:
|
||||
vals = _get_default_vals()
|
||||
|
||||
|
||||
if hash(st.font) != hash(style.DEFAULTS.font):
|
||||
vals['fontId'] = fonts_table[hash(st.font)]
|
||||
vals['applyFont'] = '1'
|
||||
|
||||
|
||||
if hash(st.borders) != hash(style.DEFAULTS.borders):
|
||||
vals['borderId'] = borders_table[hash(st.borders)]
|
||||
vals['applyBorder'] = '1'
|
||||
|
||||
|
||||
if hash(st.fill) != hash(style.DEFAULTS.fill):
|
||||
vals['fillId'] = fills_table[hash(st.fill)]
|
||||
vals['applyFillId'] = '1'
|
||||
@@ -191,7 +191,7 @@ class StyleWriter(object):
|
||||
if st.number_format != style.DEFAULTS.number_format:
|
||||
vals['numFmtId'] = '%d' % number_format_table[st.number_format]
|
||||
vals['applyNumberFormat'] = '1'
|
||||
|
||||
|
||||
if hash(st.alignment) != hash(style.DEFAULTS.alignment):
|
||||
vals['applyAlignment'] = '1'
|
||||
|
||||
@@ -209,7 +209,7 @@ class StyleWriter(object):
|
||||
|
||||
def _write_cell_style(self):
|
||||
cell_styles = SubElement(self._root, 'cellStyles', {'count':'1'})
|
||||
cell_style = SubElement(cell_styles, 'cellStyle',
|
||||
cell_style = SubElement(cell_styles, 'cellStyle',
|
||||
{'name':"Normal", 'xfId':"0", 'builtinId':"0"})
|
||||
|
||||
def _write_dxfs(self):
|
||||
@@ -217,7 +217,7 @@ class StyleWriter(object):
|
||||
|
||||
def _write_table_styles(self):
|
||||
|
||||
table_styles = SubElement(self._root, 'tableStyles',
|
||||
table_styles = SubElement(self._root, 'tableStyles',
|
||||
{'count':'0', 'defaultTableStyle':'TableStyleMedium9',
|
||||
'defaultPivotStyle':'PivotStyleLight16'})
|
||||
|
||||
@@ -245,12 +245,12 @@ class StyleWriter(object):
|
||||
num_fmt_offset += 1
|
||||
exceptions_list.append(number_format)
|
||||
|
||||
num_fmts = SubElement(self._root, 'numFmts',
|
||||
num_fmts = SubElement(self._root, 'numFmts',
|
||||
{'count':'%d' % len(exceptions_list)})
|
||||
|
||||
for number_format in exceptions_list :
|
||||
SubElement(num_fmts, 'numFmt',
|
||||
SubElement(num_fmts, 'numFmt',
|
||||
{'numFmtId':'%d' % number_format_table[number_format],
|
||||
'formatCode':'%s' % number_format.format_code})
|
||||
|
||||
'formatCode':'%s' % number_format.format_code})
|
||||
|
||||
return number_format_table
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"""Write the theme xml based on a fixed string."""
|
||||
|
||||
# package imports
|
||||
from openpyxl.shared.xmltools import fromstring, get_document_content
|
||||
from ..shared.xmltools import fromstring, get_document_content
|
||||
|
||||
|
||||
def write_theme():
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
"""Write the workbook global settings to the archive."""
|
||||
|
||||
# package imports
|
||||
from openpyxl.shared.xmltools import Element, SubElement
|
||||
from openpyxl.cell import absolute_coordinate
|
||||
from openpyxl.shared.xmltools import get_document_content
|
||||
from openpyxl.shared.ooxml import NAMESPACES, ARC_CORE, ARC_WORKBOOK, \
|
||||
from ..shared.xmltools import Element, SubElement
|
||||
from ..cell import absolute_coordinate
|
||||
from ..shared.xmltools import get_document_content
|
||||
from ..shared.ooxml import NAMESPACES, ARC_CORE, ARC_WORKBOOK, \
|
||||
ARC_APP, ARC_THEME, ARC_STYLE, ARC_SHARED_STRINGS
|
||||
from openpyxl.shared.date_time import datetime_to_W3CDTF
|
||||
from ..shared.date_time import datetime_to_W3CDTF
|
||||
|
||||
|
||||
def write_properties_core(properties):
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
from StringIO import StringIO # cStringIO doesn't handle unicode
|
||||
|
||||
# package imports
|
||||
from openpyxl.cell import coordinate_from_string, column_index_from_string
|
||||
from openpyxl.shared.xmltools import Element, SubElement, XMLGenerator, \
|
||||
from ..cell import coordinate_from_string, column_index_from_string
|
||||
from ..shared.xmltools import Element, SubElement, XMLGenerator, \
|
||||
get_document_content, start_tag, end_tag, tag
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ def write_worksheet_sheetviews(doc, worksheet):
|
||||
tag(doc, 'selection', selectionAttrs)
|
||||
end_tag(doc, 'sheetView')
|
||||
end_tag(doc, 'sheetViews')
|
||||
|
||||
|
||||
|
||||
def write_worksheet_cols(doc, worksheet):
|
||||
"""Write worksheet columns to xml."""
|
||||
|
||||
Reference in New Issue
Block a user