Use Case:
When the user clicks the “CSV” button, the application will fetch the accounting document details and it will then prepare a CSV file. This CSV file will then be downloaded and stored in the local filesystem on the user’s device.
The screenshot below shows the CAP application UI, which includes a custom button to trigger CSV generation and download.
The downloaded CSV looks like the screenshot below:
Implementation Steps:
Define a Virtual field in serviceHandler logic to generate and download csvImporting necessary modulesImplementing the Read HandlerPreparing the JSON ContentConverting the JSON to CSVConverting CSV data to buffer to downloadConverting “Open file” link to a button in the UI
Define a Virtual field in service: Define a virtual field at the service level with type “LargeBinary” and media type “application/csv”.
entity Documents {
key ID : UUID;
name : String;
virtual null as csv : LargeBinary @Core.MediaType: ‘application/csv’,
}
This will automatically generate a hyperlink labelled “Open File” in the UI as shown in the screenshot below.
Handler logic to generate and download csv:
To download an accounting document in CSV format, first, retrieve the accounting Document with Book and accounting Principle details for the specified document ID using a database transaction. Then, convert the csv data to a buffer. Finally, set the file name based on the accounting document ID and specify the content type as CSV.
Importing Necessary Modules
To handle the conversion and streaming of the CSV content, you’ll require the Buffer and Readable modules from Node.js and json2csv library to convert the Json data to csv format. Import these modules into your project with the following code:
import { Buffer } from “buffer”;
import { Readable } from “stream”;
import { json2csv } from “json-2-csv”;
Add the “json2csv” library through package.json
“dependencies”: {
“json-2-csv”: “^5.5.1”,
Implementing the Read Handler:
In the Read handler of the entity, verify if the URL path includes “csv”. (name of the virtual field defined in your entity). If you have named the virtual field differently, ensure to check for that specific name in the URL.
virtual null as csv : LargeBinary @Core.MediaType: ‘application/csv’,
If the URL path contains the specified virtual field name(url.includes(“csv”)), proceed to generate the CSV content. Convert this CSV content into buffer data, push the buffered data into a Readable stream, and return it. Make sure to include the media content type and the disposition filename in the response.
Example:
/dch/ui/accounting/documents/Documents(${object.ID})/csv
Preparing the JSON content :
Construct the JSON content with the retrieved data from the database.
let documentOutputValue: RetrieveDocumentDetails = {
“Entity Type”: EntityTypeCodes.ACCOUNTING_DOCUMENT,
ID: documentsHeaderData.displayId.toString(),
Company: companyData.name,
“Accounting Principle”: accountingPrincipleData.code,
“Key Date”: documentsHeaderData.CutOffDate,
“Created On”: documentsHeaderData.createdAt,
“Created By”: documentsHeaderData.createdBy,
“Item ID”: “”,
“Item Type”: “”,
“Amount (Position Currency)”: “”,
“Position Currency”: “”,
“Amount (Local Currency)”: “”,
“Local Currency”: “”,
Text: “SAP Digital Currency Hub”
};
Converting the JSON to CSV:
Convert the JSON content to CSV format by passing the JSON data to the json2csv library function, enabling the download of the data as a file.
//Prepare csv output file
const csvOptions = {
delimiter: {
wrap: ‘”‘,
field: “;”, // specify the delimiter here
eol: “n”
}
};
const csvOutput = json2csv(documentOutput, csvOptions);
Converting CSV data to buffer to download:
Adding the CSV data to a buffer is necessary because buffers handle raw binary data, which is useful for file operations such as downloading. Converting the CSV data to a buffer ensures that the data is correctly encoded and can be managed efficiently for creating the downloadable file. This step is crucial for maintaining data integrity during the download process.
BufferData = Buffer.from(csvOutput, “utf8”);
fileName = `AccountingDocument${documentsHeaderData.displayId}.csv`;
contentType = “application/csv”;
return this.returnBufferContents(BufferData, fileName, contentType);
Converting “Open File” link to a button in the UI:
Define a UI Fragment that contains a button with the handler in app/webapp/ext/fragment section.
<core:FragmentDefinition xmlns:core=”sap.ui.core” xmlns=”sap.m”>
<Button
core:require=”{ handler: ‘sap/erp4sme/c4b/accounting/documents/ext/fragment/ActionCsvDownload’}”
text=”CSV” press=”handler.onPress” />
</core:FragmentDefinition>
Create a handler for the button that, when pressed, displays a toast message saying “DownloadingCSV” and then redirects the browser to the CSV URL.
sap.ui.define([
“sap/m/MessageToast”
], function (MessageToast) {
‘use strict’;
return {
onPress: function (oEvent) {
const view = this.editFlow.getView();
const i18nModelBundle = view.getModel(“i18n”).getResourceBundle();
MessageToast.show(i18nModelBundle.getText(“DownloadingCSV”));
const object = oEvent.getSource().getBindingContext().getObject();
sap.m.URLHelper.redirect(`/dch/ui/accounting/documents/Documents(${object.ID})/csv`, true);
}
};
});
Add the fragment in the columns section in manifest.json.
“ActionCsvDownload”: {
“header”: “{i18n>downloadcsv}”,
“position”: {
“anchor”: “DataFieldForAction::DocumentsUiService.unconfirmPosting”,
“placement”: “After”
},
“template”: “sap.erp4sme.c4b.accounting.documents.ext.fragment.ActionCsvDownload”,
“horizontalAlign”: “Center”,
“width”: “5em”
}
Use Case: When the user clicks the “CSV” button, the application will fetch the accounting document details and it will then prepare a CSV file. This CSV file will then be downloaded and stored in the local filesystem on the user’s device.The screenshot below shows the CAP application UI, which includes a custom button to trigger CSV generation and download.The downloaded CSV looks like the screenshot below:Implementation Steps:Define a Virtual field in serviceHandler logic to generate and download csvImporting necessary modulesImplementing the Read HandlerPreparing the JSON ContentConverting the JSON to CSVConverting CSV data to buffer to downloadConverting “Open file” link to a button in the UIDefine a Virtual field in service: Define a virtual field at the service level with type “LargeBinary” and media type “application/csv”.entity Documents { key ID : UUID; name : String; virtual null as csv : LargeBinary @Core.MediaType: ‘application/csv’,} This will automatically generate a hyperlink labelled “Open File” in the UI as shown in the screenshot below.Handler logic to generate and download csv:To download an accounting document in CSV format, first, retrieve the accounting Document with Book and accounting Principle details for the specified document ID using a database transaction. Then, convert the csv data to a buffer. Finally, set the file name based on the accounting document ID and specify the content type as CSV.Importing Necessary ModulesTo handle the conversion and streaming of the CSV content, you’ll require the Buffer and Readable modules from Node.js and json2csv library to convert the Json data to csv format. Import these modules into your project with the following code:import { Buffer } from “buffer”;import { Readable } from “stream”;import { json2csv } from “json-2-csv”;Add the “json2csv” library through package.json “dependencies”: { “json-2-csv”: “^5.5.1”,Implementing the Read Handler:In the Read handler of the entity, verify if the URL path includes “csv”. (name of the virtual field defined in your entity). If you have named the virtual field differently, ensure to check for that specific name in the URL. virtual null as csv : LargeBinary @Core.MediaType: ‘application/csv’,If the URL path contains the specified virtual field name(url.includes(“csv”)), proceed to generate the CSV content. Convert this CSV content into buffer data, push the buffered data into a Readable stream, and return it. Make sure to include the media content type and the disposition filename in the response.Example:/dch/ui/accounting/documents/Documents(${object.ID})/csvPreparing the JSON content :Construct the JSON content with the retrieved data from the database.let documentOutputValue: RetrieveDocumentDetails = { “Entity Type”: EntityTypeCodes.ACCOUNTING_DOCUMENT, ID: documentsHeaderData.displayId.toString(), Company: companyData.name, “Accounting Principle”: accountingPrincipleData.code, “Key Date”: documentsHeaderData.CutOffDate, “Created On”: documentsHeaderData.createdAt, “Created By”: documentsHeaderData.createdBy, “Item ID”: “”, “Item Type”: “”, “Amount (Position Currency)”: “”, “Position Currency”: “”, “Amount (Local Currency)”: “”, “Local Currency”: “”, Text: “SAP Digital Currency Hub” };Converting the JSON to CSV:Convert the JSON content to CSV format by passing the JSON data to the json2csv library function, enabling the download of the data as a file. //Prepare csv output file const csvOptions = { delimiter: { wrap: ‘”‘, field: “;”, // specify the delimiter here eol: “n” } }; const csvOutput = json2csv(documentOutput, csvOptions);Converting CSV data to buffer to download:Adding the CSV data to a buffer is necessary because buffers handle raw binary data, which is useful for file operations such as downloading. Converting the CSV data to a buffer ensures that the data is correctly encoded and can be managed efficiently for creating the downloadable file. This step is crucial for maintaining data integrity during the download process. BufferData = Buffer.from(csvOutput, “utf8”); fileName = `AccountingDocument${documentsHeaderData.displayId}.csv`; contentType = “application/csv”; return this.returnBufferContents(BufferData, fileName, contentType);Converting “Open File” link to a button in the UI:Define a UI Fragment that contains a button with the handler in app/webapp/ext/fragment section.<core:FragmentDefinition xmlns:core=”sap.ui.core” xmlns=”sap.m”> <Button core:require=”{ handler: ‘sap/erp4sme/c4b/accounting/documents/ext/fragment/ActionCsvDownload’}” text=”CSV” press=”handler.onPress” /></core:FragmentDefinition>Create a handler for the button that, when pressed, displays a toast message saying “DownloadingCSV” and then redirects the browser to the CSV URL.sap.ui.define([ “sap/m/MessageToast”], function (MessageToast) { ‘use strict’; return { onPress: function (oEvent) { const view = this.editFlow.getView(); const i18nModelBundle = view.getModel(“i18n”).getResourceBundle(); MessageToast.show(i18nModelBundle.getText(“DownloadingCSV”)); const object = oEvent.getSource().getBindingContext().getObject(); sap.m.URLHelper.redirect(`/dch/ui/accounting/documents/Documents(${object.ID})/csv`, true); } };});Add the fragment in the columns section in manifest.json. “ActionCsvDownload”: { “header”: “{i18n>downloadcsv}”, “position”: { “anchor”: “DataFieldForAction::DocumentsUiService.unconfirmPosting”, “placement”: “After” }, “template”: “sap.erp4sme.c4b.accounting.documents.ext.fragment.ActionCsvDownload”, “horizontalAlign”: “Center”, “width”: “5em” } Read More Technology Blogs by SAP articles
#SAP
#SAPTechnologyblog
+ There are no comments
Add yours