Fórum Gravando e resgatando PDF de banco Access com Blob #461764
22/11/2013
0
Estou com um problema em um projeto onde há a necessidade de gravar um arquivo PDF no banco de dados, pois solicitaram que ele não fique exposto em uma pasta. O banco é Access XP ainda, pois é a única versão que posso usar aqui por ser um órgão público e ter somente ele disponível.
No banco o campo que recebe o documento PDF é do tipo OLE, sendo que ao gravar o dado, consigo ver na tabela que algo está naquele campo, o Access mostra somente a inscrição 'binários longos' . Estou tentando resolver o problema usando BLOB, que funcionou fácil na gravação, porém na recuperação / amostragem não.
Outro item que tenho grande dúvida é quanto o uso do comando ShellExecute, sei que seu funcionamento é fácil, até fiz uns testes aqui, porém não consigo mostrar ao Delphi como carregar aquele registro no banco e mostrá-lo em PDF.
Vale ressaltar que a conexão com o banco de dados funciona normalmente (ADOConnection, ADOQuery e DataSource).
Bom... abaixo segue o código de um exemplo de aplicação voltada somente para resolver este problema. Quem tiver alguma noção, por favor, me ajude!
unit unit_blob;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, StdCtrls, ExtCtrls, ShellApi, DBCtrls, OleCtnrs, DBClient, dbtables;
type
TForm1 = class(TForm)
SaveDialog1: TSaveDialog;
btAnexar: TButton;
ADOConnection1: TADOConnection;
ADOQuery1: TADOQuery;
DataSource1: TDataSource;
btInserir: TButton;
Shape1: TShape;
btVisualizar: TButton;
cdsTemporario: TClientDataSet;
cdsTemporarioarquivoPDF: TBlobField;
Memo1: TMemo;
procedure btAnexarClick(Sender: TObject);
procedure btInserirClick(Sender: TObject);
procedure btVisualizarClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
// Anexando dados (funcional) ++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TForm1.btAnexarClick(Sender: TObject);
begin
SaveDialog1.Execute;
if (SaveDialog1.FileName <> '') then
begin
Memo1.Lines.SaveToFile(SaveDialog1.FileName);
Memo1.Text := SaveDialog1.FileName;
//Propriedade text usada pelo fato do nome do arquivo não aparecer
//no memo automaticamente.
end;
end;
// Inserido dados (funcional) ++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TForm1.btInserirClick(Sender: TObject);
begin
ADOQuery1.Close; //Fecha conexões antigas...
ADOQuery1.SQL.Clear; //Limpa conexões...
ADOQuery1.SQL.Add('insert into tbl_arquivo (arquivo) values (:param_cx_arquivo)'); //Faz a inserção...
ADOQuery1.Parameters.ParamByName('param_cx_arquivo').LoadFromFile(memo1.Text, ftBlob); //Dado recebido...
//Load carrega o dado para o banco, vai em formato blob...
try
ADOQuery1.ExecSQL; //Execução da Query.
ShowMessage('Registro gravado com sucesso!');
except
ShowMessage('Erro ao gravar dados...');
end;
end;
// Visualizando / Recuperando dados (não funcional) ++++++++++++++++++++++++++++
procedure TForm1.btVisualizarClick(Sender: TObject);
var
blob : TBlobField;
software : String;
caminho : String;
dado : String;
begin
//Consultando
ADOQuery1.Close; //Fecha conexões antigas...
ADOQuery1.SQL.Clear; //Limpa conexões...
ADOQuery1.SQL.Add('select arquivo from tbl_arquivo where codigo = 3'); //Faz a inserção...
ADOQuery1.Open; //Execução da Query.
{
Daqui em diante não sei como proceder...
A consulta é bastante simples, pois ela será implementada após resolver
sobre o resgate / apresentação dos dados.
}
end;
end.
Diego Bispo
Curtir tópico
+ 0Post mais votado
09/12/2013
Dica: o TMemoryStream é um grande aliado, fique de olho nele!
Minha solução:
unit unit_blob;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, StdCtrls, ExtCtrls, ShellApi, DBCtrls, OleCtnrs, DBClient, DBTables;
type
TForm1 = class(TForm)
SaveDialog1: TSaveDialog;
btAnexar: TButton;
ADOQuery1: TADOQuery;
DataSource1: TDataSource;
btInserir: TButton;
Shape1: TShape;
btVisualizar: TButton;
Memo1: TMemo;
lblResultado: TLabel;
ADOConnection1: TADOConnection;
procedure btAnexarClick(Sender: TObject);
procedure btInserirClick(Sender: TObject);
procedure btVisualizarClick(Sender: TObject);
procedure btTestaConexaoClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
// Anexando dados (funcional) ++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TForm1.btAnexarClick(Sender: TObject);
var
arquivo : TMemoryStream;
begin
SaveDialog1.Execute;
if (SaveDialog1.FileName <> '') then
begin
//Carregamento da imagem:
arquivo := TMemoryStream.Create;
//Alocando o conteúdo da SaveDialog na variável.
Memo1.Lines.SaveToStream(arquivo);
//Mostrando o nome ao usuário.
Memo1.Text := SaveDialog1.FileName;
//Propriedade text usada pelo fato do nome do arquivo não aparecer
//no memo automaticamente.
end;
end;
// Inserido dados (não funcional) ++++++++++++++++++++++++++++++++++++++++++++++++++
procedure TForm1.btInserirClick(Sender: TObject);
begin
//Gravando os dados...
ADOQuery1.Close; //Fecha conexões antigas...
ADOQuery1.SQL.Clear; //Limpa conexões...
ADOQuery1.SQL.Add('insert into tbl_arquivo (arquivo) values (:param_cx_arquivo)'); //Faz a inserção...
ADOQuery1.Parameters.ParamByName('param_cx_arquivo').LoadFromFile(Memo1.Lines.Text, ftBlob); //Dado recebido...
//Executa a query.
try
ADOQuery1.ExecSQL; //Execução da Query.
ShowMessage('Registro gravado com sucesso!');
except
ShowMessage('Erro ao gravar dados...');
end;
end;
// Visualizando / Recuperando dados (funcional) ++++++++++++++++++++++++++++
procedure TForm1.btVisualizarClick(Sender: TObject);
var
//Tratando Blob
S : TMemoryStream;
FileStream : TFileStream;
//Confirmação de informações
resultado : Integer;
begin
//Consultando
ADOQuery1.Close; //Fecha conexões antigas...
ADOQuery1.SQL.Clear; //Limpa conexões...
ADOQuery1.SQL.Add('select arquivo from tbl_arquivo where codigo = 23'); //Faz a inserção...
ADOQuery1.Open; //Execução da Query.
//Contando o resultado...
resultado := ADOQuery1.RecordCount;
lblResultado.Caption := 'Resultado da pesquisa: '+ IntToStr(resultado) +' registro(s) encontrado(s).';
lblResultado.Visible := True;
S := TMemoryStream.Create;
try
//Criação do arquivo que receberá o pdf...
FileStream := TFileStream.Create('c:\arquivo.pdf', fmCreate);
//Salvamento do conteúdo do arquivo dentro da memória Ram...
TBlobField(ADOQuery1.FieldByName('arquivo')).SaveToStream(S);
//Ainda não sei a função do posicionamento...
S.Position := 0;
//Transferência dos dados da Ram para o arquivo criado
FileStream.CopyFrom(S, S.Size);
//Abertura do arquivo.
//RESULT := 'c:\arquivo.pdf';
ShellExecute(handle, 'open', 'c:\arquivo.pdf', '', '', SW_SHOWNORMAL);
finally
S.Free;
FileStream.Free;
end;
end;
//Testando a conexão com o banco MySQL... (funcional)
procedure TForm1.btTestaConexaoClick(Sender: TObject);
begin
try
ADOConnection1.Open();
ShowMessage('Conectou!!');
except
on erro_ao_conectar: Exception do
ShowMessage(erro_ao_conectar.Message);
end;
end;
end.
Diego Bispo
Gostei + 1
Mais Posts
22/11/2013
Diego Bispo
Gostei + 0
28/06/2018
Douglas
Gostei + 0
28/06/2018
Emerson Nascimento
S := TMemoryStream.Create;
try
//Criação do arquivo que receberá o pdf...
FileStream := TFileStream.Create('c:\\arquivo.pdf', fmCreate);
//Salvamento do conteúdo do arquivo dentro da memória Ram...
TBlobField(ADOQuery1.FieldByName('arquivo')).SaveToStream(S);
//Ainda não sei a função do posicionamento...
S.Position := 0;
//Transferência dos dados da Ram para o arquivo criado
FileStream.CopyFrom(S, S.Size);
//Abertura do arquivo.
//RESULT := 'c:\\arquivo.pdf';
ShellExecute(handle, 'open', 'c:\\arquivo.pdf', '', '', SW_SHOWNORMAL);
finally
S.Free;
FileStream.Free;
end;
não poderia ser somente isto:
try
TBlobField(ADOQuery1.FieldByName('arquivo')).SaveToFile('c:\\arquivo.pdf');
ShellExecute(handle, 'open', 'c:\\arquivo.pdf', '', '', SW_SHOWNORMAL);
except
end;
Gostei + 0
28/06/2018
Emerson Nascimento
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)