Skip to Content
Technical Articles
Author's profile photo Jacky Liu

Call BTP SAP Print Service To Print Document In BTP UI5 Application

In my blog Test BTP SAP Print Service With Postman, I have explained how to SAP Print Service with postman. In this blog, I will explain how to use it to print document in an UI5 application deployed in BTP cloud foundry run time. To use a PDF document, I will combine the code with my blog Render and View PDF in SAP UI5 with Forms service by adobe in BTP.

Prerequisite:

1, You have installed CF Client .

2, You have installed Nodejs .

3,  You have installed  Cloud MTA Build Tool .

4, You have finished  Initial Setup for Document Management Service, Integration Option.

5, You have finished Onboarding Repository.

6, Destination for CMIS service key has been created as step 1 in  blog .

7, You have installed VSCode (optional).

Steps :

Step 1:  Generate SAPUI5 project with easy-ui5 .

Use the following commands to open the project with visual code .

 

Step 2:  Change the view MainView.view as the following code:

<View controllerName="com.sap.printui5.controller.MainView" xmlns:mvc="sap.ui.core.mvc" xmlns:core="sap.ui.core" displayBlock="true" xmlns="sap.m">
	<Page id="page" title="{i18n>title}" showNavButton="true">
		<content>
			<VBox width="100%" direction="Column" id="vbox0" alignContent="Center">
				<items>
					<HBox width="100%" id="hbox1">
						<items>
							<Label id="filenamel" width="200px" class="sapUiSmallMargin" text="FileName:" />
							<Input id="filename" width="200px"  editable="true" />
						</items>
					</HBox>
					<HBox id="hbox4">
						<Select id="select1" showSecondaryValues="true" width="200px" class="sapUiSmallMargin" items="{ path: '/templates' }">
							<core:ListItem id="listitem1" text="{name}" />
						</Select>
						<Button text="PDF Render" id="button2" class="sapUiSmallMargin" type="Emphasized" width="200px" press="pdfRender" />
					</HBox>
				</items>
				<HBox width="100%" id="hbox5">
					<Select id="select" showSecondaryValues="false" class="sapUiSmallMargin" width="200px" items="{ path: '/printQs' }">
						<core:ListItem id="listitem" text="{qname}" additionalText="{qdescription}" />
					</Select>
					<Button text="Send To PrintQ" id="button3" class="sapUiSmallMargin" type="Emphasized" width="200px" press="pdfPrint" />
				</HBox>
				<ScrollContainer id="scrollc1" height="100%" width="100%" horizontal="true" vertical="true">
					<FlexBox id="flexb1" direction="Column" renderType="Div" class="sapUiSmallMargin">
						<PDFViewer id="pdfview" source="{/Source}" title="{/Title}" height="{/Height}">
							<layoutData>
								<FlexItemData id="flexitemdata1" growFactor="1" />
							</layoutData>
						</PDFViewer>
					</FlexBox>
				</ScrollContainer>
			</VBox>
		</content>
	</Page>
</View>

Step 3:  Create folder service under webapp, create file named FileUpload.js under folder service . Change the file FileUpload.js as the following code:

// @ts-ignore

