1414 < label for ="{{ filter_form.status.id }} " class ="sr-only "> {{ filter_form.status.label.text }}</ label >
1515 {{ filter_form.status(class_='form-control custom-select') }}
1616 </ div >
17- < button type ="submit " class ="btn btn-primary "> {{ _('Filter') }}</ button >
17+ < button type ="submit " class ="btn btn-primary mr-sm-2 "> {{ _('Filter') }}</ button >
18+ < a class ="btn btn-outline-secondary " id ="export-btn "> {{ _('Export process summary') }}</ a >
1819 </ div >
1920</ form >
2021{%- endblock %}
3132 {% if incidents_summary.top %}
3233 < h4 class ="font-weight-light mt-4{{ ' rtl' if g.locale.text_direction == 'rtl' else '' }} "> {{ _('Summary') }}</ h4 >
3334 < div class ="table-responsive ">
34- < table class ="table table-bordered table-striped ">
35+ < table class ="table table-bordered table-striped " data-summary-table data-form-name =" {{ form.name }} " >
3536 < tr class ="{{ 'rtl' if g.locale.text_direction == 'rtl' else '' }} ">
3637 < th width ="250 "> {{ _('Location') }}</ th >
3738 < th width ="100 " style ="text-align:center "> N</ th >
@@ -79,7 +80,7 @@ <h5 class="font-weight-light{{ ' rtl' if g.locale.text_direction == 'rtl' else '
7980 {% set question_summary = form|checklist_question_summary(field, location, dataframe) %}
8081 {% set stats = question_summary.stats %}
8182 < div class ="table-responsive ">
82- < table width ="100% " class ="table table-striped table-bordered ">
83+ < table width ="100% " class ="table table-striped table-bordered " data-summary-table data-form-name =" {{ form.name }} " >
8384 < tr class ="{{ 'rtl' if g.locale.text_direction == 'rtl' else '' }} ">
8485 < td width ="30 " rowspan ="{% if stats.urban %}4{% else %}2{% endif %} "> < strong > {{ field.tag }}</ strong > </ td >
8586 < td rowspan ="{% if stats.urban %}4{% else %}2{% endif %} "> < a class ="text-decoration-none " href ="{{ url_for('process_analysis.process_analysis_with_location_and_tag', form_id=form.id, location_id=location.id, tag=field.tag) }} "> {{ field.description }}</ a > </ td >
@@ -138,3 +139,68 @@ <h5 class="font-weight-light{{ ' rtl' if g.locale.text_direction == 'rtl' else '
138139 </ div >
139140</ div >
140141{% endblock %}
142+ {% block scripts %}
143+ < script src ="{{ url_for('static', filename='js/xlsx.mini.min.js') }} "> </ script >
144+ < script >
145+ const loader = ( ) => {
146+ document . querySelector ( '#export-btn' ) . addEventListener ( 'click' , ( ) => {
147+ const createGapRows = ( worksheet , nrows ) => {
148+ let ref = XLSX . utils . decode_range ( worksheet [ '!ref' ] ) ;
149+ ref . e . r += nrows ;
150+ worksheet [ '!ref' ] = XLSX . utils . encode_range ( ref ) ;
151+ } ;
152+
153+ const tryParseNumericValue = value => {
154+ const result = Number . parseInt ( value ) ;
155+ return isNaN ( result ) ? value : result ;
156+ } ;
157+
158+ const extractTableData = table => {
159+ let tableData = [ ] , splitCols = { } ;
160+ Array . from ( table . rows ) . forEach ( row => {
161+ let rowData = [ ] ;
162+ Array . from ( row . cells ) . forEach ( cell => {
163+ if ( cell . childNodes . length > 1 ) {
164+ if ( cell . querySelector ( 'br' ) ) {
165+ const value = cell . childNodes [ 2 ] . textContent . replace ( '(' , '' ) . replace ( ')' , '' ) . trim ( ) ;
166+ rowData . push ( Number . parseInt ( value ) ) ;
167+ } else {
168+ rowData . push ( cell . textContent . trim ( ) ) ;
169+ }
170+ } else {
171+ rowData . push ( tryParseNumericValue ( cell . textContent . trim ( ) ) ) ;
172+ }
173+ } ) ;
174+ tableData . push ( rowData ) ;
175+ } ) ;
176+
177+ return tableData ;
178+ } ;
179+
180+ const tables = Array . from ( document . querySelectorAll ( 'table[data-summary-table]' ) ) ;
181+ if ( tables . length === 0 ) {
182+ return ;
183+ }
184+
185+ ///*
186+ const workbook = XLSX . utils . book_new ( ) ;
187+ let worksheet ;
188+ tables . forEach ( ( table , index ) => {
189+ if ( index === 0 ) {
190+ worksheet = XLSX . utils . aoa_to_sheet ( extractTableData ( table ) )
191+ } else {
192+ XLSX . utils . sheet_add_dom ( worksheet , table , { origin : - 1 } )
193+ }
194+ createGapRows ( worksheet , 2 ) ;
195+ } ) ;
196+ const formName = tables [ 0 ] . dataset . formName ;
197+ const filename = `${ formName } -process-data-summary-${ Math . floor ( ( new Date ( ) ) . getTime ( ) / 1000 ) } .xlsx` ;
198+ XLSX . utils . book_append_sheet ( workbook , worksheet , formName ) ;
199+ XLSX . writeFile ( workbook , filename ) ;
200+ //*/
201+ //console.log(extractTableData(tables[0]));
202+ } ) ;
203+ } ;
204+ document . addEventListener ( 'DOMContentLoaded' , loader ) ;
205+ </ script >
206+ {% endblock scripts %}
0 commit comments