1. Luis Alberto Coca
  2. PowerBuilder
  3. Monday, 28 March 2022 00:50 AM UTC

I am using PB2019R3 consuming with an API that returns a PDF in Blob. I use HttpClient supports Blob response, checking the size of the file I use Len and it is correct.

My problem is how to convert or decode the Blob to PDF to save on local machine.

Reading Powerbuilder 2019R3 documentation, I can't find anything related. In forums I find FileOpen , FileReadEx and OleObject mentioned but no luck.

Only the WebBrowser that supports JavaScript seems to me the best option. First I test creating the script in an html5 and it works I can see the PDF in the Web browser,

  <script>
    fetch(getInvoice, {
      method: "GET",
      headers: {
        "Content-Type": "Application/PDF",
        Authorization: "Bearer " + dataToken,
      },
    })
      .then((Res) => {
        if (Res.status === 200) {
          return Res.blob();
          //return Res.text();
        } else {
          alert("Error Status :" + Res.status);
        }
      })
      .then((data) => {
        const domString = URL.createObjectURL(data);
        document.querySelector("#DisplayPdf").setAttribute("src", domString);
      });
  </script>

now I pass it to EvaluateJavascriptSync and it seems that it does not support fetch. I test with XMLHttpRequest

ls_get_invoice_pdf = 'function get_invoice_Display() {'+&
'   fetch(getInvoice,{'+&
'        method: "GET",'+&
'        headers:{;'+&
'            "Content-Type": "Application/PDF",'+&
'            "Authorization": "Bearer " + dataToken,'+&
'        },'+&
'    })'+&
'    .then(Res => {'+&
'        if(Res.status === 200){'+&
'            return Res.blob();'+&
'        }else{'+&
'            alert("Error Status :" + Res.status);'+&
'        }'+&
'    })'+&
'    .then((data) => {;'+&
'       const domString = URL.createObjectURL(data);'+&
'	document.body.innerHTML = `'+& 
'    <embed '+& 
'      src="/"'+& 
'      type="application/pdf"'+& 
'      width="800px"+& 
'      height="600px"'+& 
'      id="DisplayPdf"'+& 
'    />'+&
'`;'+&
'      document.querySelector("#DisplayPdf").setAttribute("src", domString);'+&
'    });'+&
'} get_invoice_Display(); '
wb_webbrowser_pdf.evaluatejavascriptsync(ls_get_invoice_pdf)
Accepted Answer
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Monday, 28 March 2022 14:35 PM UTC
  2. PowerBuilder
  3. # Permalink

Hi Luis;

  Suggestion:  Once you have the Blob data (PDF), then write it to disk using PB's FIleOpen() and FileWriteEx() methods. Then use the Web Browser's Navigate() method pointing it to the local file (aka PDF) for viewing. Food for thought. HTH

Regards ... Chris

Comment
There are no comments made yet.
Luis Alberto Coca Accepted Answer Pending Moderation
  1. Tuesday, 29 March 2022 18:33 PM UTC
  2. PowerBuilder
  3. # 1

Hi Luis;

  Suggestion:  Once you have the Blob data (PDF), then write it to disk using PB's FIleOpen() and FileWriteEx() methods. Then use the Web Browser's Navigate() method pointing it to the local file (aka PDF) for viewing. Food for thought. HTH

Regards ... Chris


Hello Chris.

Thank you very much for the suggestion, it works great. I leave the code to help if someone needs it.

string ls_url, ls_msg
integer li_return, li_FileNum
String data_cuf, ls_get_invoice_pdf
Blob ls_body_blob

HttpClient Data_HttpClient
Data_HttpClient = CREATE HttpClient


ls_url = "http://api/by-cuf/"+data_cuf.text+"/pdf"


Data_HttpClient.setrequestheader( "Content-Type", "Application/pdf;chartset=UTF-8")
Data_HttpClient.setrequestheader( "Authorization", "Bearer " +  mle_responsetoken.text )
li_return = Data_HttpClient.sendrequest( "GET", ls_url, ls_body_blob)

ls_msg =	"Headers: " + string(Data_HttpClient.GetResponseHeaders( )) + '~r~n' + &
		"Response Body: " + String(len(ls_body_blob))
messagebox('Response Status', ls_msg)


if li_return = 1 and Data_HttpClient.GetResponseStatusCode( ) = 200 then
	Data_HttpClient.getresponsebody(ls_body_blob)