sap.ui.define("FileUpload", [
    "sap/ui/base/Object"
], function (ui5Object) {
    "use strict";
    return ui5Object.extend("ui5applicationmodule.service.FileUpload", {

        printDm: function (content, filename) {
            return new Promise((resolve, reject) => {
                // @ts-ignore
                var data = new FormData();
                data.append("media", content, filename)
                let request = new Request("/print/dm/api/v1/rest/print-documents", { method: "POST", body: data });
                request.headers.append("scan", "true");
                request.headers.append("If-None-Match", "*");
                request.headers.append("DataServiceVersion", "2.0");
                request.headers.append("Accept", "*/*")
                fetch(request).then(res => res.text()).then(data => resolve(data)
                ).catch(err => reject(err));

            });
        },
        printTask: function (dmId, qname, filename) {
            return new Promise((resolve, reject) => {
                var url = "/print/qm/api/v1/rest/print-tasks/".concat(dmId);
                var bodyJson = {
                    "numberOfCopies": 1,
                    "username": "test user",
                    "qname": qname,
                    "metadata": {
                        "business_metadata": {
                            "business_user": "user1",
                            "object_node_type": "object_node_1"
                        },
                        "version": 1.2
                    },
                    "printContents": [
                        {
                            "objectKey": dmId,
                            "documentName": filename
                        }
                    ]
                }
                var body = JSON.stringify(bodyJson);
                var myHeaders = new Headers();
                myHeaders.append("If-None-Match", "*");
                myHeaders.append("Content-Type", "application/json");
                var requestOptions = {
                    method: 'PUT',
                    headers: myHeaders,
                    body: body,
                    redirect: 'follow'
                };

                fetch(url, requestOptions).then(res => res.status).then(data => resolve(data)).catch(err => reject(err));
            })
        },
        getPrintq() {
            return new Promise((resolve, reject) => {
                // @ts-ignore
                const request = new Request("/print/qm/api/v1/rest/queues");
                request.headers.append("Content-Type", "application/json");
 
                // @ts-ignore
                fetch(request).then(res => res.json()).then(data => {
                    resolve(data)
                }).catch(err => {
                    reject(err);
                })

            })
        },

        render: function (template, content) {
            return new Promise((resolve, reject) => {
                // @ts-ignore
                var rendercont = btoa(content);
                var pdfcontent = {
                    embedFont: 0,
                    formLocale: "en_US",
                    formType: "print",
                    taggedPdf: 1,
                    xdpTemplate: template,
                    xmlData: rendercont
                };
                var myHeaders = new Headers();
                myHeaders.append("Content-Type", "application/json");

                var requestOptions = {
                    method: 'POST',
                    headers: myHeaders,
                    body: JSON.stringify(pdfcontent),
                    redirect: 'follow'
                };

                fetch("/adobeapi/v1/adsRender/pdf?templateSource=storageName&TraceLevel=0", requestOptions).then(res => res.json()).then(data => {
                    const deccont = atob(data.fileContent);
                    const byteNumbers = new Array(deccont.length);
                    for (let i = 0; i < deccont.length; i++) {
                        byteNumbers[i] = deccont.charCodeAt(i);
                    }
                    const byteArray = new Uint8Array(byteNumbers);
                    const blob = new Blob([byteArray], { type: "application/pdf" });
                    const docurl = URL.createObjectURL(blob);
                    resolve(docurl);

                }).catch(err => reject(err));
            });
        },
        getTemplates: function () {
            return new Promise((resolve, reject) => {
                var request = new Request("/adobeapi/v1/forms");
                var templates = [];

                var temp = "";
                fetch(request).then(res => res.json()).then(data => {
                    data.forEach(form => {
                        temp = form.formName
                        form.templates.forEach(template => {
                            temp = temp.concat("/").concat(template.templateName);
                            templates.push({ "name": temp });
                            temp = "";
                        });
                    });
                    resolve(templates)
                }).catch(err => reject(err));
            });
        }
    });

})

Step 4:  Change the controller MainView.controller.js as the following code:

