| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- # Copyright (c) 2010-2024 openpyxl
- from openpyxl.compat import safe_string
- from openpyxl.xml.functions import Element, SubElement, whitespace, XML_NS
- from openpyxl import LXML
- from openpyxl.utils.datetime import to_excel, to_ISO8601
- from datetime import timedelta
- from openpyxl.worksheet.formula import DataTableFormula, ArrayFormula
- from openpyxl.cell.rich_text import CellRichText
- def _set_attributes(cell, styled=None):
- """
- Set coordinate and datatype
- """
- coordinate = cell.coordinate
- attrs = {'r': coordinate}
- if styled:
- attrs['s'] = f"{cell.style_id}"
- if cell.data_type == "s":
- attrs['t'] = "inlineStr"
- elif cell.data_type != 'f':
- attrs['t'] = cell.data_type
- value = cell._value
- if cell.data_type == "d":
- if hasattr(value, "tzinfo") and value.tzinfo is not None:
- raise TypeError("Excel does not support timezones in datetimes. "
- "The tzinfo in the datetime/time object must be set to None.")
- if cell.parent.parent.iso_dates and not isinstance(value, timedelta):
- value = to_ISO8601(value)
- else:
- attrs['t'] = "n"
- value = to_excel(value, cell.parent.parent.epoch)
- if cell.hyperlink:
- cell.parent._hyperlinks.append(cell.hyperlink)
- return value, attrs
- def etree_write_cell(xf, worksheet, cell, styled=None):
- value, attributes = _set_attributes(cell, styled)
- el = Element("c", attributes)
- if value is None or value == "":
- xf.write(el)
- return
- if cell.data_type == 'f':
- attrib = {}
- if isinstance(value, ArrayFormula):
- attrib = dict(value)
- value = value.text
- elif isinstance(value, DataTableFormula):
- attrib = dict(value)
- value = None
- formula = SubElement(el, 'f', attrib)
- if value is not None and not attrib.get('t') == "dataTable":
- formula.text = value[1:]
- value = None
- if cell.data_type == 's':
- if isinstance(value, CellRichText):
- el.append(value.to_tree())
- else:
- inline_string = Element("is")
- text = Element('t')
- text.text = value
- whitespace(text)
- inline_string.append(text)
- el.append(inline_string)
- else:
- cell_content = SubElement(el, 'v')
- if value is not None:
- cell_content.text = safe_string(value)
- xf.write(el)
- def lxml_write_cell(xf, worksheet, cell, styled=False):
- value, attributes = _set_attributes(cell, styled)
- if value == '' or value is None:
- with xf.element("c", attributes):
- return
- with xf.element('c', attributes):
- if cell.data_type == 'f':
- attrib = {}
- if isinstance(value, ArrayFormula):
- attrib = dict(value)
- value = value.text
- elif isinstance(value, DataTableFormula):
- attrib = dict(value)
- value = None
- with xf.element('f', attrib):
- if value is not None and not attrib.get('t') == "dataTable":
- xf.write(value[1:])
- value = None
- if cell.data_type == 's':
- if isinstance(value, CellRichText):
- el = value.to_tree()
- xf.write(el)
- else:
- with xf.element("is"):
- if isinstance(value, str):
- attrs = {}
- if value != value.strip():
- attrs["{%s}space" % XML_NS] = "preserve"
- el = Element("t", attrs) # lxml can't handle xml-ns
- el.text = value
- xf.write(el)
- else:
- with xf.element("v"):
- if value is not None:
- xf.write(safe_string(value))
- if LXML:
- write_cell = lxml_write_cell
- else:
- write_cell = etree_write_cell
|