You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
3.8 KiB
Python
94 lines
3.8 KiB
Python
import json
|
|
import pandas as pd
|
|
import io
|
|
import xlsxwriter as xlx
|
|
|
|
class Exporter :
|
|
def __init__(self,_data):
|
|
"""
|
|
The data is passed by syncfusion
|
|
"""
|
|
self._data = _data
|
|
self._sheets = _data['sheets'] if 'JSONData' not in _data else _data['JSONData']['sheets']
|
|
self._stream = io.BytesIO()
|
|
self._workbook = xlx.Workbook(self._stream)
|
|
def _getColRowIndex(self,_label):
|
|
"""
|
|
This function will return column/row given an excel specification for instance C1 -> 2,0
|
|
"""
|
|
_ndxCol = []
|
|
_ndxRow = []
|
|
for xchar in _label.strip() :
|
|
if xchar.isnumeric() :
|
|
|
|
_ndxRow.append( xchar )
|
|
else:
|
|
_ndxCol.append( ord(xchar) -65)
|
|
|
|
return sum(_ndxCol), int("".join(_ndxRow)) -1
|
|
|
|
def _initData (self):
|
|
|
|
self._charts = []
|
|
for _info in self._sheets :
|
|
_rows = _info['rows']
|
|
_name = _info['name'] #-- sheet name
|
|
_icol,_irow = self._getColRowIndex( _info.get('topLeftCell','A1'))
|
|
_worksheet = self._workbook.add_worksheet(_name)
|
|
|
|
for _item in _rows :
|
|
cells = _item['cells']
|
|
|
|
for _ndxcol in range(0, len(cells)) :
|
|
if not cells[_ndxcol] :
|
|
continue
|
|
if 'value' in cells[_ndxcol] :
|
|
_value = cells[_ndxcol]['value']
|
|
if 'formattedText' in cells[_ndxcol] :
|
|
_value = cells[_ndxcol]['formattedText']
|
|
|
|
_worksheet.write(_irow, _icol + _ndxcol, _value)
|
|
|
|
if 'chart' in cells[_ndxcol] :
|
|
for _chart in cells[_ndxcol]['chart'] :
|
|
offset = 0 if 'value' not in cells[_ndxcol] else 1
|
|
_xchar = chr( _ndxcol + _icol + 65 + offset)+str(_irow+1)
|
|
_meta = {'cell':_xchar, 'sheet_name':_name,'chart':_chart}
|
|
self._charts.append(_meta)
|
|
|
|
_irow += 1 # incrementing rows
|
|
def _initCharts(self):
|
|
for _meta in self._charts :
|
|
_sheet = self._workbook.get_worksheet_by_name(_meta['sheet_name'])
|
|
_chart = self._workbook.add_chart({'type':_meta['chart']['type'].lower()})
|
|
if 'range' in _meta['chart'] :
|
|
#
|
|
# Analysis of the range expression in case we have more than one series
|
|
_range = _meta['chart']['range'].split('!')[-1]
|
|
# #
|
|
# #
|
|
_series = _range.split(':')
|
|
_lowerColIndex,_lowerRowIndex = self._getColRowIndex(_series[-1])
|
|
_upperColIndex,_upperRowIndex = self._getColRowIndex(_series[0])
|
|
|
|
if _upperColIndex == _lowerColIndex :
|
|
_xchar = chr(_upperColIndex + 65)
|
|
_chart.add_series({'values':_meta['chart']['range'],'name':f"{_meta['sheet_name']}!{_xchar}{_upperRowIndex+1}"})
|
|
else:
|
|
for _i in range(_upperColIndex,_lowerColIndex + 1) :
|
|
_xchar = chr( _i + 65)
|
|
_range = f"{_meta['sheet_name']}!{_xchar}{_upperRowIndex+1}:{_xchar}{_lowerRowIndex+1}"
|
|
_chart.add_series({'values':_range,'name':f'{_meta["sheet_name"]}!{_xchar}{_upperRowIndex+1}'})
|
|
_sheet.insert_chart(_meta['cell'],_chart)
|
|
def get(self):
|
|
self._initData ()
|
|
self._initCharts()
|
|
self._workbook.close()
|
|
self._stream.seek(0)
|
|
return self._stream
|
|
|
|
|
|
#
|
|
# here is the interface to the calling code (in case it can)
|
|
def instance (_data) :
|
|
return (Exporter(_data)).get() |