From 92694544ef2ad4fa7292e1caf5584965e75899aa Mon Sep 17 00:00:00 2001 From: Stanislav Ulrych Date: Wed, 25 Dec 2019 21:47:25 +0100 Subject: [PATCH 1/3] Added XLS export with xlsxwriter --- export_report_xls.py | 52 +++++++++++++++++++++++++++++++++++++++++++ report.py | 45 +++++++++++++++++++++++++++++++++++++ reporting_toolbars.py | 3 ++- 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 export_report_xls.py diff --git a/export_report_xls.py b/export_report_xls.py new file mode 100644 index 0000000..cdee724 --- /dev/null +++ b/export_report_xls.py @@ -0,0 +1,52 @@ +import FreeCAD +import FreeCADGui + +from report_utils.resource_utils import iconPath +from report_utils.selection_utils import findSelectedReportConfig +from report_utils import qtutils + +XLSX_FILES = "XLSX Files (*.xlsx)" + +class ExportReportXLSCommand: + toolbarName = 'Reporting_Tools' + commandName = 'Export_Report_XLS' + + def GetResources(self): + return {'MenuText': "Export Report XLS", + 'ToolTip': "Exports the configuration stored inside the Report object to a XLS file", + 'Pixmap': iconPath('ExportConfig.svg') + } + + def Activated(self): + reportConfig = findSelectedReportConfig() + + if reportConfig is None: + qtutils.showInfo( + "No Report selected", "Select exactly one Report object to export its content") + + return + + selectedFile = qtutils.userSelectedFile( + 'Export Location', XLSX_FILES, False) + + if selectedFile is None: + return + + reportConfig.exportXLS(selectedFile) + + def IsActive(self): + """If there is no active document we can't do anything.""" + return not FreeCAD.ActiveDocument is None + + +if __name__ == "__main__": + command = ExportReportXLSCommand() + + if command.IsActive(): + command.Activated() + else: + qtutils.showInfo("No open Document", "There is no open document") +else: + import reporting_toolbars + reporting_toolbars.toolbarManager.registerCommand( + ExportReportXLSCommand()) diff --git a/report.py b/report.py index 1bab8cf..1a2360d 100644 --- a/report.py +++ b/report.py @@ -467,6 +467,51 @@ def importJson(self, fileObject): finally: fileObject.close() + def convertValue(self, value): + if value is None: + return '' + elif isinstance(value, Units.Quantity): + return value.UserString + + return str(value) + + def exportXLS(self, selected_file): + import xlsxwriter + + try: + workbook = xlsxwriter.Workbook(selected_file) + boldFormat = workbook.add_format({'bold': True}) + + for statement in self.statements: + worksheet = workbook.add_worksheet(statement.header) + lineNumber = 1 + + if not statement.skipColumnNames: + columnName = None + + for columnLabel in statement.getColumnNames(): + columnName = nextColumnName(columnName) + cellName = buildCellName(columnName, lineNumber) + worksheet.write_string(cellName, columnLabel, boldFormat) + lineNumber += 1 + + rows = statement.execute() + + for row in rows: + columnName = None + + for column in row: + columnName = nextColumnName(columnName) + cellName = buildCellName(columnName, lineNumber) + worksheet.write_string(cellName, self.convertValue(column), + boldFormat if statement.printResultInBold else None) # TODO fix unit format + + lineNumber += 1 + + finally: + workbook.close() + + def __getstate__(self): state = ['VERSION:1'] diff --git a/reporting_toolbars.py b/reporting_toolbars.py index 77dc0ea..9096d2d 100644 --- a/reporting_toolbars.py +++ b/reporting_toolbars.py @@ -13,4 +13,5 @@ def registerCommand(self, command): # import commands here import create_report import export_report_config -import import_report_config \ No newline at end of file +import import_report_config +import export_report_xls \ No newline at end of file From 3e9c9280c7a2dff7c8af08393af02663ae4c604d Mon Sep 17 00:00:00 2001 From: Stanislav Ulrych Date: Thu, 26 Dec 2019 13:17:03 +0100 Subject: [PATCH 2/3] Added proper xlsx unit formatting. --- report.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/report.py b/report.py index 1a2360d..729132e 100644 --- a/report.py +++ b/report.py @@ -467,20 +467,17 @@ def importJson(self, fileObject): finally: fileObject.close() - def convertValue(self, value): - if value is None: - return '' - elif isinstance(value, Units.Quantity): - return value.UserString - - return str(value) - def exportXLS(self, selected_file): import xlsxwriter try: workbook = xlsxwriter.Workbook(selected_file) boldFormat = workbook.add_format({'bold': True}) + fmts = {} + def _get_format(unit): + if not unit in fmts: + fmts[unit] = workbook.add_format({'num_format': '#.??\\ \\' + unit}) + return fmts[unit] for statement in self.statements: worksheet = workbook.add_worksheet(statement.header) @@ -500,11 +497,17 @@ def exportXLS(self, selected_file): for row in rows: columnName = None - for column in row: + for value in row: columnName = nextColumnName(columnName) cellName = buildCellName(columnName, lineNumber) - worksheet.write_string(cellName, self.convertValue(column), - boldFormat if statement.printResultInBold else None) # TODO fix unit format + fmt = None + if isinstance(value, Units.Quantity): + un = value.getUserPreferred() + worksheet.write(cellName, value.Value/un[1], _get_format(un[2])) + elif value is None: + worksheet.write_string(cellName, '') + else: + worksheet.write_string(cellName, str(value)) lineNumber += 1 From 9afd928b000e4527665ec597f0a40bc968855000 Mon Sep 17 00:00:00 2001 From: Stanislav Ulrych Date: Thu, 2 Jan 2020 16:12:21 +0100 Subject: [PATCH 3/3] Added xlsxwriter import check. --- report.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/report.py b/report.py index 729132e..2410b58 100644 --- a/report.py +++ b/report.py @@ -468,7 +468,12 @@ def importJson(self, fileObject): fileObject.close() def exportXLS(self, selected_file): - import xlsxwriter + try: + import xlsxwriter + + except: + FreeCAD.Console.PrintError("It looks like 'xlsxwriter' could not be found on your system. Please see https://xlsxwriter.readthedocs.io/getting_started.html how to install it.") + return try: workbook = xlsxwriter.Workbook(selected_file)