fixing export and open files

main
Steve Nyemba 1 week ago
parent 9a87c724d5
commit 6fb5cec1e4

@ -1,6 +1,7 @@
ej.base.registerLicense('ORg4AjUWIQA/Gnt2XFhhQlJHfV5AQmBIYVp/TGpJfl96cVxMZVVBJAtUQF1hTH5VdkxhWnpWcHZcTmhfWkZ/') ej.base.registerLicense('ORg4AjUWIQA/Gnt2XFhhQlJHfV5AQmBIYVp/TGpJfl96cVxMZVVBJAtUQF1hTH5VdkxhWnpWcHZcTmhfWkZ/')
ej.spreadsheet.Spreadsheet.Inject(ej.spreadsheet.ExcelExport);
var studio = {_context:''} var studio = {_context:''}
studio.defaults = { studio.defaults = {
'duckdb':'SELECT * \nFROM INFORMATION_SCHEMA.TABLES', 'duckdb':'SELECT * \nFROM INFORMATION_SCHEMA.TABLES',
@ -58,6 +59,16 @@ studio.dbe.providers = function (_render){
// }) // })
// } // }
function triggerDownload(blob, filename) {
const url = URL.createObjectURL(blob); // create a temporary URL
const a = document.createElement("a");
a.href = url;
a.download = filename; // suggest a filename
document.body.appendChild(a); // Firefox needs it in DOM
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url); // cleanup
}
studio.grid = function (){ studio.grid = function (){
this.columns = function (_data){ this.columns = function (_data){
var _columns = [] var _columns = []
@ -161,8 +172,9 @@ studio.grid = function (){
}) })
var spreadsheet = new ej.spreadsheet.Spreadsheet(); var spreadsheet = new ej.spreadsheet.Spreadsheet();
_sheet_name = _id.trim().replace(/[#,.]/g,'').replace(/ /g,'-').trim()
spreadsheet.sheets = [ spreadsheet.sheets = [
{name:_id.replace(/[#,.]/g,' '), {name:_sheet_name,
ranges:[{dataSource:rows}], ranges:[{dataSource:rows}],
} }
@ -170,7 +182,7 @@ studio.grid = function (){
if( $(_id)[0].spreadsheet ){ if( $(_id)[0].spreadsheet ){
book = $(_id)[0].spreadsheet ; book = $(_id)[0].spreadsheet ;
book.sheets.forEach((sheet)=>{ book.sheets.forEach((sheet)=>{
if(sheet.name != _id.replace(/[#,.]/g,' ')){ if(sheet.name != _sheet_name){
spreadsheet.sheets.push(sheet) spreadsheet.sheets.push(sheet)
} }
@ -188,7 +200,8 @@ studio.grid = function (){
// } // }
// ] // ]
spreadsheet.saveUrl = studio._context+'api/io/write'
spreadsheet.appendTo(_id) spreadsheet.appendTo(_id)
$(_id)[0].spreadsheet = spreadsheet $(_id)[0].spreadsheet = spreadsheet
@ -254,7 +267,7 @@ studio.frame = function (_args){
} }
this.open = function (_id,file){ this.open = function (_id,file){
var http = HttpClient.instance() var http = HttpClient.instance()
_uri = 'api/io/open' _uri = 'api/io/read'
var form = new FormData() var form = new FormData()
form.append('file',file) form.append('file',file)
http.setData(form) http.setData(form)
@ -295,7 +308,8 @@ studio.frame = function (_args){
}) })
} }
this.export = function(_label,spreadsheet){
this._export = function(_label,spreadsheet){
var uri = 'api/io/write' var uri = 'api/io/write'
var http = HttpClient.instance() var http = HttpClient.instance()
var _data = {} var _data = {}
@ -357,12 +371,58 @@ studio.frame = function (_args){
}) })
} }
} }
this.export = function (_label,spreadsheet){
// spreadsheet.save({filename:_label+'-export.xlsx'})
uri = studio._context+'api/io/write'
filename = _label+'.xlsx'
spreadsheet.saveAsJson().then(response => {
// const fd = new FormData();
// fd.append('JSONData', JSON.stringify(response.jsonObject.Workbook));
// fd.append('fileName', filename);
form = {'JSONData':response.jsonObject.Workbook,'fileName':filename}
// r = fetch(uri, { method: 'POST', body: fd });
var http = HttpClient.instance()
http.setHeader('Content-Type','application/json')
http.setData ( JSON.stringify(form))
http.post(uri,(x)=>{
if(x.status == 200 && x.readyState == 4){
//
//
// console.log(x)
// var blob = new Blob([x.response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const byteCharacters = atob(x.responseText);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
const blob = new Blob([byteArray], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = _label+'-export.xlsx';
document.body.appendChild(link);
link.click();
// Cleanup
URL.revokeObjectURL(link.href);
document.body.removeChild(link);
}
})
});
}
this.render = function (){ this.render = function (){
var _args = this._args var _args = this._args
var _importSheet = this.open var _importSheet = this.open
var _exportSheet = this.export var _exportSheet = this.export
var _icon = $('<img>').attr('src',this._args.icon) var _icon = $('<img>').attr('src',this._args.icon)
_text = _args.provider _text = _args.provider
if (_args.AI){ if (_args.AI){

@ -11,25 +11,29 @@ import json
import base64 import base64
from flask import make_response, send_file from flask import make_response, send_file
import copy import copy
import json
import plugin_ix
import os
@cms.Plugin(mimetype="application/json",method="POST")
def read(**_args) : # @cms.Plugin(mimetype="application/json",method="POST")
_request = _args['request'] # def read(**_args) :
_body = _request.json # _request = _args['request']
_data = {} # _body = _request.json
try: # _data = {}
reader = transport.get.reader(label = _body['label']) # try:
_query = _body['query'] # reader = transport.get.reader(label = _body['label'])
# # _query = _body['query']
# @TODO : # #
# - support for mongodb and NoSQL ... # # @TODO :
# - limit to 10K # # - support for mongodb and NoSQL ...
_data = reader.apply(_query) # # - limit to 10K
_data.to_dict(orient='split') # _data = reader.apply(_query)
del _data['index'] # _data.to_dict(orient='split')
except Exception as e: # del _data['index']
print (e) # except Exception as e:
return _data # print (e)
# return _data
def format (file,_mimetype) : def format (file,_mimetype) :
if 'csv' in _mimetype : if 'csv' in _mimetype :
_df = pd.read_csv(file).fillna('n/a') _df = pd.read_csv(file).fillna('n/a')
@ -40,31 +44,43 @@ def format (file,_mimetype) :
return {'Workbook':{'sheets':sheets}} return {'Workbook':{'sheets':sheets}}
@cms.Plugin(mimetype="text/plain")
def python (**_args) :
_request = _args['request']
_code ="""
# generated code
import pandas as pd
import transport
#
# genereric data reader
dreader = transport.get.reader(label='{_label}')
_df = dreader.read(sql=_sql)
"""
@cms.Plugin(mimetype="application/json",method="POST") @cms.Plugin(mimetype="application/json",method="POST")
def open(**_args): def read(**_args):
"""
This function will in theory open a spreadsheet or csv file
"""
_request = _args['request'] _request = _args['request']
file = _request.files['file'] file = _request.files['file']
spreadsheet = format(file,file.mimetype) spreadsheet = format(file,file.mimetype)
return spreadsheet #{"Workbook":{"sheets":[{"usedRange":{"colIndex":1,"rowIndex":3},"name":"Sheet1","rows":[{"cells":[{"value":"name"},{"value":"age"}]},{"cells":[{"value":"steve"},{"value":"44"}]},{"cells":[{"value":"elon"},{"value":"9"}]},{"cells":[{"value":"nico"},{"value":"33"}]}],"standardHeight":20}]}}) return spreadsheet #{"Workbook":{"sheets":[{"usedRange":{"colIndex":1,"rowIndex":3},"name":"Sheet1","rows":[{"cells":[{"value":"name"},{"value":"age"}]},{"cells":[{"value":"steve"},{"value":"44"}]},{"cells":[{"value":"elon"},{"value":"9"}]},{"cells":[{"value":"nico"},{"value":"33"}]}],"standardHeight":20}]}})
@cms.Plugin(mimetype="application/octet-stream",method="POST") @cms.Plugin(mimetype="application/octet-stream",method="POST")
def write(**_args) : def write(**_args):
_request = _args['request']
_data = _request.json #json.loads(_request.form['JSONData'])
print (_data.keys())
# _data = json.loads(_request.form['JSONData'])
# _data = {"JSONData":_data}
_config = _args['config']
_path = os.sep.join([_config['layout']['location'],_config['layout']['root'],'_plugins'])
# if os.path.exists(_path) :
_filename = os.sep.join([_path,'ms-excel.py'])
_lx = plugin_ix.Loader(file=_filename)
_getExcelStream = _lx._modules.get('instance')
_stream = _getExcelStream(_data)
print (_stream.read())
_stream.seek(0)
return base64.b64encode(_stream.read()).decode('utf-8')
# response = make_response(_stream.getvalue())
# # Set headers for file download
# filename = _request.form['fileName']
# response.headers["Content-Disposition"] = f"attachment; filename={filename}"
# response.headers["Content-Type"] = "application/octet-stream" # Or a more specific MIME type like 'text/plain'
# return response
def _write(**_args) :
""" """
This functon generates an excel file, by returning the encoded 64bit stream This functon generates an excel file, by returning the encoded 64bit stream
""" """

@ -0,0 +1,94 @@
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()
Loading…
Cancel
Save