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

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()