delphipdfdelphi-xe7twebbrowser

Delphi: Display a PDF in a TWebBrowser


I need to display a pdf file into a TWebBrowser object. WebBrowser1.navigate(PDFFileName) works fine.

But i would like to load the pdf file from a TMemoryStream.

I have a base64 encoded PDF file content as the input of my procedure and searching on google i wrote something like this:

procedure WriteOnWB(EncodedPDFString: WideString);
var
    Bytes: TBytes;
    MS: TMemoryStream;
begin   
    Bytes := TNetEncoding.Base64.DecodeStringToBytes(EncodedPDFString);
    MS := TMemoryStream.Create;
    MS.WriteBuffer(Bytes, Length(Bytes));
    MS.Seek(0, 0);

    WebBrowser1.Navigate('about:blank');
    (WebBrowser1.Document as IPersistStreamInit).Load(TStreamAdapter.Create(MS));
end;

and this is the result: TWebBrowserResult the twebbrowser doesn't recognize that the content of the document is a pdf file. I suppose I forgot something like setting the content type of the page, something like SetContentType('Application/pdf')

What am i doing wrong? Is this even possible?

PS: I'm working with Delphi XE7


Solution

  • TWebBrowser is an embeded IE istance and IE doesn't allow you to show a PDF if you don't save it as a physical file.

    So to display it you should write something like this:

    procedure WriteOnWB(EncodedPDFString: WideString);
    var
        Bytes: TBytes;
        MS: TMemoryStream;
    begin   
        Bytes := TNetEncoding.Base64.DecodeStringToBytes(EncodedPDFString);
        MS := TMemoryStream.Create;
        MS.WriteBuffer(Bytes, Length(Bytes));
        MS.Seek(0, 0);
        MS.SaveToFile('FileName.pdf');
    
        // Now you can navigate to 'FileName.pdf'
        WebBrowser1.Navigate('FileName.pdf');
    end;
    

    An alternative solution is to use Chromium (As Olivier suggested). Chromium (since it's Chrome) allows you to show a PDF file through a base64 encoded string, for example, within an iframe tag (see this answer):

    <iframe src="data:application/pdf;base64,YOUR_BINARY_DATA" height="100%" width="100%"></iframe>