1

I have the following JSON response from a webservice method which will return byte[] in PDF format:

JVBERi0xLjQKJeLjz9MKMSAwI......nVq2P63zkirBH1z9aW3pDxn6F7q9TFV==

The return value is a byte() array. I been trying for a few days trying to use the function available in one of the questions posted in "Generating PDF from Base64 string in VBA" to generate PDF from the above Base64 Byte array, but I couldn't.

What I have done is that based on the return byte array from the webservice method, I save it as a byte array variable name b64testByte. Subsequently, I then proceed to call 2 methods in my program, namely encodeBase64 first, and followed by DecodeBase64. The PDF file is generated. However, when I try to open the file, there is an error which reads "Error: the document is damaged and cannot be repaired. Adobe Reader could not open because it is either not a supported file type or because the file has been damaged (for example, it was sent as an email attachment and wasn't correctly decoded)."

Dim b64testByte() As Byte
b64testByte = xmlhttp.responseText 

Dim B64String As String
B64String = encodeBase64(b64testByte)


    Dim FilePath As String
    FilePath = "D:\label.pdf"
    Open FilePath For Binary Access Write As #1
    Put #1, 1, DecodeBase64(B64String)
    Close #1


Private Function DecodeBase64(ByVal strData As String) As Byte()
    Dim objXML As Object 'MSXML2.DOMDocument
    Dim objNode As Object 'MSXML2.IXMLDOMElement
    'get dom document
    Set objXML = CreateObject("MSXML2.DOMDocument")
    'create node with type of base 64 and decode
    Set objNode = objXML.createElement("b64")
    objNode.DataType = "bin.base64"
    objNode.Text = strData
    DecodeBase64 = objNode.nodeTypedValue
    'clean up
    Set objNode = Nothing
    Set objXML = Nothing
End Function

Private Function encodeBase64(ByRef arrData() As Byte) As String
    Dim objXML As Object 'MSXML2.DOMDocument
    Dim objNode As Object 'MSXML2.IXMLDOMElement
    'get dom document
    Set objXML = CreateObject("MSXML2.DOMDocument")

    Set objNode = objXML.createElement("b64")
    objNode.DataType = "bin.base64"
    objNode.nodeTypedValue = arrData
    encodeBase64 = objNode.Text

    Set objNode = Nothing
    Set objXML = Nothing
End Function**
  • 2
    Please be explicit about what does and doesn't work. _but I couldn't_ isn't a good description of a problem. The answer on that question looks fine to me, without more information, I have nothing to add. – Erik A Jul 03 '18 at 08:53
  • @ErikvonAsmuth, thanks. I had amended my question. Hope it provide more clarity now. – Wilson Chan Jul 03 '18 at 09:42
  • Eh... Why would you first run a base64 encode and then a decode? If the result is a bytearray, that's __not__ the same as a base64 string, and you should just write it to a file directly. If it's a base64 string, you should only decode it. By encoding and then decoding it, you're essentially doing nothing at all. – Erik A Jul 03 '18 at 09:46
  • Also note that `responseText` returns a string. You can implicitly cast a string to a byte array, but then the byte array will contain that string, not a base64 decoded variant of the string – Erik A Jul 03 '18 at 09:49
  • Thanks @ErikvonAsmuth. I tried writing the result directly to the file. Put #1, 1, b64testByte . The PDF file is generated with the same error as "Error: the document is damaged and cannot be repaired. Adobe Reader could not open because it is either not a supported file type or because the file has been damaged (for example, it was sent as an email attachment and wasn't correctly decoded)." I had also tried opening the PDF file using notepad. The content is exactly the same as what was return by the webservice method. "JVBERi0xLjQKJeLjz9MKMSAwI......nVq2P63zkirBH1z9aW3pDxn6F7q9TFV==" – Wilson Chan Jul 03 '18 at 09:58
  • Just start by determining the content of that response... Is, or isn't it base64 encoded? If it is, decode it. If it isn't, and it's a binary PDF, then write it to a file. Just never encode and decode it, that's just wasting resources. – Erik A Jul 03 '18 at 09:59
  • According to the User Manual from the Web Service Provider, the return result is a return byte[] in PDF format. Sample as ""JVBERi0xLjQKJeLjz9MKMSAwI........nVq2P63zkirBH1z9aW3pDxn6F7q9TFV=" which is what I am getting if I do a msgbox on the return value in my program. In this case, may I know if it's a base64 encoded? Thank you and appreciate your help. My apologies if it sounds confusing. – Wilson Chan Jul 03 '18 at 10:09
  • 1
    .... That's a base64 string, which is __NOT__ a bytearray, but a string. Use it as such, and decode it once, like the code in the answer you referred to does. – Erik A Jul 03 '18 at 10:11
  • The response is a string containing base64 encoded data. Decode it and save resulting byte array to the file. That's it. `Function encodeBase64()` is excessive here. The first part you provided `JVBERi0xLjQKJeLjz9MKMSAwI` is decoded as `%PDF-1.4 %âăĎÓ 1 0`, if you open any PDF file with notepad you will see exactly the same beginning, thus the suggested algorithm is right, and the issue caused by the content received, but not by the encoding. – omegastripes Jul 03 '18 at 10:46
  • Also it's not quite clear how does JSON tag related to the question. IMO that tag should be removed. – omegastripes Jul 03 '18 at 10:48
  • Thanks to both of you. I am advancing with your advice. Please pardon me. I am passing the response to the decode function -> Put #1, 1, DecodeBase64(xmlhttp.responseText) and also tried -> Put #1, 1, DecodeBase64(b64testByte). However, I encounter the below error message as "Run-Time error '-2147467 (80004005)': Error Parsing "JVBERi0xLjQKJeLjz9MKMSAwI......nVq2P63zkirBH1z9aW3pDxn6F7q9TFV==" as bin.base 64 datatype. " The error highlighted is one of the line code in DecodeBase64 function -> objNode.Text = strData. Sincerely seek your help once again. Thanks – Wilson Chan Jul 03 '18 at 11:07

0 Answers0