Przeglądaj źródła

Merge pull request #2687 from manassolanki/report

Report Export
version-14
Nabin Hait 8 lat temu
committed by GitHub
rodzic
commit
d23c369fc0
7 zmienionych plików z 156 dodań i 26 usunięć
  1. +38
    -0
      frappe/desk/query_report.py
  2. +26
    -12
      frappe/desk/reportview.py
  3. +39
    -8
      frappe/public/js/frappe/views/reports/query_report.js
  4. +17
    -5
      frappe/public/js/frappe/views/reports/reportview.js
  5. +9
    -1
      frappe/utils/response.py
  6. +26
    -0
      frappe/utils/xlsxutils.py
  7. +1
    -0
      requirements.txt

+ 38
- 0
frappe/desk/query_report.py Wyświetl plik

@@ -61,6 +61,7 @@ def get_script(report_name):

@frappe.whitelist()
def run(report_name, filters=None, user=None):

report = get_report_doc(report_name)
if not user:
user = frappe.session.user
@@ -111,6 +112,40 @@ def run(report_name, filters=None, user=None):
"chart": chart
}


@frappe.whitelist()
def export_query():
"""export from query reports"""

data = frappe._dict(frappe.local.form_dict)

del data["cmd"]

if isinstance(data.get("filters"), basestring):
filters = json.loads(data["filters"])
if isinstance(data.get("report_name"), basestring):
report_name = data["report_name"]
if isinstance(data.get("file_format_type"), basestring):
file_format_type = data["file_format_type"]

if file_format_type == "Excel":

data = run(report_name, filters)
data = frappe._dict(data)

columns = get_columns_dict(data.columns)
content = []
for col in columns.values():
content.append(col["label"])

from frappe.utils.xlsxutils import make_xlsx
xlsx_file = make_xlsx([content] + data.result, "Query Report")

frappe.response['filename'] = report_name + '.xlsx'
frappe.response['filecontent'] = xlsx_file.getvalue()
frappe.response['type'] = 'binary'


def get_report_module_dotted_path(module, report_name):
return frappe.local.module_app[scrub(module)] + "." + scrub(module) \
+ ".report." + scrub(report_name) + "." + scrub(report_name)
@@ -166,6 +201,7 @@ def add_total_row(result, columns, meta = None):
result.append(total_row)
return result


def get_filtered_data(ref_doctype, columns, data, user):
result = []
linked_doctypes = get_linked_doctypes(columns, data)
@@ -189,6 +225,7 @@ def get_filtered_data(ref_doctype, columns, data, user):

return result