// path to save the pdf and display from WebBrowser
	li_FileNum = FileOpen("C:\gravetal\testblob.pdf",StreamMode!, Write!, Shared!, Replace!)
	FileWriteEx(li_FileNum,ls_body_blob)
	FileClose(li_FileNum)
	wb_webbrowser_pdf.navigate("C:\gravetal\testblob.pdf")
end if

destroy(Data_HttpClient)

Comment
  1. Chris Pollach @Appeon
  2. Tuesday, 29 March 2022 18:49 PM UTC
Hi Luis .. that is great news - I am so pleased that it worked for you! :-)
  1. Helpful
There are no comments made yet.
Luis Alberto Coca Accepted Answer Pending Moderation
  1. Monday, 28 March 2022 20:49 PM UTC
  2. PowerBuilder
  3. # 2

Hi Luis;

  Suggestion:  Once you have the Blob data (PDF), then write it to disk using PB's FIleOpen() and FileWriteEx() methods. Then use the Web Browser's Navigate() method pointing it to the local file (aka PDF) for viewing. Food for thought. HTH

Regards ... Chris

--------------------------------------------

Hello  Chris.
Thanks for your suggestion, I'll put it into practice again.
If you can guide me on what the steps to follow would be, I don't quite understand how to use those methods.

According to the FileReadEx example :

integer li_fnum
long ll_bytes
blob Emp_Id_Pic

//I understand that it is to create the image blob 
//I don't have the image path, I already have the blob, should I skip this step? 

li_fnum = FileOpen("C:\Users\pb2019\Pictures\rect296.png",StreamMode!)
messagebox("data li_fnum ",string(li_fnum))	


//I understand to put a state to the Blob to read 
//It should work only with this method, as I continue to save the PDF or send to WebBrowser 

ll_bytes = FileReadEx(li_fnum, Emp_Id_Pic)
messagebox("data ll_bytes ",string(ll_bytes))	

 

Best regards.

Comment
  1. Chris Pollach @Appeon
  2. Monday, 28 March 2022 21:00 PM UTC
You do *not* need the FIleReadEx() command as the Web Service call returned you the PDF into a BLOB variable. After a FileOpen() to get a writeable file handle ready, you just need the FileWriteEx() command to write the BLOB information to the external file and then a FileClose() command to have the O/S write the EOF marker to the external file before using the WB Control's Navigate() command to the external file itself. All these commands with examples are well documented in the PB Help. HTH
  1. Helpful 1
There are no comments made yet.
Luis Alberto Coca Accepted Answer Pending Moderation
  1. Monday, 28 March 2022 20:21 PM UTC
  2. PowerBuilder
  3. # 3

Testing again, the Fetch works. But there is an instruction that stops working in WebBrowser. What I had planned did not work, I will have to look for other alternatives. 

	ls_get_invoice_pdf = 'function get_invoice_kraken() {'+&
'	document.body.innerHTML = `'+& 
'    <embed '+& 
'      src="/"'+& 
'      type="application/pdf" '+& 
'      width="800px" '+& 
'      height="600px" '+& 
'      id="DisplayPdf"'+& 
'    />'+&
'<p>This it work! </p>'+&
'`;'+&
'	document.querySelector("#DisplayPdf").style.background = "red";'+&
'    fetch(" '+ls_url+' ",{'+&
'        method: "GET",'+&
'       headers:{'+&
'            "Content-Type": "Application/PDF",'+&
'            "Authorization": "Bearer " + " '+mle_responsetoken.text+' " '+&
'        }'+&
'} )'+& 
'    .then(responseUsers =>{'+& 
'        if(responseUsers.status === 200){'+& 
'            return responseUsers.blob();'+&    //-->Change Blob to text view stream pdf
'        }'+& 
'    })'+& 
'    .then(BlobPDF => {'+&
'	   alert(BlobPDF)'+&
'          const domString = URL.createObjectURL(BlobPDF)'+&   //Error en WebBrowser display nothing
'          document.querySelector("#DisplayPdf").setAttribute("src",domString)'+&
'    })'+& 
'} get_invoice_kraken(); '
wb_webbrowser_pdf.evaluatejavascriptsync( ls_get_invoice_pdf)

it's a pity that it doesn't recognize or limit the evaluatejavascriptsync. It would be very useful to load complex scripts.

By accommodating the pure javascript I can customize the view, I hope it will help someone in the future or experiment to create great thing.

Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.