Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Coloboración Paypal con ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 27-06-2024
darkamerico darkamerico is offline
Miembro
 
Registrado: dic 2010
Posts: 273
Poder: 15
darkamerico Va por buen camino
Red face Cargar un PDF de BD (base64) a un TWebBrowser

Saludos amigos,
Tengo la siguiente unidad:

Código Delphi [-]
unit uPrincipal;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls, Data.DB, Vcl.Grids, Vcl.DBGrids, System.NetEncoding,
  Vcl.OleCtrls, SHDocVw;

type
  TfrmPrincipal = class(TForm)
    Label1: TLabel;
    txtIDDoc: TEdit;
    Label2: TLabel;
    txtTituloPDF: TEdit;
    Label3: TLabel;
    btnAbrirPDF: TButton;
    open: TOpenDialog;
    Label4: TLabel;
    gridArchivos: TDBGrid;
    web: TWebBrowser;
    Label5: TLabel;
    procedure btnAbrirPDFClick(Sender: TObject);
    procedure gridArchivosCellClick(Column: TColumn);
  private
    { Private declarations }
  public
    function PDFToBase64(const FilePath: string): string;
    procedure ViewPDFInWebBrowser(WebBrowser: TWebBrowser; const Base64Str: string);
  end;

var
  frmPrincipal: TfrmPrincipal;

implementation

uses
  uDM;

{$R *.dfm}

procedure TfrmPrincipal.ViewPDFInWebBrowser(WebBrowser: TWebBrowser; const Base64Str: string);
var
  MemoryStream: TMemoryStream;
  DataUrl: string;
  ByteStream: TStringStream;
  Bytes: TBytes;
begin
  MemoryStream := TMemoryStream.Create;
  Bytes := TEncoding.UTF8.GetBytes(Base64Str);
  MemoryStream.Clear;
  MemoryStream.WriteBuffer(Bytes[0], Length(Bytes));
  MemoryStream.Position := 0;

  try
    ByteStream := TStringStream.Create;
    try
      MemoryStream.Position := 0;
      ByteStream.LoadFromStream(MemoryStream);
      DataUrl := 'data:application/pdf;base64,' + TNetEncoding.Base64.EncodeBytesToString(ByteStream.Bytes);
      WebBrowser.Navigate('about:blank');

      WebBrowser.OleObject.Document.Write(VarArrayOf([DataUrl])); // <-- Error "Los Tipos No Coinciden"
      WebBrowser.Refresh;
    finally
      ByteStream.Free;
    end;
  finally
    MemoryStream.Free;
  end;
end;

function TfrmPrincipal.PDFToBase64(const FilePath: string): string;
var
  FileStream: TFileStream;
  Bytes: TBytes;
begin
  FileStream := TFileStream.Create(FilePath, fmOpenRead or fmShareDenyWrite);
  try
    SetLength(Bytes, FileStream.Size);
    FileStream.ReadBuffer(Bytes[0], FileStream.Size);
    Result := TNetEncoding.Base64.EncodeBytesToString(Bytes);
  finally
    FileStream.Free;
  end;
end;

procedure TfrmPrincipal.btnAbrirPDFClick(Sender: TObject);
var
  insertedOk: boolean;
  Base64PDF: string;
begin
  if open.Execute then
  begin
    Base64PDF := PDFToBase64(open.FileName);
    try
      dm.q_SavePDF.Close;
      dm.q_SavePDF.Params[0].AsInteger := StrToInt(txtIDDoc.Text);
      dm.q_SavePDF.Params[1].AsString := Trim(txtTituloPDF.Text);
      dm.q_SavePDF.Params[2].AsString := Base64PDF;
      dm.q_SavePDF.ExecSQL;
      insertedOk := True;
    except
      insertedOk := False;
    end;
    if not insertedOk then
    begin
      ShowMessage('Error: No se pudo Insertar el Registro');
      Exit;
    end
    else
    begin
      ShowMessage('Ok: Registro Insertado!');

    end;
  end;
end;

procedure TfrmPrincipal.gridArchivosCellClick(Column: TColumn);
begin
  ViewPDFInWebBrowser(web, gridArchivos.DataSource.DataSet.FieldByName('docPDF').AsString);
end;

end.

La grabacion funciona bien, cuando quiero ver el PDF haciendo clic en la grilla me aparece un error en la linea:

Código Delphi [-]
WebBrowser.OleObject.Document.Write(VarArrayOf([DataUrl])); // <-- Error "Los Tipos No Coinciden"

