{
"d": {
"results": [
{
"__metadata": {
"uri": "http://services.odata.org/V2/northwind/Northwind.svc/Customers('ALFKI')",
"type": "NorthwindModel.Customer"
},
"CustomerID": "ALFKI",
"CompanyName": "Alfreds Futterkiste",
"ContactName": "Maria Anders",
"ContactTitle": "Sales Representative",
"Address": "Obere Str. 57",
"City": "Berlin",
"Region": null,
"PostalCode": "12209",
"Country": "Germany",
"Phone": "030-0074321",
"Fax": "030-0076545",
"Orders": {
"__deferred": {
"uri": "http://services.odata.org/V2/northwind/Northwind.svc/Customers('ALFKI')/Orders"
}
},
"CustomerDemographics": {
"__deferred": {
"uri": "http://services.odata.org/V2/northwind/Northwind.svc/Customers('ALFKI')/CustomerDemographics"
}
}
},
...
sap.ui.define([
"sap/ui/base/Object"
], function(BaseObject) {
"use strict";
/**
* Abstract class which generates files based on OData REST sources.
*
* The implementing subclasses define which specific file type will be generated.
* This class is not tuned for a maximum of performance but for easy extendability.
*
* @class
* @public
* @name com.utils.FileGenerator
*/
var FileGenerator = BaseObject.extend("com.utils.FileGenerator", {
/**
* @param {array} [aSkipAttributes] Array of attributes which will be skipped during file generation.
* This is useful to hide fields and metadata. If the parameter is null,
* only the default attribute "__metadata" will be skipped.
* @public
*/
constructor: function(aSkipAttributes) {
/**
* Array of attributes which will be skipped during file generation.
* @private
*/
this._aSkipAttributes = aSkipAttributes || ["__metadata"];
},
/**
* Extracts the header row and applies the cell processor function on each label.
* @param {array} aRows An array of rows. This is usually the result set from the OData response.
* @param {function} fnCellProcessor Function which will be called on each data field. The function
* will be given the data field as the only parameter.
* @param {function} fnLineBreakProcessor Function which will be called after each row to handle any line breaks.
* @private
*/
_extractHeader: function(aRows, fnCellProcessor, fnLineBreakProcessor) {
if (aRows.length > 0) {
this._deleteSkippedAttributes(aRows[0]);
Object.keys(aRows[0]).forEach(function(sHeader) {
fnCellProcessor(sHeader);
});
fnLineBreakProcessor();
}
},
/**
* Loops over each row in aRows and applies the cell processor function on each data cell.
* The first row in aRows is treated as the column header.
* @param {array} aRows An array of rows. This is usually the result set from the OData response.
* @param {function} fnCellProcessor Function which will be called on each data field. The function
* will be given the data field as the only parameter.
* @param {function} fnLineBreakProcessor Function which will be called after each row to handle any line breaks.
* @protected
*/
loopDataRows: function(aRows, fnCellProcessor, fnLineBreakProcessor) {
var self = this;
this._extractHeader(aRows, fnCellProcessor, fnLineBreakProcessor);
aRows.forEach(function(oRow) {
// Remove unwanted attributes
self._deleteSkippedAttributes(oRow);
// Process each data cell (key, value)
Object.keys(oRow).forEach(function(sKey) {
// Processor can now use the cell value to create a file
fnCellProcessor(self._sanitizeCellValue(oRow[sKey]));
});
// Allow to handle line breaks
fnLineBreakProcessor();
});
},
/**
* Sanitizes the cell value by ignoring objects and only handling primitve value types.
* @param sCell The cell value to sanitize
* @return {string} Returns the parameter value if it is a string otherwise the empty string will be returend.
* @private
*/
_sanitizeCellValue: function(sCell) {
return sCell === undefined || sCell === null || typeof sCell === "object" ? "" : sCell;
},
/**
* Deletes every key of the skipAttributes member from the oRow.
* @param {object} oRow A single row (object) of the result set.
* @private
*/
_deleteSkippedAttributes: function(oRow) {
this._aSkipAttributes.forEach(function(oAttribute) {
delete oRow[oAttribute];
});
}
/**
* Generates a file (type specified by the subclass) from the odata result set.
*
* @param {array} aRows An array of rows. This is usually the result set from the OData response.
* @name com.utils.FileGenerator.prototype.generate
* @function
* @public
*/
/**
* Triggers a download from the browser to the generated file.
*
* @param {string} sFilename Filename of the download.
* @name com.utils.FileGenerator.prototype.download
* @function
* @public
*/
});
return FileGenerator;
});
/* global document */
sap.ui.define([
"com/utils/FileGenerator"
], function(
FileGenerator
) {
"use strict";
/**
* Creates a CSV file from an OData result set.
*
* @class
* @public
* @name com.utils.CSVGenerator
*/
var CSVGenerator = FileGenerator.extend("com.utils.CSVGenerator", {
/**
* @param {string} [sEscape] Escape symbol which is used to wrap each data field. Default is ".
* @param {string} [sSeparator] Data field separator symbol. Default is ";".
* @param {string} [sLinebreak] Line break symbol. Default is '\r\n'.
* @public
*/
constructor: function(sEscape, sSeparator, sLinebreak) {
FileGenerator.call(this);
this._sOutput = undefined;
this._sEscape = sEscape || '"';
this._sSeparator = sSeparator || ";";
this._sLinebreak = sLinebreak || '\r\n';
},
/**
* Appends the value to the output field. Separator and escape symbols are applied.
* @param {string} sValue The value of the data field.
* @private
*/
_processCell: function(sValue) {
this._sOutput += this._sEscape + sValue + this._sEscape + this._sSeparator;
},
/**
* Appends the line break symbol to the output.
* @private
*/
_processLineBreak: function() {
this._sOutput += this._sLinebreak;
},
/**
* Generates a CSV file from the odata result set.
*
* @param {array} aRows An array of rows. This is usually the result set from the OData response.
* The result set may be modified by this function.
* @public
*/
generate: function(aRows) {
this._sOutput = "";
// In parent object
this.loopDataRows(aRows, this._processCell.bind(this), this._processLineBreak.bind(this));
},
/**
* Triggers a download from the browser to the generated file.
* This is done by placing a hidden link in the DOM and triggering a click event on it.
* After the download the link is removed again.
* Ensure that the generate function has been called before, otherwise the download will not work.
*
* @param {string} sFilename Filename of the download.
* @public
*/
download: function(sFilename) {
if (this._sOutput !== undefined) {
var oLink = document.createElement("a");
oLink.href = "data:text/csv;charset=utf-8," + escape(this._sOutput);
oLink.style = "visibility:hidden";
oLink.download = sFilename + ".csv";
document.body.appendChild(oLink);
oLink.click();
document.body.removeChild(oLink);
}
}
});
return CSVGenerator;
});
var oCSVGenerator = new CSVGenerator();
this.getView().getModel().read("/MyODataResource", {
success: function(oData) {
oCSVGenerator.generate(oData.results);
oCSVGenerator.download("OData_Export");
}
});
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
17 | |
14 | |
12 | |
10 | |
9 | |
8 | |
7 | |
7 | |
6 | |
6 |