def has_match(row, linked_doctypes, doctype_match_filters, ref_doctype, if_owner, columns_dict, user):
"""Returns True if after evaluating permissions for each linked doctype
- There is an owner match for the ref_doctype
@@ -297,6 +334,7 @@ def get_columns_dict(columns):
else:
col_dict["fieldtype"] = col[1]

col_dict["label"] = col[0]
col_dict["fieldname"] = frappe.scrub(col[0])

# dict


+ 26
- 12
frappe/desk/reportview.py Wyświetl plik

@@ -91,8 +91,10 @@ def export_query():
form_params["as_list"] = True
doctype = form_params.doctype
add_totals_row = None
file_format_type = form_params["file_format_type"]

del form_params["doctype"]
del form_params["file_format_type"]

if 'add_totals_row' in form_params and form_params['add_totals_row']=='1':
add_totals_row = 1
@@ -110,20 +112,32 @@ def export_query():
for i, row in enumerate(ret):
data.append([i+1] + list(row))

# convert to csv
from cStringIO import StringIO
import csv
if file_format_type == "CSV":

f = StringIO()
writer = csv.writer(f)
for r in data:
# encode only unicode type strings and not int, floats etc.
writer.writerow(map(lambda v: isinstance(v, unicode) and v.encode('utf-8') or v, r))
# convert to csv
import csv
from cStringIO import StringIO

f = StringIO()
writer = csv.writer(f)
for r in data:
# encode only unicode type strings and not int, floats etc.
writer.writerow(map(lambda v: isinstance(v, unicode) and v.encode('utf-8') or v, r))

f.seek(0)
frappe.response['result'] = unicode(f.read(), 'utf-8')
frappe.response['type'] = 'csv'
frappe.response['doctype'] = doctype

elif file_format_type == "Excel":

from frappe.utils.xlsxutils import make_xlsx
xlsx_file = make_xlsx(data, doctype)

frappe.response['filename'] = doctype + '.xlsx'
frappe.response['filecontent'] = xlsx_file.getvalue()
frappe.response['type'] = 'binary'

f.seek(0)
frappe.response['result'] = unicode(f.read(), 'utf-8')
frappe.response['type'] = 'csv'
frappe.response['doctype'] = doctype

def append_totals_row(data):
if not data:


+ 39
- 8
frappe/public/js/frappe/views/reports/query_report.js Wyświetl plik

@@ -88,7 +88,7 @@ frappe.views.QueryReport = Class.extend({
}, me.report_doc.letter_head);
}, true);

this.page.add_menu_item(__('Export'), function() { me.export_report(); },
this.page.add_menu_item(__('Export'), function() { me.make_export(); },
true);

this.page.add_menu_item(__("Setup Auto Email"), function() {
@@ -784,18 +784,49 @@ frappe.views.QueryReport = Class.extend({
}
});
},
export_report: function() {

make_export: function() {

var me = this;
this.title = this.report_name;

if(!frappe.model.can_export(this.report_doc.ref_doctype)) {
msgprint(__("You are not allowed to export this report"));
return false;
}

var result = $.map(frappe.slickgrid_tools.get_view_data(this.columns, this.dataView),
function(row) {
return [row.splice(1)];
});
this.title = this.report_name;
frappe.tools.downloadify(result, null, this.title);
frappe.prompt({fieldtype:"Select", label: __("Select File Type"), fieldname:"file_format_type",
options:"Excel\nCSV", default:"Excel", reqd: 1},
function(data) {

if (data.file_format_type == "CSV") {

var result = $.map(frappe.slickgrid_tools.get_view_data(me.columns, me.dataView),
function(row) {
return [row.splice(1)];
});
frappe.tools.downloadify(result, null, me.title);
}

else if (data.file_format_type == "Excel") {

me.wrapper.find(".results").toggle(false);
try {
var filters = me.get_values(true);
} catch(e) {
return;
}
var args = {
cmd: 'frappe.desk.query_report.export_query',
report_name: me.report_name,
file_format_type: data.file_format_type,
filters: filters
};

open_url_post(frappe.request.url, args);
}
}, __("Export Report: "+ me.title), __("Download"));

return false;
},



+ 17
- 5
frappe/public/js/frappe/views/reports/reportview.js Wyświetl plik

@@ -265,6 +265,7 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
filters: this.filter_list.get_filters(),
save_list_settings_fields: 1,
with_childnames: 1,
file_format_type: this.file_format_type
}
},

@@ -676,11 +677,22 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
}
var export_btn = this.page.add_menu_item(__('Export'), function() {
var args = me.get_args();
args.cmd = 'frappe.desk.reportview.export_query'
if(me.add_totals_row) {
args.add_totals_row = 1;
}
open_url_post(frappe.request.url, args);

frappe.prompt({fieldtype:"Select", label: __("Select File Type"), fieldname:"file_format_type",
options:"Excel\nCSV", default:"Excel", reqd: 1},
function(data) {

args.cmd = 'frappe.desk.reportview.export_query';
args.file_format_type = data.file_format_type;

if(me.add_totals_row) {
args.add_totals_row = 1;
}

open_url_post(frappe.request.url, args);

}, __("Export Report: " + me.doctype), __("Download"));

}, true);
},



+ 9
- 1
frappe/utils/response.py Wyświetl plik

@@ -36,7 +36,8 @@ def build_response(response_type=None):
'download': as_raw,
'json': as_json,
'page': as_page,
'redirect': redirect
'redirect': redirect,
'binary': as_binary
}

return response_type_map[frappe.response.get('type') or response_type]()
@@ -68,6 +69,13 @@ def as_json():
response.data = json.dumps(frappe.local.response, default=json_handler, separators=(',',':'))
return response

def as_binary():
response = Response()
response.mimetype = 'application/octet-stream'
response.headers[b"Content-Disposition"] = ("filename=\"%s\"" % frappe.response['filename'].replace(' ', '_')).encode("utf-8")
response.data = frappe.response['filecontent']
return response

def make_logs(response = None):
"""make strings for msgprint and errprint"""
if not response:


+ 26
- 0
frappe/utils/xlsxutils.py Wyświetl plik

@@ -0,0 +1,26 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals

import frappe
from frappe.utils import encode, cstr, cint, flt, comma_or

import openpyxl
from cStringIO import StringIO
from openpyxl.styles import Font

# return xlsx file object
def make_xlsx(data, sheet_name):

wb = openpyxl.Workbook(write_only=True)
ws = wb.create_sheet(sheet_name, 0)

row1 = ws.row_dimensions[1]
row1.font = Font(name='Calibri',bold=True)

for row in data:
ws.append(row)

xlsx_file = StringIO()
wb.save(xlsx_file)
return xlsx_file

+ 1
- 0
requirements.txt Wyświetl plik

@@ -41,3 +41,4 @@ xlwt
oauthlib
PyJWT
pypdf
openpyxl

Ładowanie…
Anuluj
Zapisz