sap.ui.define(
    ["./BaseController",
        "sap/m/MessageBox",
        "sap/base/security/URLWhitelist",
        "../service/FileUpload",
    "sap/ui/model/json/JSONModel"],
    /**
     * @param {typeof sap.ui.core.mvc.Controller} Controller
     */
    function (Controller, MessageBox, URLWhitelist, FileUpload,JSONModel) {
        "use strict";

        return Controller.extend("com.sap.printui5.controller.MainView", {
            onInit: function () {
                if (!this._fileUpload) {
                    this._fileUpload =  new FileUpload();
                }
                this._fileUpload.getPrintq().then(data => { 
                  
                    
                    this.byId("select").setModel(new JSONModel({"printQs":data}) ); }).catch(err => { MessageBox.information(JSON.stringify(err)) });

                this._fileUpload.getTemplates().then(data=>{
                    var model = new JSONModel({"templates": data});
                    this.byId("select1").setModel(model);
                }).catch(err=>{
                    console.log("template is empty")
                    MessageBox.information(JSON.stringify(err))});
            },
            pdfPrint: function(){
                if (!this._fileUpload) {
                    this._fileUpload = new FileUpload();
                }
                var printQ = this.byId("select").getSelectedItem().getText();
               var filename = this.byId("filename").getValue();
               var objurl = this.byId("pdfview").getSource();
               if(objurl&&filename){
               fetch(objurl).then(r=>r.blob()).then(blob=>{
                this._fileUpload.printDm(blob,filename).then(dmid=>{
                    console.log(dmid);
                    this._fileUpload.printTask(dmid,printQ,filename).then(data=>{
                        console.log(data);
                        if(data === 204){
                            MessageBox.information("document has been sent to ".concat(printQ))
                        }
                    })
                }).catch(err=>console.log(err))
               })}else{
                MessageBox.information("Please input filename or render pdf first");
               }
            },
            pdfRender: function () {

                var printd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><form1><LabelForm><DeliveryId>Mirum est ut animus agitatione motuque corporis excitetut.</DeliveryId><Position>Ego ille</Position><MaterialNo>Si manu vacuas</MaterialNo><Quantity>Apros tres et quidem</Quantity><Package>Mirum est</Package><QRCode>01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789</QRCode></LabelForm><LabelForm><DeliveryId>Ad retia sedebam: erat in proximo non venabulum aut lancea, sed stilus et pugilares:</DeliveryId><Position>Licebit auctore</Position><MaterialNo>Proinde</MaterialNo><Quantity>Am undique</Quantity><Package>Ad retia sedebam</Package><QRCode>01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789</QRCode></LabelForm><LabelForm><DeliveryId>meditabar aliquid enotabamque, ut, si manus vacuas, plenas tamen ceras reportarem.</DeliveryId><Position>Vale</Position><MaterialNo>Ego ille</MaterialNo><Quantity>Si manu vacuas</Quantity><Package>Apros tres et quidem</Package><QRCode>01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789</QRCode></LabelForm></form1>";

                var filename = this.getView().byId("filename").getValue();

                if (!this._fileUpload) {
                    this._fileUpload = new FileUpload();
                };
                var template = this.byId("select1").getSelectedItem().getText();

                this._fileUpload.render(template,printd).then(url => {
                    var pdfSource= new JSONModel({
                        "Source": url,
                        "Title":  "Outbound Delivery",
                        "Height": "600px"
                    }); 
                    URLWhitelist.add("blob");
                    this.byId("pdfview").setModel(pdfSource);

                }).catch(err => {
                    console.log("render failed");
                    console.log(err);
                })

            }
        });
    }
);


 

Step 5:  Add router in xs-app.json under folder approuter .

{
  "welcomeFile": "uimodule/index.html",
  "authenticationMethod": "none",
  "logout": {
    "logoutEndpoint": "/do/logout"
  },
  "routes": [
    {
      "source": "^/adobeapi/(.*)$",
      "target": "/$1",
      "authenticationType": "xsuaa",
      "csrfProtection": false,
      "destination": "adobeapi"
    },
    {
      "source": "^/print/(.*)$",
      "target": "/$1",
      "authenticationType": "xsuaa",
      "csrfProtection": false,
      "destination": "printServiceApi"
    },
    {
      "source": "^/uimodule/(.*)$",
      "target": "$1",
      "authenticationType": "none",
      "localDir": "uimodule/webapp"
    }
  ]
}

Step 6:  Create destination ‘adobeapi’ for form service by adobe and ‘printServiceApi’ for SAP Print Service with plan sender.

Name: adobeapi

Type: HTTP

URL: uri  from previous screen

Client ID: uaa>clientid.   from previous screen

Client Secret: uaa>clientsecret.  from previous screen

Token Service URL:  uaa>url + /oauth/token  from previous screen

Token Service User: uaa>clientid.   from previous screen

Token Service Password: uaa>clientid.   from previous screen

 

Name: printServiceApi

Type: HTTP

URL: service_url from previous screen

Client ID: uaa>clientid.   from previous screen

Client Secret: uaa>clientsecret.  from previous screen

Token Service URL:  uaa>url + /oauth/token  from previous screen

Token Service User: uaa>clientid.   from previous screen

Token Service Password: uaa>clientid.   from previous screen

Step 7:  Use the following command to build deploy the application to BTP cloud foundry run time.

mbt build

cf login

cf deploy mta_archives/printui5_0.0.1.mtar

Step 8:  Test the deployed application:

 

Step 9:  Check print task in print Queue:

 

The Ends

Thanks for your time!

Best regards!

Jacky Liu

Assigned Tags

      1 Comment
      You must be Logged on to comment or reply to a post.
      Author's profile photo Inês Martins
      Inês Martins

      Hello thank you so much for the post!

      I'm having "render failed" error, but checked everything and don't find what the problem is. Also tried to use Postman to try the connection and I'm getting "401 Unauthorized", but I've create the destination to ADS as you explained.

      Do you have any suggestions?