Blob file containing PDF to WebHTMLViewer

My database and xjojo are on the same machine and the database passes a path to a pdf to xojo which displays it in a WebHTMLViewer using…

Dim f As FolderItem = Volume(0) f = New FolderItem(docPath, folderitem.PathTypeNative) myPDFFile = WebFile.Open(f) myPDFFile.MIMEType = "application/pdf" myPDFFile.ForceDownload = false htmlViewer_Document.URL = myPDFFile.URL

The database can also return a blob of the file. The code in the database looks like this…

DOCUMENT TO BLOB($path;$blob) WEB SEND BLOB($blob;"application/pdf")

Xojo and the database exchange data using using localhost:9000. The following works using a browser on the same machine as Xojo and the database …

Host = "localhost:9000" htmlViewer_Document.URL = "http://"+Host+"/chaos/getDocumentBlob?path="+docPath+"&output=xml&site=xojo"

Doing this I am seeing at least a 5X increase in spead to load the pdf over using FolderItem in the same setup. Unfortunaely this will only work if the browser is on the same machine as Xojo and the database.

Port 9000 is not a public port in my devlopment or production environments nor do I want it to be. I would want all external comms to be through xojo.

Is there a way to serve the blob to the WebHTMLViewer through the Xojo WebApp? I can get the blob to the Xojo web app using…

socket1.Get("http://"+Host+"/chaos/getDocumentBlob?path="+docPath+"&output=xml&site=xojo", 30)

I cannot figure out how to consume the socket1.get so that it displays the PDF in the WebHTMLViewer.

If this at all possible could someone point me in the right direction.

John

It depends on how you’re presenting the PDF. If you’re using a viewer like PDF.JS then the url can contain base64 or typedArrays.

It should be possible to use a data URI and download a PDF or display it in a new window. I’ve set-up a jsfiddle with some methods that have worked in the past: https://jsfiddle.net/eduo/2t7wsbph/11/

(not tested, might need tweaking)

If this works for you (or a variation, rather), you can encode the binary into base64 directly off the database or do it through javascript before feeding it off to the URI.

@Eduardo Gutierrez de Oliveira thanks. I am displaying the PDF in a Xojo WebHTMLViewer control. Not sure how your suggestions might help me to that end.

John

if I understood your question correctly, yes you can send the data (blob) of the pdf file directly to the WebHTMLViewer. To do this you simply need to create an HTML page containing the data of the pdf encoded as base64.
In the example below “rs.Field(“xxx”).NativeValue” represents the PDF file saved in a BlobColumn.

[code]Dim rs As RecordSet
Dim dat() As String

rs = db.SQLSelect(“SELECT * FROM …”)
if rs<>Nil Then
dat.Append("")
dat.Append("")
dat.Append("")
dat.Append("<meta charset="“UTF-8"”>")
dat.Append("")
dat.Append("")
dat.Append("<object data="“data:application/pdf;base64,”)
dat.Append(EncodeBase64(rs.Field(“xxx”).NativeValue,0))
dat.Append(""" type="“application/pdf”" width="“100%”" height="""+Str(HTMLViewer1.Height)+“px”">")
dat.Append("")
dat.Append("")
dat.Append("")

HTMLViewer1.LoadPage(Join(dat,EndOfLine))
end if[/code]

Of course you can add other parameters to the html file like eg “” …

@Alain Clausen I was just about to give up…

I took your suggestion and tried…

Dim pdfBlob As String DIM socket1 As New HTTPSocket pdfBlob = EncodeBase64(socket1.Get("http://127.0.0.1:9000/chaos/getDocumentBlob?path="+docPath+"&output=xml&site=xojo", 30),0) Dim dat() As String dat.Append("<!DOCTYPE html>") dat.Append("<html>") dat.Append("<head>") dat.Append("<meta charset=""UTF-8"">") dat.Append("</head>") dat.Append("<body>") dat.Append("<object data=""data:application/pdf;base64,") dat.Append(pdfBlob) dat.Append(""" type=""application/pdf"" width=""100%"" height="""+Str(htmlViewer_Document.Height)+"px"">") dat.Append("</object>") dat.Append("</body>") dat.Append("</html>") htmlViewer_Document.LoadPage(Join(dat,EndOfLine))

I get the page but it is blank. Do you see anything I am doing wrong?

Remember that the following works…

 htmlViewer_Document.URL = "http://127.0.0.1:9000/chaos/getDocumentBlob?path="+docPath+"&output=xml&site=xojo" 

The BLOB data that represents your pdf file must be the binary data of the file, eg the value returned by a BinaryStream.Read(bs.length). This works perfectly with a database open directly in the WebApp where you can read the data via a recordset.
In your case, if you recover the pdf via an url you must be sure that the data received correspond exactly to the file (encoding). Maybe this can help (change the encoding if the file has not been saved in UTF8):

pdfBlob = EncodeBase64(DefineEncoding(socket1.Get("http://127.0.0.1:9000/chaos/getDocumentBlob?path="+docPath+"&output=xml&site=xojo", 30),Encodings.UTF8),0)

You can test your code by downloading a pdf from the internet, this example shows the pdf of a microchip microcontroller:

pdfBlob = EncodeBase64(DefineEncoding(socket1.Get("http://ww1.microchip.com/downloads/en/DeviceDoc/41196g.pdf", 30),Encodings.UTF8),0)

Hmmmm. the microchip test pdf works fine, but even with the DefineEncoding I ams still getting a blank page.

Actually I realized that I am not getting a blank page per se, but a grey block where the PDF would hve displayed if it workded. I am not sure what encoding the database is using to send the blob. Trying to find out now, but am about ready to give up on this.

@Alain Clausen I got it working now. I had a typo in the request. One letter can sure waste a lof of ones time

Now that I have it working I see that that having Xojo serve the blob to the browser is even slower than using the the folderitem approach. Having the browser get the blob directly from the database is significantly faster but I cannot expose the request to the database.

Thanks for your help.

The solution selected does not work in Xojo 2019r3 because HTMLViewer1.LoadPage() need a FolderItem not a string

I have a similar problem (conversation is here )and this my solution :

[code]If DBFileList.SelectedRowIndex < 0 Then Return

// Get the file to save the BLOB to
Var outputFile As FolderItem = SpecialFolder.Resource(“temp.pdf”)

If outputFile Is Nil Then Return

// ID is the Unique iddentifier on my Tabale
Var id As Integer = DBFileList.RowTagAt(DBFileList.SelectedRowIndex)

// Get the BLOB from the DB into a string
Var blob As SQLiteBlob = mDB.OpenBlob(“File”, “FileData”, id, False)

If blob <> Nil Then
Var output As BinaryStream
output = BinaryStream.Create(outputFile, True)

While Not blob.EndOfFile
Try
output.Write(blob.Read(1000))
Catch err as IOException
MessageDialog.Show(“Error reading from BLOB.”)
Exit While
End Try
Wend
blob.Close
output.Close

// Load file on HTML Viewer
HTMLViewer1.LoadPage(outputFile)
Else
MessageDialog.Show(“This BLOB column has no data.”)

End If
[/code]