Alguien me daría una mano?

Atte
Americo
Responder Con Cita
  #2  
Antiguo 27-06-2024
darkamerico darkamerico is offline
Miembro
 
Registrado: dic 2010
Posts: 273
Poder: 15
darkamerico Va por buen camino
Red face Otra variante

Este otra versión de la función, interesante pero también presenta error:

Código Delphi [-]
procedure TfrmPrincipal.ViewPDFInWebBrowser(WebBrowser: TWebBrowser; const Base64Str: string);
var
  PDFBase64: TBase64Encoding;
  PDFDoc: Variant;
  HTMLString: WideString;
  Stream: TStringStream;
begin
  PDFBase64 := TBase64Encoding.Create;
  try
    PDFBase64.Decode(Base64Str);
    PDFDoc := '' +
              '<_embed width="100%" height="100%" type="application/pdf" ' +
              'src="data:application/pdf;base64,' + Base64Str + '">' +
              '';
    HTMLString := PDFDoc;
    Stream := TStringStream.Create(HTMLString, TEncoding.UTF8);
    try
      WebBrowser.Navigate('about:blank');
      while WebBrowser.ReadyState < READYSTATE_INTERACTIVE do
        Application.ProcessMessages;
      (WebBrowser.Document as IPersistStreamInit).Load(TStreamAdapter.Create(Stream));
    finally
      Stream.Free;
    end;
  finally
    PDFBase64.Free;
  end;
end;
Responder Con Cita
  #3  
Antiguo 28-06-2024
Avatar de pgranados
pgranados pgranados is offline
Miembro
 
Registrado: sep 2022
Ubicación: México
Posts: 318
Poder: 3
pgranados Va por buen camino
Hola, hace mucho yo intente cargar un PDF en un TWebBrowser y por mas que intente no pude, solo pude cargar archivos XML. Lo que termine haciendo fue usar el TWebBrower de TMS para leer PDF.

Ahorita no tengo mi laptop del trabajo pero mañana te paso el codigo de como cargar un PDF en un TWebBrowser de TMS
Responder Con Cita
  #4  
Antiguo 28-06-2024
darkamerico darkamerico is offline
Miembro
 
Registrado: dic 2010
Posts: 273
Poder: 15
darkamerico Va por buen camino
Red face Gracias

Gracias por responder, quedo atento.

Estuve viendo y tengo instalado el componente TTMSFNCWebBrowser.

Atte

Última edición por darkamerico fecha: 28-06-2024 a las 15:03:33.
Responder Con Cita
  #5  
Antiguo 28-06-2024
Avatar de pgranados
pgranados pgranados is offline
Miembro
 
Registrado: sep 2022
Ubicación: México
Posts: 318
Poder: 3
pgranados Va por buen camino
Necesitas uno llamado TAdvWebBrowser y en la forma donde vayas a tener tu visor pdf en el evento onCreate pon esto:

Código Delphi [-]
try
    webBrowser1.Navigate('file:///'+FormaPrincipal.psRutaPDF);
except
    ShellExecute(Handle, 'open', 'explorer.exe', PChar(FormaPrincipal.psRutaPDF), nil, SW_SHOWNORMAL);
    PostMessage(Handle, WM_CLOSE, 0, 0); // cierro la forma
    Exit;
end;

FormaPrincipal.psRutaPDF es una variable tipo string el cual almacena la ruta del archivo. Si en algun caso no se logra cargar el PDF en el webBrowser se abrira el archivo con el visor pdf predeterminado en la computadora.

Recuerda que los WebBrowser basados en Chromiun necesitan una dll llamada WebView2Loader
Responder Con Cita
  #6  
Antiguo 28-06-2024
darkamerico darkamerico is offline
Miembro
 
Registrado: dic 2010
Posts: 273
Poder: 15
darkamerico Va por buen camino
Red face Amigo

Hola, tengo un problemita con la libreria WevView2Loader_xXX.dll,
Según este manual, baje los instaladores de ambas plataformas x32, x64 pero me dice que YA están instaladas en mi sistema.
Responder Con Cita
  #7  
Antiguo 28-06-2024
darkamerico darkamerico is offline
Miembro
 
Registrado: dic 2010
Posts: 273
Poder: 15
darkamerico Va por buen camino
Red face

Cita:
Empezado por pgranados Ver Mensaje
Necesitas uno llamado TAdvWebBrowser y en la forma donde vayas a tener tu visor pdf en el evento onCreate pon esto:

Código Delphi [-]
try
    webBrowser1.Navigate('file:///'+FormaPrincipal.psRutaPDF);
except
    ShellExecute(Handle, 'open', 'explorer.exe', PChar(FormaPrincipal.psRutaPDF), nil, SW_SHOWNORMAL);
    PostMessage(Handle, WM_CLOSE, 0, 0); // cierro la forma
    Exit;
end;

FormaPrincipal.psRutaPDF es una variable tipo string el cual almacena la ruta del archivo. Si en algun caso no se logra cargar el PDF en el webBrowser se abrira el archivo con el visor pdf predeterminado en la computadora.

Recuerda que los WebBrowser basados en Chromiun necesitan una dll llamada WebView2Loader
Amigo, baje el TMS VCL UI Pack y al tratar de instalarlo, se cruza con TMS Component Pack.
Responder Con Cita
  #8  
Antiguo 28-06-2024
Avatar de pgranados
pgranados pgranados is offline
Miembro
 
Registrado: sep 2022
Ubicación: México
Posts: 318
Poder: 3
pgranados Va por buen camino
Para eso yo utilizo este codigo:

Código Delphi [-]
if EsWindows64Bits then // Si Windows es 64 bits vamos a mandar las DLL
begin // Si Windows es de 64 bits copio y pego las dos DLL en System 32
    if not FileExists('C:\Windows\SysWOW64\WebView2Loader_x86.dll') then
    begin
      if not FileExists(psRutaRaizServer+'WebView2Loader_x86.dll') then
        exit;

      Destino := 'C:\Windows\SysWOW64';

      ZeroMemory(@FO, SizeOf(FO));
      FO.Wnd := 0;
      FO.wFunc := FO_COPY;
      FO.pFrom := PChar(psRutaRaizServer+'WebView2Loader_x86.dll' + #0);
      FO.pTo := PChar(Destino + #0);
      FO.fFlags := FOF_NOCONFIRMATION or FOF_NOCONFIRMMKDIR;

      if SHFileOperation(FO) <> 0 then
        Application.MessageBox(PChar('Hubo un error con WebView2Loader_x86.dll'), PChar(csNombrePrograma),MB_OK + MB_ICONERROR)
      else
        lbTerminar:= true;
    end;

    if not FileExists('C:\Windows\SysWOW64\WebView2Loader_x64.dll') then
    begin
      if not FileExists(psRutaRaizServer+'WebView2Loader_x64.dll') then
        exit;

      Destino := 'C:\Windows\SysWOW64';

      ZeroMemory(@FO, SizeOf(FO));
      FO.Wnd := 0;
      FO.wFunc := FO_COPY;
      FO.pFrom := PChar(psRutaRaizServer+'WebView2Loader_x64.dll' + #0);
      FO.pTo := PChar(Destino + #0);
      FO.fFlags := FOF_NOCONFIRMATION or FOF_NOCONFIRMMKDIR;

      if SHFileOperation(FO) <> 0 then
        Application.MessageBox(PChar('Hubo un error con WebView2Loader_x64.dll'), PChar(csNombrePrograma),MB_OK + MB_ICONERROR)
      else
        lbTerminar:= true;
   end;
end;

if lbTerminar = true then
begin
    Application.MessageBox(PChar('Al cerrar este mensaje se cerrará el sistema. al volver a entrar se terminarán de instalar los archivos requeridos para el correcto funcionamiento de 
    este.'), PChar(csNombrePrograma),MB_OK + MB_ICONWARNING);
    // Aqui cerramos el programa
end;
Responder Con Cita
  #9  
Antiguo 28-06-2024
darkamerico darkamerico is offline
Miembro
 
Registrado: dic 2010
Posts: 273
Poder: 15
darkamerico Va por buen camino
Red face

Cita:
Empezado por pgranados Ver Mensaje
Para eso yo utilizo este codigo:

Código Delphi [-]
if EsWindows64Bits then // Si Windows es 64 bits vamos a mandar las DLL
begin // Si Windows es de 64 bits copio y pego las dos DLL en System 32
    if not FileExists('C:\Windows\SysWOW64\WebView2Loader_x86.dll') then
    begin
      if not FileExists(psRutaRaizServer+'WebView2Loader_x86.dll') then
        exit;

      Destino := 'C:\Windows\SysWOW64';

      ZeroMemory(@FO, SizeOf(FO));
      FO.Wnd := 0;
      FO.wFunc := FO_COPY;
      FO.pFrom := PChar(psRutaRaizServer+'WebView2Loader_x86.dll' + #0);
      FO.pTo := PChar(Destino + #0);
      FO.fFlags := FOF_NOCONFIRMATION or FOF_NOCONFIRMMKDIR;

      if SHFileOperation(FO) <> 0 then
        Application.MessageBox(PChar('Hubo un error con WebView2Loader_x86.dll'), PChar(csNombrePrograma),MB_OK + MB_ICONERROR)
      else
        lbTerminar:= true;
    end;

    if not FileExists('C:\Windows\SysWOW64\WebView2Loader_x64.dll') then
    begin
      if not FileExists(psRutaRaizServer+'WebView2Loader_x64.dll') then
        exit;

      Destino := 'C:\Windows\SysWOW64';

      ZeroMemory(@FO, SizeOf(FO));
      FO.Wnd := 0;
      FO.wFunc := FO_COPY;
      FO.pFrom := PChar(psRutaRaizServer+'WebView2Loader_x64.dll' + #0);
      FO.pTo := PChar(Destino + #0);
      FO.fFlags := FOF_NOCONFIRMATION or FOF_NOCONFIRMMKDIR;

      if SHFileOperation(FO) <> 0 then
        Application.MessageBox(PChar('Hubo un error con WebView2Loader_x64.dll'), PChar(csNombrePrograma),MB_OK + MB_ICONERROR)
      else
        lbTerminar:= true;
   end;
end;

if lbTerminar = true then
begin
    Application.MessageBox(PChar('Al cerrar este mensaje se cerrará el sistema. al volver a entrar se terminarán de instalar los archivos requeridos para el correcto funcionamiento de 
    este.'), PChar(csNombrePrograma),MB_OK + MB_ICONWARNING);
    // Aqui cerramos el programa
end;
Brother, el objeto puntero FO, como se define
Responder Con Cita
  #10  
Antiguo 28-06-2024
Avatar de pgranados
pgranados pgranados is offline
Miembro
 
Registrado: sep 2022
Ubicación: México
Posts: 318
Poder: 3
pgranados Va por buen camino
Código Delphi [-]
FO: TSHFileOpStruct;
Responder Con Cita
  #11  
Antiguo 28-06-2024
darkamerico darkamerico is offline
Miembro
 
Registrado: dic 2010
Posts: 273
Poder: 15
darkamerico Va por buen camino
Red face modificaciones a tu codigo

Amigo hice algunas cosas en tu codigo:

Código Delphi [-]

function EsWindows64Bits: Boolean;
type
  TIsWow64Process = function(Handle: THandle; var Res: BOOL): BOOL; stdcall;
var
  IsWow64Result: BOOL;
  IsWow64Process: TIsWow64Process;
begin
  Result := False;
  IsWow64Process := GetProcAddress(GetModuleHandle('kernel32.dll'), 'IsWow64Process');
  if Assigned(IsWow64Process) then
  begin
    if IsWow64Process(GetCurrentProcess, IsWow64Result) then
    begin
      Result := IsWow64Result;
    end;
  end;
end;

procedure TfrmPrincipal.Button1Click(Sender: TObject);
var
  rutaSistema, rutaFileLocal, Destino:string;
  FO:TSHFileOpStruct;
  lbTerminar:Boolean;
begin
  rutaFileLocal:=ExtractFilePath(Application.ExeName);
  if EsWindows64Bits then
  begin // Si Windows es de 64 bits copio y pego las dos DLL en System 32
    rutaSistema:='C:\Windows\SysWOW64\';

    if not FileExists(rutaSistema + 'WebView2Loader_x64.dll') then
    begin
      Destino := 'C:\Windows\SysWOW64';

      ZeroMemory(@FO, SizeOf(FO));
      FO.Wnd := 0;
      FO.wFunc := FO_COPY;
      FO.pFrom := PChar(rutaFileLocal+'Files\WebView2Loader_x64.dll' + #0);
      FO.pTo := PChar(Destino + #0);
      FO.fFlags := FOF_NOCONFIRMATION or FOF_NOCONFIRMMKDIR;

      if SHFileOperation(FO) <> 0 then
        Application.MessageBox(PChar('Hubo un error con WebView2Loader_x64.dll'), PChar('OK'),MB_OK + MB_ICONERROR)
      else
        lbTerminar:=True;
    end;
  end
  else // 32 Bits
  begin
    rutaSistema:='C:\Windows\System32\';

    if not FileExists(rutaSistema+'WebView2Loader_x86.dll') then
    begin
      Destino := 'C:\Windows\System32';

      ZeroMemory(@FO, SizeOf(FO));
      FO.Wnd := 0;
      FO.wFunc := FO_COPY;
      FO.pFrom := PChar(rutaFileLocal+'Files\WebView2Loader_x86.dll' + #0);
      FO.pTo := PChar(Destino + #0);
      FO.fFlags := FOF_NOCONFIRMATION or FOF_NOCONFIRMMKDIR;

      if SHFileOperation(FO) <> 0 then
        Application.MessageBox(PChar('Hubo un error con WebView2Loader_x86.dll'), PChar('Ok'),MB_OK + MB_ICONERROR)
      else
        lbTerminar:= true;
     end;
  end;
end;

Última edición por darkamerico fecha: 28-06-2024 a las 17:20:06.
Responder Con Cita
  #12  
Antiguo 28-06-2024
darkamerico darkamerico is offline
Miembro
 
Registrado: dic 2010
Posts: 273
Poder: 15
darkamerico Va por buen camino
Red face Ayuda

Amigos, aquí comparto el proyecto donde intento recuperar el PDF en base64 desde la BD y al hacer clic en una grilla se debe visualizar el PDF en el componente TAdvWebBrowser. El archivo .BAK esta ahí también

Lo que deseo evitar es que el PDF de la BD se grabe en archivos temporales en el disco.
No es indispensable usar un componente TAdvWebBrowser, con que se visualice el documento con ShellExecute, suficiente.

Proyecto:
Bajar (800k)

Atte,
Americo Torres

Última edición por darkamerico fecha: 28-06-2024 a las 21:12:07.
Responder Con Cita
  #13  
Antiguo 29-06-2024
Avatar de pgranados
pgranados pgranados is offline
Miembro
 
Registrado: sep 2022
Ubicación: México
Posts: 318
Poder: 3
pgranados Va por buen camino
Cita:
Empezado por darkamerico Ver Mensaje
Lo que deseo evitar es que el PDF de la BD se grabe en archivos temporales en el disco.
Aqui ya no entendi, lo que quieres es guardar un base64 en la base de datos?

Para eso en Firebird 2.5 utilizas el tipo de campo tipo blob no un campo tipo string
Responder Con Cita
  #14  
Antiguo 29-06-2024
Avatar de pgranados
pgranados pgranados is offline
Miembro
 
Registrado: sep 2022
Ubicación: México
Posts: 318
Poder: 3
pgranados Va por buen camino
Cita:
Empezado por pgranados Ver Mensaje
Aqui ya no entendi, lo que quieres es guardar un base64 en la base de datos?

Para eso en Firebird 2.5 utilizas el tipo de campo tipo blob no un campo tipo string
Es mas, directamente guardas el PDF en el BLOB y lo recuperas con un TStream
Responder Con Cita
  #15  
Antiguo 01-07-2024
darkamerico darkamerico is offline
Miembro
 
Registrado: dic 2010
Posts: 273
Poder: 15
darkamerico Va por buen camino
Red face Gracias por responder

Saludos pgranados,
Como puedes advertir en el código que he mostrado, el archivo PDF ya lo tengo almacenado en base64 en la BD, lo único que deseo ahora es poder visualizarlo.
Mi WhatsApp: +51 956 940 019

Atte
Americo Torres
Responder Con Cita
  #16  
Antiguo 02-07-2024
Avatar de pgranados
pgranados pgranados is offline
Miembro
 
Registrado: sep 2022
Ubicación: México
Posts: 318
Poder: 3
pgranados Va por buen camino
Estuve investigando un poco el tema y encontre este hilo:


Al parecer Internet Explorer (WebBrowser) utiliza un plugin de Adobe Acrobat para leer PDF en el navegador, puedes intentar seguir el hilo para llegar a la solución pero honestamente te recomiendo usar algun componente de terceros como los TMS o DevExpress o algun componente basado en Chromiun y no en Internet Explorer
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Base64 IdDecoderMIME a zip GustavoCruz Internet 9 10-11-2020 07:57:12
Cargar una Imagen base64 en un Timage darkamerico Gráficos 7 25-10-2020 01:04:29
Cargar esta web en un Twebbrowser problemas user agent cocute Varios 8 02-11-2014 17:57:19
Mostrar imagen que viene en Base64 jars Gráficos 7 25-06-2012 09:42:57
Cargar datos formulario web en Twebbrowser Rockin Internet 8 23-02-2011 12:50:34


La franja horaria es GMT +2. Ahora son las 22:45:45.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi