@sapui5/sap.ui.export 1.100.0 → 1.102.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/package.json +1 -1
  2. package/src/sap/ui/export/.library +2 -2
  3. package/src/sap/ui/export/ExportBase.js +29 -7
  4. package/src/sap/ui/export/ExportDialog.js +30 -22
  5. package/src/sap/ui/export/ExportHandler.js +463 -0
  6. package/src/sap/ui/export/ExportUtils.js +215 -97
  7. package/src/sap/ui/export/PortableDocument.js +94 -56
  8. package/src/sap/ui/export/Spreadsheet.js +35 -22
  9. package/src/sap/ui/export/SpreadsheetExport.js +1 -1
  10. package/src/sap/ui/export/fragments/SettingsDialog.fragment.xml +24 -14
  11. package/src/sap/ui/export/js/XLSXBuilder.js +1 -1
  12. package/src/sap/ui/export/js/XLSXBuilder.js.map +1 -1
  13. package/src/sap/ui/export/library.js +42 -15
  14. package/src/sap/ui/export/messagebundle.properties +55 -4
  15. package/src/sap/ui/export/messagebundle_ar.properties +34 -2
  16. package/src/sap/ui/export/messagebundle_bg.properties +34 -2
  17. package/src/sap/ui/export/messagebundle_ca.properties +34 -2
  18. package/src/sap/ui/export/messagebundle_cs.properties +34 -2
  19. package/src/sap/ui/export/messagebundle_cy.properties +34 -2
  20. package/src/sap/ui/export/messagebundle_da.properties +34 -2
  21. package/src/sap/ui/export/messagebundle_de.properties +34 -2
  22. package/src/sap/ui/export/messagebundle_el.properties +34 -2
  23. package/src/sap/ui/export/messagebundle_en.properties +33 -1
  24. package/src/sap/ui/export/messagebundle_en_GB.properties +33 -1
  25. package/src/sap/ui/export/messagebundle_en_US_sappsd.properties +33 -1
  26. package/src/sap/ui/export/messagebundle_en_US_saprigi.properties +33 -1
  27. package/src/sap/ui/export/messagebundle_en_US_saptrc.properties +33 -1
  28. package/src/sap/ui/export/messagebundle_es.properties +34 -2
  29. package/src/sap/ui/export/messagebundle_es_MX.properties +34 -2
  30. package/src/sap/ui/export/messagebundle_et.properties +34 -2
  31. package/src/sap/ui/export/messagebundle_fi.properties +34 -2
  32. package/src/sap/ui/export/messagebundle_fr.properties +39 -7
  33. package/src/sap/ui/export/messagebundle_fr_CA.properties +36 -4
  34. package/src/sap/ui/export/messagebundle_hi.properties +34 -2
  35. package/src/sap/ui/export/messagebundle_hr.properties +34 -2
  36. package/src/sap/ui/export/messagebundle_hu.properties +34 -2
  37. package/src/sap/ui/export/messagebundle_id.properties +35 -3
  38. package/src/sap/ui/export/messagebundle_it.properties +34 -2
  39. package/src/sap/ui/export/messagebundle_iw.properties +34 -2
  40. package/src/sap/ui/export/messagebundle_ja.properties +34 -2
  41. package/src/sap/ui/export/messagebundle_kk.properties +34 -2
  42. package/src/sap/ui/export/messagebundle_ko.properties +34 -2
  43. package/src/sap/ui/export/messagebundle_lt.properties +34 -2
  44. package/src/sap/ui/export/messagebundle_lv.properties +34 -2
  45. package/src/sap/ui/export/messagebundle_ms.properties +34 -2
  46. package/src/sap/ui/export/messagebundle_nl.properties +34 -2
  47. package/src/sap/ui/export/messagebundle_no.properties +34 -2
  48. package/src/sap/ui/export/messagebundle_pl.properties +34 -2
  49. package/src/sap/ui/export/messagebundle_pt.properties +34 -2
  50. package/src/sap/ui/export/messagebundle_pt_PT.properties +34 -2
  51. package/src/sap/ui/export/messagebundle_ro.properties +34 -2
  52. package/src/sap/ui/export/messagebundle_ru.properties +34 -2
  53. package/src/sap/ui/export/messagebundle_sh.properties +34 -2
  54. package/src/sap/ui/export/messagebundle_sk.properties +34 -2
  55. package/src/sap/ui/export/messagebundle_sl.properties +36 -4
  56. package/src/sap/ui/export/messagebundle_sv.properties +34 -2
  57. package/src/sap/ui/export/messagebundle_th.properties +34 -2
  58. package/src/sap/ui/export/messagebundle_tr.properties +34 -2
  59. package/src/sap/ui/export/messagebundle_uk.properties +34 -2
  60. package/src/sap/ui/export/messagebundle_vi.properties +34 -2
  61. package/src/sap/ui/export/messagebundle_zh_CN.properties +34 -2
  62. package/src/sap/ui/export/messagebundle_zh_TW.properties +34 -2
  63. package/src/sap/ui/export/provider/DataProviderBase.js +10 -10
@@ -23,9 +23,11 @@ sap.ui.define([
23
23
  var ValueState = coreLibrary.ValueState;
24
24
  var FileType = library.FileType;
25
25
  var EdmType = library.EdmType;
26
+ var Destination = library.Destination;
26
27
  var uiVersion = null;
27
28
 
28
29
  /* Async call to resource bundle */
30
+ var oResourceBundle;
29
31
  var oResourceBundlePromise = Core.getLibraryResourceBundle('sap.ui.export', true);
30
32
 
31
33
  var CLASS_NAME = 'sap.ui.export.ExportUtils';
@@ -44,25 +46,32 @@ sap.ui.define([
44
46
  });
45
47
 
46
48
  /* Returns the Export Settings used by the User Settings Dialog */
47
- function getDefaultSettings(oCustomConfig, oResourceBundle, oExportCapabilities) {
49
+ function getDefaultSettings(oCustomConfig, oResourceBundle, oExportCapabilities, bRemoteDestination) {
48
50
  var sSelectedKey;
49
51
  var aSupportedFormats = Object.keys(oExportCapabilities);
50
52
 
51
53
  var oDefaultConfig = {
52
54
  fileName: 'Standard',
53
- fileType: [],
54
- selectedFileType: 'XLSX',
55
- selectedPaperSize: 'DIN_A4',
56
- selectedOrientation: 'LANDSCAPE',
55
+ fileTypeCollection: [],
56
+ fileType: 'XLSX',
57
+ destinationCollection: [
58
+ {key: Destination.LOCAL, text: oResourceBundle.getText('DESTINATION_LOCAL')}
59
+ ],
60
+ destination: Destination.LOCAL,
61
+ paperSize: 'DIN_A4',
62
+ orientation: 'LANDSCAPE',
57
63
  splitCells: false,
58
64
  includeFilterSettings: false,
59
65
  addDateTime: false,
60
66
  doEnableAccessibility: false,
61
- paperSize: [
67
+ pdfArchive: false,
68
+ capabilities: oExportCapabilities,
69
+ fitToPage: false,
70
+ paperSizeCollection: [
62
71
  {key: "DIN_A4", text: oResourceBundle.getText("PAPER_SIZE_A4")},
63
72
  {key: "US_LETTER", text: oResourceBundle.getText("PAPER_SIZE_US_LETTER")}
64
73
  ],
65
- orientation: [
74
+ orientationCollection: [
66
75
  {key:"LANDSCAPE", text: oResourceBundle.getText("ORIENTATION_LAND")},
67
76
  {key:"PORTRAIT", text: oResourceBundle.getText("ORIENTATION_PORT")}
68
77
  ],
@@ -72,23 +81,30 @@ sap.ui.define([
72
81
  };
73
82
 
74
83
  aSupportedFormats.forEach(function(sFormat) {
75
- oDefaultConfig.fileType.push({key: sFormat.toUpperCase()});
84
+ oDefaultConfig.fileTypeCollection.push({key: sFormat.toUpperCase()});
76
85
  });
77
86
 
87
+ if (bRemoteDestination) {
88
+ oDefaultConfig.destinationCollection.push({
89
+ key: 'REMOTE',
90
+ text: oResourceBundle.getText('DESTINATION_REMOTE')
91
+ });
92
+ }
93
+
78
94
  var oExportConfig = Object.assign({}, oDefaultConfig, oCustomConfig || {});
79
95
 
80
- for (var i = 0; i < oExportConfig.fileType.length; i++) {
96
+ for (var i = 0; i < oExportConfig.fileTypeCollection.length; i++) {
81
97
  sSelectedKey = null;
82
98
 
83
- if (!oExportConfig.fileType[i].text) {
84
- oExportConfig.fileType[i].text = oResourceBundle.getText(oExportConfig.fileType[i].key + '_FILETYPE');
99
+ if (!oExportConfig.fileTypeCollection[i].text) {
100
+ oExportConfig.fileTypeCollection[i].text = oResourceBundle.getText(oExportConfig.fileTypeCollection[i].key + '_FILETYPE');
85
101
  }
86
- if (oExportConfig.fileType[i].key === oExportConfig.selectedFileType) {
87
- sSelectedKey = oExportConfig.fileType[i].key;
102
+ if (oExportConfig.fileTypeCollection[i].key === oExportConfig.fileType) {
103
+ sSelectedKey = oExportConfig.fileTypeCollection[i].key;
88
104
  }
89
105
  }
90
106
  if (!sSelectedKey) {
91
- oExportConfig.selectedFileType = oExportConfig.fileType[0].key;
107
+ oExportConfig.fileType = oExportConfig.fileTypeCollection[0].key;
92
108
  }
93
109
 
94
110
  return oExportConfig;
@@ -97,7 +113,7 @@ sap.ui.define([
97
113
  function processExportSettings(oSettings) {
98
114
  var oFinalSettings = {};
99
115
 
100
- ["fileName", "selectedFileType", "selectedPaperSize", "selectedOrientation", "splitCells", "includeFilterSettings", "addDateTime", "doEnableAccessibility", "fontSize", "signature", "signatureReason"].forEach(function(sProperty) {
116
+ ["fileName", "fileType", "paperSize", "orientation", "splitCells", "includeFilterSettings", "addDateTime", "doEnableAccessibility", "fitToPage", "fontSize", "signature", "signatureReason", "pdfArchive", 'destination'].forEach(function(sProperty) {
101
117
  oFinalSettings[sProperty] = oSettings[sProperty];
102
118
  });
103
119
 
@@ -108,7 +124,7 @@ sap.ui.define([
108
124
  * Utilities related to export to enable reuse in integration scenarios (e.g. tables).
109
125
  *
110
126
  * @author SAP SE
111
- * @version 1.100.0
127
+ * @version 1.102.1
112
128
  *
113
129
  * @since 1.59
114
130
  * @name sap.ui.export.ExportUtils
@@ -159,8 +175,9 @@ sap.ui.define([
159
175
  /**
160
176
  * Creates the Export settings dialog that can be used for configuring the spreadsheet before exporting.
161
177
  *
162
- * @param {Object} mCustomConfig Initial configuration of the settings dialog
163
- * @param {Object} oExportCapabilities Definition of supported export features
178
+ * @param {object} mCustomConfig Initial configuration of the settings dialog
179
+ * @param {object} oExportCapabilities Definition of supported export features
180
+ * @param {boolean} [bRemoteDestination] Activates remote destinations for export
164
181
  * @param {sap.ui.core.Control} [oOpener] The opener of the dialog
165
182
  * @param {function(sap.m.Dialog)} [fnCallback] Handler function that is called once the dialog has been opened. A reference to the dialog is passed as parameter
166
183
  *
@@ -168,14 +185,22 @@ sap.ui.define([
168
185
  *
169
186
  * @static
170
187
  */
171
- getExportSettingsViaDialog: function(mCustomConfig, oExportCapabilities, oOpener, fnCallback) {
188
+ getExportSettingsViaDialog: function(mCustomConfig, oExportCapabilities, bRemoteDestination, oOpener, fnCallback) {
172
189
  return new Promise(function (fnResolve, fnReject) {
173
190
  var oExportSettingsDialog;
174
191
 
192
+ // Shift optional arguments
193
+ if (typeof bRemoteDestination === 'object') {
194
+ fnCallback = oOpener;
195
+ oOpener = bRemoteDestination;
196
+ } else if (typeof bRemoteDestination === 'function') {
197
+ fnCallback = bRemoteDestination;
198
+ }
199
+
175
200
  oResourceBundlePromise.then(function (oResourceBundle) {
176
201
  var oExportConfigModel = new JSONModel();
177
202
 
178
- oExportConfigModel.setData(getDefaultSettings(mCustomConfig, oResourceBundle, oExportCapabilities));
203
+ oExportConfigModel.setData(getDefaultSettings(mCustomConfig, oResourceBundle, oExportCapabilities, bRemoteDestination));
179
204
 
180
205
  Fragment.load({
181
206
  name: 'sap.ui.export.fragments.SettingsDialog',
@@ -187,6 +212,12 @@ sap.ui.define([
187
212
  isXLSX: function(sValue) {
188
213
  return sValue === FileType.XLSX;
189
214
  },
215
+ hasDestinations: function(sFileType, aDestinationCollection) {
216
+ return sFileType === FileType.XLSX && aDestinationCollection.length > 1;
217
+ },
218
+ formatExportButton: function(sDestination) {
219
+ return sDestination === Destination.LOCAL ? oResourceBundle.getText('EXPORT_BUTTON') : oResourceBundle.getText('DIALOG_BUTTON_CLOUD_DESTINATION');
220
+ },
190
221
  onCancel: function() {
191
222
  oExportSettingsDialog.close();
192
223
  },
@@ -222,9 +253,11 @@ sap.ui.define([
222
253
  oExportBtn.setEnabled(!bValidate);
223
254
  },
224
255
  onFileTypeChange: function(oEvent) {
225
- var oSelectedItem = oEvent.getParameter("selectedItem");
256
+ var oSelectedItem = oEvent.getParameter('selectedItem');
226
257
  if (oSelectedItem && oSelectedItem.getKey() === FileType.PDF) {
227
- oExportConfigModel.setProperty("/splitCells", true);
258
+ oExportConfigModel.setProperty('/splitCells', true);
259
+ oExportConfigModel.setProperty('/includeFilterSettings', false);
260
+ oExportConfigModel.setProperty('/destination', Destination.LOCAL);
228
261
  } else {
229
262
  Core.byId('exportSettingsDialog-signatureReason').setVisible(false);
230
263
  Core.byId('exportSettingsDialog-signatureReasonLabel').setVisible(false);
@@ -295,7 +328,7 @@ sap.ui.define([
295
328
  * Combines the filter operator with the value and
296
329
  * creates a textual representation.
297
330
  *
298
- * @param {Object} oFilter A single filter object according to ListBinding#getFilterInfo
331
+ * @param {object} oFilter A single filter object according to ListBinding#getFilterInfo
299
332
  * @returns {string} Textual representation of the filter operation and value
300
333
  * @private
301
334
  */
@@ -325,7 +358,7 @@ sap.ui.define([
325
358
  /**
326
359
  * Parse filter tree recursively.
327
360
  *
328
- * @param {Object} oFilter Filter configuration according to ListBinding#getFilterInfo
361
+ * @param {object} oFilter Filter configuration according to ListBinding#getFilterInfo
329
362
  * @returns {Array} Array of filter entries
330
363
  * @private
331
364
  */
@@ -348,11 +381,12 @@ sap.ui.define([
348
381
  * Parses a logical filter and concatenates all
349
382
  * subsequent filters.
350
383
  *
351
- * @param {Object} oLogicalFilter Filter object according to ListBinding#getFilterInfo
352
- * @returns {Array} Array containing all filter settings
384
+ * @param {object} oLogicalFilter Filter object according to ListBinding#getFilterInfo
385
+ * @returns {Array} Array containing evaluated filter settings
353
386
  * @private
354
387
  */
355
388
  _parseLogical: function(oLogicalFilter) {
389
+ var aFilters, sProperty;
356
390
 
357
391
  /* Breakout behavior for between filter */
358
392
  if (oLogicalFilter.op == '&&'
@@ -382,14 +416,34 @@ sap.ui.define([
382
416
  });
383
417
  }
384
418
 
385
- return Utils._parseFilter(oLogicalFilter.left).concat(Utils._parseFilter(oLogicalFilter.right));
419
+ aFilters = Utils._parseFilter(oLogicalFilter.left).concat(Utils._parseFilter(oLogicalFilter.right));
420
+
421
+ /* Group logical OR filter on the same property */
422
+ if (oLogicalFilter.op === '||' && aFilters.length) {
423
+ sProperty = aFilters[0].key;
424
+
425
+ if (aFilters.every(function(item) { return item.key === sProperty; })) {
426
+ aFilters = [
427
+ {
428
+ key: sProperty,
429
+ value: aFilters.reduce(function(acc, item) {
430
+ var sSeparator = acc ? '; ' : '';
431
+
432
+ return acc + sSeparator + item.value;
433
+ }, '')
434
+ }
435
+ ];
436
+ }
437
+ }
438
+
439
+ return aFilters;
386
440
  },
387
441
 
388
442
  /**
389
443
  * Parses a binary filter and returns an Array that
390
444
  * contains this explicit filter item.
391
445
  *
392
- * @param {Object} oBinaryFilter Filter object according to ListBinding#getFilterInfo
446
+ * @param {object} oBinaryFilter Filter object according to ListBinding#getFilterInfo
393
447
  * @returns {Array} Array containing this explicit filter setting
394
448
  * @private
395
449
  */
@@ -409,7 +463,7 @@ sap.ui.define([
409
463
  * Parses an unary filter and returns a modified
410
464
  * subsequent filter.
411
465
  *
412
- * @param {Object} oUnaryFilter Filter object according to ListBinding#getFilterInfo
466
+ * @param {object} oUnaryFilter Filter object according to ListBinding#getFilterInfo
413
467
  * @returns {Array} Array containing the modified subsequent filter
414
468
  * @private
415
469
  */
@@ -430,7 +484,7 @@ sap.ui.define([
430
484
  * Parses an call filter and returns an Array containing
431
485
  * this particular filter configuration.
432
486
  *
433
- * @param {Object} oCallFilter Filter object according to ListBinding#getFilterInfo
487
+ * @param {object} oCallFilter Filter object according to ListBinding#getFilterInfo
434
488
  * @returns {Array} Array containing this explicit filter setting
435
489
  * @private
436
490
  */
@@ -515,41 +569,6 @@ sap.ui.define([
515
569
  });
516
570
  },
517
571
 
518
- /**
519
- * Queries the Fiori Launchpad service for available cloud
520
- * export targets. If no cloud service is available or the
521
- * the user has no cloud export subscription, the Promise
522
- * returns an empty Array.
523
- *
524
- * @returns {Promise}
525
- * Array of available targets
526
- */
527
- getAvailableCloudExportTargets: function() {
528
- var servicePromise = Utils.getCloudExportService();
529
-
530
- return servicePromise.then(function(service) {
531
- return service && service.getSupportedTargets ? service.getSupportedTargets() : [];
532
- }).catch(function() {
533
- return [];
534
- });
535
- },
536
-
537
- /**
538
- * Returns the cloud export service. The availability of the service is
539
- * independent of a cloud export subscription. If no cloud export
540
- * service is available, which is the case on an On-Premise system, the
541
- * function returns null.
542
- *
543
- * @returns {Promise}
544
- * Promise that returns the cloud export service once it is resolved
545
- */
546
- getCloudExportService: function() {
547
- return sap.ushell
548
- && sap.ushell.Container
549
- && sap.ushell.Container.getServiceAsync
550
- ? sap.ushell.Container.getServiceAsync('ProductivityIntegration') : Promise.reject();
551
- },
552
-
553
572
  /**
554
573
  * This function saves the provided Blob to the local file system.
555
574
  * The parameter name is optional and depending on the browser it
@@ -608,33 +627,24 @@ sap.ui.define([
608
627
  * can lead to throwing an <code>Error</code>. Missing or incorrect information might get adjusted by either
609
628
  * default values or by truncating the original value.
610
629
  *
611
- * @param {Object} mSettings Export settings that will be validated
630
+ * @param {object} mSettings Export settings that will be validated
612
631
  * @param {number} mSettings.count Expected amount of data that will be available on the service
613
- * @param {Object} mSettings.dataSource DataSource configuration that will be used to fetch the data
632
+ * @param {object} mSettings.dataSource DataSource configuration that will be used to fetch the data
614
633
  * @param {string} mSettings.fileName Name of the exported file
615
634
  * @param {string} mSettings.fileType Member of sap.ui.export.FileType
616
635
  * @param {boolean} mSettings.showProgress Controls whether the progress dialog will be shown during export or not
617
- * @param {Object} mSettings.workbook Export settings that are relevant for the file structure
636
+ * @param {object} mSettings.workbook Export settings that are relevant for the file structure
618
637
  * @param {boolean} mSettings.worker Controls whether the export will be run in a dedicated Web Worker or not
619
- * @param {Object} mSettings.customizing Contains export customizing like currency and unit scale settings
638
+ * @param {object} mSettings.customizing Contains export customizing like currency and unit scale settings
620
639
  *
621
640
  * @since 1.78
622
641
  */
623
642
  validateSettings: function(mSettings) {
624
- var sExtension;
625
643
 
626
644
  /* Validate dataSource */
627
645
  Utils._validateDataSource(mSettings.dataSource);
628
646
 
629
- /* Validate fileName and fileType */
630
- mSettings.fileType = FileType[mSettings.fileType] ? mSettings.fileType : FileType.XLSX;
631
- sExtension = '.' + mSettings.fileType.toLowerCase();
632
- mSettings.fileName = mSettings.fileName || 'export' + sExtension;
633
-
634
- if (!mSettings.fileName.endsWith(sExtension)) {
635
- mSettings.fileName += sExtension;
636
- Log.warning(CLASS_NAME + ': fileName was missing the proper file extension - extension has been added');
637
- }
647
+ Utils.validateFileSettings(mSettings);
638
648
 
639
649
  /* Validate showProgress */
640
650
  if (typeof mSettings.showProgress !== 'boolean') {
@@ -654,10 +664,24 @@ sap.ui.define([
654
664
  Utils._validateScaleCustomizing(mSettings.customizing, 'unit');
655
665
  },
656
666
 
667
+ validateFileSettings: function(mSettings) {
668
+ var sExtension;
669
+
670
+ /* Validate fileName and fileType */
671
+ mSettings.fileType = FileType[mSettings.fileType] ? mSettings.fileType : FileType.XLSX;
672
+ sExtension = '.' + mSettings.fileType.toLowerCase();
673
+ mSettings.fileName = mSettings.fileName || 'export' + sExtension;
674
+
675
+ if (!mSettings.fileName.endsWith(sExtension)) {
676
+ mSettings.fileName += sExtension;
677
+ Log.info(CLASS_NAME + ': fileName was missing the proper file extension - extension has been added');
678
+ }
679
+ },
680
+
657
681
  /**
658
682
  * Validates the datasource configuration.
659
683
  *
660
- * @param {Object} mDataSource DataSource configuration that will be used to fetch the data
684
+ * @param {object} mDataSource DataSource configuration that will be used to fetch the data
661
685
  * @param {number|null} mDataSource.count Amount of data that will be requested from the service
662
686
  * @param {Array} [mDataSource.data] Array of data that will be exported
663
687
  * @param {string} [mDataSource.dataUrl] URL that is used to request the data from the backend
@@ -741,9 +765,9 @@ sap.ui.define([
741
765
  * Validates the workbook configuration that contains information about the columns,
742
766
  * the hierarchyLevel and meta information.
743
767
  *
744
- * @param {Object} mWorkbook Configuration of the Spreadsheet workbook
768
+ * @param {object} mWorkbook Configuration of the Spreadsheet workbook
745
769
  * @param {Array} mWorkbook.columns Column definition of the worksheet
746
- * @param {Object} mWorkbook.context Meta information that is written to the generated file
770
+ * @param {object} mWorkbook.context Meta information that is written to the generated file
747
771
  * @param {string} mWorkbook.hierarchyLevel Name of the property that contains the hierarchy level information
748
772
  *
749
773
  * @since 1.78
@@ -831,7 +855,7 @@ sap.ui.define([
831
855
  });
832
856
 
833
857
  /* Validate string based properties (not column type String related) */
834
- ['inputFormat', 'unit', 'unitProperty', 'template', 'trueValue', 'falseValue'].forEach(function(sProperty) {
858
+ ['inputFormat', 'unit', 'unitProperty', 'template', 'trueValue', 'falseValue', 'timezone', 'timezoneProperty'].forEach(function(sProperty) {
835
859
  Utils._validateString(oColumn, sProperty);
836
860
  });
837
861
 
@@ -855,11 +879,27 @@ sap.ui.define([
855
879
  }
856
880
 
857
881
  /* Validate utc property */
858
- if (oColumn.utc != null && (oColumn.type === EdmType.Date || oColumn.type === EdmType.Time)) {
859
- oColumn.utc = true; // Date and Time always use UTC
860
- }
861
882
  if (oColumn.type === EdmType.DateTime) {
862
- Utils._validateProperty(oColumn, 'utc', 'boolean', true);
883
+
884
+ /*
885
+ * Apply local time or UTC as fixed timezone
886
+ * in case no timezone is defined. This also
887
+ * serves as a fallback if timezoneProperty
888
+ * is defined but the Line Item has no value
889
+ * for the referenced property name.
890
+ */
891
+ if (!oColumn.timezone) {
892
+ oColumn.timezone = oColumn.utc === false ? new Intl.DateTimeFormat().resolvedOptions().timeZone : 'UTC';
893
+ }
894
+
895
+ /* Remove obviously incorrect timezoneProperty settings */
896
+ if (oColumn.property === oColumn.timezoneProperty || (typeof oColumn.timezoneProperty === 'string' && oColumn.timezoneProperty.split(',').length > 1)) {
897
+ Log.warning(CLASS_NAME + ': Property timezoneProperty is invalid.');
898
+ delete oColumn.timezoneProperty;
899
+ }
900
+ } else if (typeof oColumn.utc === 'boolean') {
901
+ Log.warning(CLASS_NAME + ': Property utc is only supported for type DateTime.');
902
+ delete oColumn.utc;
863
903
  }
864
904
 
865
905
  /* Validate scale property */
@@ -892,7 +932,7 @@ sap.ui.define([
892
932
  /**
893
933
  * Validates and fixes the type definition of a particular column if possible.
894
934
  *
895
- * @param {Object} oColumn Export settings of a particular column
935
+ * @param {object} oColumn Export settings of a particular column
896
936
  * @since 1.84
897
937
  * @private
898
938
  */
@@ -932,9 +972,9 @@ sap.ui.define([
932
972
  /**
933
973
  * Validates the context object on the workbook definition.
934
974
  *
935
- * @param {Object} oContext Context object
975
+ * @param {object} oContext Context object
936
976
  * @param {string} [oContext.application] Name of the application (default: "SAP UI5")
937
- * @param {string} [oContext.version] Application version (default: "1.100.0")
977
+ * @param {string} [oContext.version] Application version (default: "1.102.1")
938
978
  * @param {string} [oContext.title] Title that will be written to the file (NOT the filename)
939
979
  * @param {string} [oContext.modifiedBy] Optional user context that will be written to the file
940
980
  * @param {string} [oContext.sheetName] Name of the data sheet - Maximum length of 31 characters
@@ -978,7 +1018,7 @@ sap.ui.define([
978
1018
  * the value will be adjusted or discarded and the function writes an entry to the Log. If the property value
979
1019
  * exceeds the maximum allowed length, it will be truncated.
980
1020
  *
981
- * @param {Object} oContext Context on which the property is defined
1021
+ * @param {object} oContext Context on which the property is defined
982
1022
  * @param {string} sProperty Name of the property
983
1023
  * @param {string} sDefaultValue Default value that gets applied in case of an invalid value - null if not defined
984
1024
  * @param {number} [iMaxLength] Maximum allowed length.
@@ -1011,7 +1051,7 @@ sap.ui.define([
1011
1051
  * Once the property value does not meet the criteria, the value will be discarded and
1012
1052
  * the function writes an entry to the Log.
1013
1053
  *
1014
- * @param {Object} oContext Context on which the property is defined
1054
+ * @param {object} oContext Context on which the property is defined
1015
1055
  * @param {string} sProperty Name of the property
1016
1056
  * @param {string} sType Expected type of the property
1017
1057
  * @param {Any} [defaultValue] Default value that gets applied if the initial value is invalid
@@ -1028,16 +1068,16 @@ sap.ui.define([
1028
1068
  value = null;
1029
1069
  }
1030
1070
 
1031
- oContext[sProperty] = value == null && defaultValue ? defaultValue : value;
1071
+ oContext[sProperty] = value == null && typeof defaultValue !== 'undefined' ? defaultValue : value;
1032
1072
  },
1033
1073
 
1034
1074
  /**
1035
1075
  * Validates the unit specific scale settings and ensures
1036
1076
  * that the format is according to the definition.
1037
1077
  *
1038
- * @param {Object} oCustomizing General export customizing
1039
- * @param {Object} oCustomizing.currency Currency specific customizing
1040
- * @param {Object} oCustomizing.unit Unit of measure specific customizing
1078
+ * @param {object} oCustomizing General export customizing
1079
+ * @param {object} oCustomizing.currency Currency specific customizing
1080
+ * @param {object} oCustomizing.unit Unit of measure specific customizing
1041
1081
  * @param {string} sProperty Key property of the specific customizing setting
1042
1082
  * @private
1043
1083
  */
@@ -1071,7 +1111,7 @@ sap.ui.define([
1071
1111
  * by FileType. The default class is sap/ui/export/Spreadsheet when
1072
1112
  * no specific FileType is defined in the export settings.
1073
1113
  *
1074
- * @param {Object} mSettings Export configuration with optional FileType
1114
+ * @param {object} mSettings Export configuration with optional FileType
1075
1115
  * @returns {Promise} A Promise that gets resolved with the requested instance
1076
1116
  */
1077
1117
  getExportInstance: function(mSettings) {
@@ -1118,6 +1158,84 @@ sap.ui.define([
1118
1158
  }
1119
1159
 
1120
1160
  return iCount;
1161
+ },
1162
+
1163
+ /**
1164
+ * Splits up all column settings that reference multiple
1165
+ * properties as well as amounts and currency codes.
1166
+ *
1167
+ * The function returns an array with the updated column
1168
+ * configuration for the export.
1169
+ *
1170
+ * @param {Array} aColumns Export-related column configuration that will be split up if necessary
1171
+ * @param {function} [fnResolveColumnLabel] Resolves the label for a particular column that is not directly reflected
1172
+ * @returns {Array} Updated column configuration
1173
+ */
1174
+ splitColumns: function(aColumns, fnResolveColumnLabel) {
1175
+ var aResult = [];
1176
+
1177
+ aColumns.forEach(function(oColumn) {
1178
+ var aSplittedColumns, oUpdatedColumn, oAdditionalColumn, sColumnLabel;
1179
+
1180
+ /* Split EdmType.String columns with multiple properties */
1181
+ if (Array.isArray(oColumn.property) && oColumn.property.length > 1) {
1182
+ oUpdatedColumn = Object.assign({}, oColumn);
1183
+ aSplittedColumns = [oUpdatedColumn];
1184
+
1185
+ /* Ignore the leading property */
1186
+ oUpdatedColumn.property.slice(1).forEach(function(sProperty, iIndex) {
1187
+ sColumnLabel = typeof fnResolveColumnLabel === 'function' ? fnResolveColumnLabel(sProperty) : null;
1188
+ oAdditionalColumn = {
1189
+ property: sProperty,
1190
+ label: sColumnLabel || oColumn.label + ' (' + (iIndex + 1) + ')'
1191
+ };
1192
+
1193
+ aSplittedColumns.push(oAdditionalColumn);
1194
+ });
1195
+
1196
+ oUpdatedColumn.property = oUpdatedColumn.property[0];
1197
+ delete oUpdatedColumn.template;
1198
+ }
1199
+
1200
+ /* Split EdmType.Currency and EdmType.Number columns */
1201
+ if (oColumn.unitProperty && oColumn.displayUnit !== false) { // displayUnit is assumed to be true by default - so undefined needs to be treated like true
1202
+ oUpdatedColumn = Object.assign({}, oColumn);
1203
+ sColumnLabel = typeof fnResolveColumnLabel === 'function' ? fnResolveColumnLabel(oColumn.unitProperty) : null;
1204
+ aSplittedColumns = [oUpdatedColumn, {
1205
+ property: oColumn.unitProperty,
1206
+ label: sColumnLabel || oColumn.label + ' (1)'
1207
+ }];
1208
+
1209
+ if (oUpdatedColumn.type === EdmType.Currency) {
1210
+ oUpdatedColumn.displayUnit = false;
1211
+ }
1212
+
1213
+ if (oUpdatedColumn.type === EdmType.Number) {
1214
+ delete oUpdatedColumn.unitProperty;
1215
+ }
1216
+ }
1217
+
1218
+ aResult.push(aSplittedColumns || oColumn);
1219
+ });
1220
+
1221
+ return aResult.flat();
1222
+ },
1223
+
1224
+ /**
1225
+ * Returns a <code>Promise</code> that resolves with the
1226
+ * <code>ResourceBundle</code> of the sap.ui.export library.
1227
+ *
1228
+ * @returns {Promise} <code>Promise</code> with the <code>ResourceBundle</code>
1229
+ */
1230
+ getResourceBundle: function() {
1231
+ if (!oResourceBundle) {
1232
+ return Core.getLibraryResourceBundle('sap.ui.export', true).then(function(oBundle) {
1233
+ oResourceBundle = oBundle;
1234
+
1235
+ return oResourceBundle;
1236
+ });
1237
+ }
1238
+ return Promise.resolve(oResourceBundle);
1121
1239
  }
1122
1240
  };
1123
1241