0

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

  • Yes, you definitely need to set the content-type to `application/pdf`. – Olivier Jun 03 '20 at 14:05
  • Ok but how can i do that? – Matteo Ballardini Jun 03 '20 at 14:34
  • 1
    I don't know, but in fact it's not a good idea to use IE to display a PDF, because it has no native support (you need to install the Acrobat plug-in, which is now deprecated). I suggest embedding Chromium instead (see [here](https://github.com/salvadordf/CEF4Delphi)). – Olivier Jun 03 '20 at 14:49
  • Correction: as of IE 8, an Adobe add-on is automatically installed, so you don't need to install the plug-in anymore to have PDF support. However I still think using Chromium is a better (more robust) solution. – Olivier Jun 03 '20 at 15:59
  • Ok @Olivier i will take a look today. Thank you. – Matteo Ballardini Jun 04 '20 at 06:55

2 Answers2

1

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>
0

Fileless just as a Stream

procedure FilelessWB2(encodedURL: string);
  var Bytes:TBytes;
      tMS: TMemoryStream;
      WebBrowser1: TWebBrowser; frm1:TForm;
      JPGImage: TJPEGImage;
begin   
  //Bytes:={TNetEncoding.Base64.}{DecodeString}StrToBytes(filetostring(EncodedPDFString));
    
  tMS:= TMemoryStream.Create;
  try
    HttpGet(encodedURL,tmS)
    writeln('debug size: '+itoa((tms.size)));
     { WebBrowser1:= TWebBrowser.create(self);
      MS.WriteBuffer(bytestostr(Bytes),Length(Bytes)); }
    tMS.Seek(0, 0);
     //tMS.SaveToFile(exepath+'FileNametest.jpg');
     //OpenWeb(exepath+'FileNametest.jpg')
    frm1:= TForm.create(self); 
    with frm1 do begin
      setBounds(0,0,500,500)
      with TImage.create(frm1) do begin
        parent:= frm1;
        setBounds(0,0,460,460)
        JPGImage:= TJPEGImage.Create;      
        JPGImage.LoadFromStream(tMS);                
        Picture.Graphic:=(JPGImage);
      end ;
     Show;
    end; 
  finally
    tMS.Free;
    JPGImage.Free;
  end;  
   //Now you can navigate to 'FileName.pdf'
   //WebBrowser1.Navigate(exepath+'FileNametest.pdf');
end;