cancel
Showing results for 
Search instead for 
Did you mean: 

Service side pdf download problems (CAP)

0 Kudos
1,000

Hi Experts

My current problem is that i have to make a call to an external api and get a pdf as a response. This pdf should then be rebuilt on the UI side and downloaded directly.

The problem is that I have made many attempts, but I can never correctly convert the content of the response in order to recreate the file.

I've tried different methods: "window.atob", "encodedURIComponent", to make me return different types from the call (e.g. arraybuffer) but I haven't found any solutions.

Below I report the first part of the code for the call and then the content of the pdf that I get as a result, I hope it will help.

Thanks for the collaboration

service.js

srv.on("getPDFPrint", async (req) => {

    // Imposta i parametri della richiesta
    let params = {
      LinkedSAPObjectKey: "'" + req.data.DocumentId.padStart(10, '0') + "'",
      BusinessObjectTypeName: "'VBRK'",
      'sap-language': "'IT'"
    };

    //create the url
    let url = "/GetAllOriginals?";
    Object.keys(params).forEach(function (key) {
      url += key + "=" + params[key] + "&";
    });
    url.substring(0, url.length - 1); //remove last '&'

    //first call
    let resultAllOriginals = await PDFApi.tx().get(url);
    resultAllOriginals = resultAllOriginals[0];

    //if there are no results, return an error
    if (!resultAllOriginals)
      return -1;

    //take the new url from the result
    url = resultAllOriginals.$metadata.media_src;
    url = url.substring(url.indexOf(PDFApi.path) + PDFApi.path.length); //remove destination's path

    return (await PDFApi.tx().get(url));

  });<br>

Usually i save my resault in "sBase64", and process it like this

// decodifica la stringa in base64
var sDecoded = window.atob(sBase64);

// crea un oggetto Blob contenente i dati decodificati
let byteArray = Uint8Array.from(sDecoded, c => c.charCodeAt(0))
var oBlob = new Blob([byteArray], { type: "application/pdf" });

let url = window.URL.createObjectURL(oBlob)

// crea un link temporaneo per scaricare il file
var link = document.createElement("a");
link.href = url;
link.download = DocumentId+".pdf";
document.body.appendChild(link);
link.click();
			
// rimuovi il link temporaneo e l'URL
document.body.removeChild(link);
window.URL.revokeObjectURL(url);

Accepted Solutions (0)

Answers (1)

Answers (1)

nicorunge
Participant
0 Kudos

Hi Mattia,

when looking at the response-pdf.txt, it could be that the PDF data becomes corrupted because it gets encoded to utf-8 per default from axios which is used under the hood by cap/sap-cloud-sdk. Try to add a responseType: 'arraybuffer' as header parameter in your PDFApi.get call.

BR, Nico

0 Kudos

Hi Nicolas,

thanks for your answer, however I also tried to implement something like this --> result = await PDFApi.send({ query: 'GET ' + url, responseType: 'arraybuffer'});

Unfortunately, however, the result obtained does not seem to be different

BR, Mattia

nicorunge
Participant
0 Kudos

Hi Mattia,

so when fetching the document in your CAP handler and then writing it to the local file system (using fs.writeFileSync) it is still okay?
And it only breaks in the frontend when converting/downloading?

0 Kudos

Hi Nicolas,

when I call the API (www.example.com/APIPath(ID="100", ID2="100")/$value) I can download the PDF successfully.

When I call the api in service.js, it's like downloading a blank pdf; I also tried to use fs.writeFileSync, but when I open the created file on the client side, the result is a pdf with the correct number of pages, but all completely blank

Best, Mattia

nicorunge
Participant
0 Kudos

Ok, so when fetching the file with await PDFApi.tx().get(url) and writing it to the file system in the getPDFPrint handler, the file it is already corrupted.

I still believe it is some encoding problem. Can you try to fetch the file using plain axios calls or using the sap-cloud-sdk instead of using the CAP PDFApi connection?