小妹的毕业设计做得差不多了,是一个delphi+oralce的数据查询系统。中间碰到了很多困难,通过大家的帮助,感觉长进了不少。不过也有被教训的时候,前几天在这里发帖子请教问题,还被人家骂作“不想付出,只想收获的混蛋”。郁闷了很久,一气之下,重新看了一遍资料,总算把那个问题解决了。详情请看:《毕业真的成问题了:在数据库中存取word文档,上40K就报错!》http://expert.csdn.net/Expert/topic/1821/1821292.xml?temp=.654339现在数据库的大体功能都可以实现,只剩下两个问题1。怎么把select出来的记录,通过ole显示出来。因为我的数据库支持模糊查询,有可能一次返回多条数据,我的想法是,移到某条记录时,点击button按钮就可以通过ole显示出文档或者图片。用ole从文件中读取ole的语句是这样的olecontainner1.loadfromfile('tmp') (是这样,没错吧?)那么,问题就集中在如何把我选中的文件savetofile出来。我手头上这几本讲delphi数据库操作的书上,都没有提到这个方法,大家可以指点指点吗?我自己也接着找找看,看有没有更好的方法。2。ole似乎不支持pdf 文档,可是我这里大多数资料都是pdf的,有解决的办法么?安装插件?谢谢了:)
解决方案 »
- C# 调用Delphi写的Web Services 返回中文乱码的问题!
- 读注册表数值并显示出来。!
- 转换。等着急,
- FastReport或ReportMachine 如何实现即打即停功能,请给出源码。感激!
- 数据导出到excel,前面的0自动去掉了,我不想去掉,因为这个字段是‘学号,去掉学号就不对了?
- 关于主从表的问题
- 大家评论那种报表工具好用?fastreport 能够预览修改数据保存到数据库吗?参与讨论有分!
- Delphi工程问题
- 在Delphi里用API要声明吗?有没有好的API工具?生成的程序能不能小点?怎么动不动就200多k?
- 使用DBgrid更新数据库的问题:新增一个数据,再把焦点移开(他会自动post)后,新增的那条竟然会遮住第一条
- MM,有个难题急需解决(关于录入一篇文章)
- 在改变窗体大小的时候,如何让windows media player9 自适应窗体大小阿!
你的毕业设计好像很复杂啊,看来我能从你这里获得不少分啊!呵呵。没分了就在qq上问我把!
~~我还真没有这样用过,学习
太阳雨兄,不如我加你的qq吧,keke:)
BLOB在数据库的表中实际上是以二进制数据的形式存放的。由于BLOB的特殊性,一般的程序都无法处理它。比如,如果在一张表中存在BLOB,当用Dattabase Desktop(Delphi在带的数据库管理工具)打开它时,BLOB列将只显示BLOB字样。至于该列中实际存的是什么数据是单靠Database DeskTop是无法得到的。如果在我们编制的程序中,用DBGrid控件打开一个有BLOB字段的表,效果也一样。我们的程序无法直接显示、编辑以及插入BLOB字段。可见,常规的方法是不能满足要求的。
如何处理BLOB字段,可以借鉴一些可视的桌面数据库的方法。如Access中,BLOB字段是可以通过双击该字段的方式打开。Access是通过OLE的方式实现BLOB数据的编辑及处理的,所以我们也可以在通过程序中设置OLE控件的方法来处理BLOB。下面,我们先讨论操作BLOB的关键问题,然后给出一个简单的例子。操作BLOB的关键
要在程序中自如地操作BLOB数据,无非是解决以下几个问题:
1. BLOB数据的入库操作
2. BLOB数据的显示
3. BLOB数据的编辑、修改
由于数据的类型可能千变万化,所以,采用OLE方式是较方便的选择。我们可以在程序中放置一个OLE控件,用于显示、编辑各种BLOB数据。那么,问题的关键就是BLOB数据如何入库,以及数据库如何与OLE控件之间传递数据。
第一种解决方案是在库中直接保存原始数据。具体方法如下:
BLOB数据的入库:要把BLOB数据入库,不能向普通的数据那样直接赋值;而是利用BLOB字段的LoadFromfile方法。采用这个方法,可以直接将各种数据的数据文件存入数据库。代码如下:
AblobField.LoadFromfile(aFileName);
数据库与OLE控件间的数据传递也要通过数据文件。即,BLOB字段先将数据存盘;然后,OLE从将数据文件中创建所需要的OLE对象。代码如下:
AblobField.SaveToFile(aFileName);
AOleContainer.CreateObjectFromFile(aFileName);
注意:OLE对象不能直接使用LoadFromFile方法,因为,数据库中存放的BLOB对象的格式是文件原来的格式,而不? E格式,是不能直接读取的。直接读取将导致运行错误。 第二种方案是在库中以OLE格式保存数据。具体方法如下:
本方案的不同之处,在于数据入库前先进行格式的转换。格式的转换是通过OLE控件完成的。即,先创建OLE对象,然后入库。示例代码如下:
AOleContainer.CreateObjectFromFile(aFileName);
AoleContainer.SaveToFile(tmpFileName);
AblobField.LoadFromfile(tmpFileName);
这样作的好处是,由于库中直接存储的是OLE格式,所以,在库与OLE控件之间的数据传递将非常方便。在这种情况下,可以通过文件直接传递:数据字段先将数据存到一个临时文件中,然后,OLE控件从临时文件中读取。即:
AblobField.SaveToFile(aFileName);
AOleContainer.LoadFromFile(aFileName);
另外,还可以通过内存流来完成。使用内存流,可减少磁盘操作,大大提高运行效率。即:
AblobField.SaveToStream(aStream);
AOleContainer.LoadFromStream(aStream);下面是一个简单的例子。一个简单的例子
本例中,采用Paradox数据库。库中有两个字段,一个是字符型,另一个是BLOB型。我们在主Form上放一个OLE控件用于编辑及转换数据。一个ADOTable控件操作数据库。源代码如下:unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, OleCtnrs, DB, ADODB, Grids, DBGrids;type
TForm1 = class(TForm)
ADOTable1: TADOTable;
ADOTable1DocuID: TWideStringField;
ADOTable1DocuContent: TBlobField;
OleContainer1: TOleContainer;
Button1: TButton;
OpenDialog1: TOpenDialog;
DBGrid1: TDBGrid;
DataSource1: TDataSource;
OpenTable: TButton;
CloseTable: TButton;
procedure Button1Click(Sender: TObject);
procedure OpenTableClick(Sender: TObject);
procedure ADOTable1AfterScroll(DataSet: TDataSet);
procedure CloseTableClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
fn: string;
begin
ADOTable1.Edit;
if OpenDialog1.Execute then begin //打开文件
fn := ExtractFileName(OpenDialog1.FileName);
ADOTable1DocuID.AsString := fn;
OleContainer1.CreateObjectFromFile(OpenDialog1.FileName, False); //创建OLE对象
OleContainer1.SaveToFile('tmp'); //将OLE数据存入临时文件
ADOTable1DocuContent.LoadFromFile('tmp'); //将OLE数据存入数据库
ADOTable1.UpdateRecord;
end;
end;procedure TForm1.OpenTableClick(Sender: TObject);
begin
ADOTable1.Open ;
end;procedure TForm1.ADOTable1AfterScroll(DataSet: TDataSet);
begin
if not ADOTable1DocuContent.IsNull then begin
ADOTable1DocuContent.SaveToFile('tmp'); //数据存入临时文件
OleContainer1.LoadFromFile('tmp'); //从临时文件中读取OLE对象
end;
end;procedure TForm1.CloseTableClick(Sender: TObject);
begin
ADOTable1.Close ;
end;procedure TForm1.FormCreate(Sender: TObject);
beginend;end.
begin
if not query1files.isnull then begin
query1files.savetofile('temp');
olecontainer1.loadfromfile('temp');
end;
end;
var SFileName: string;
function FileToString(const FileName: string): string;
begin
with TFileStream.Create(FileName, fmOpenRead) do
try
setLength(Result, size);
Read(pointer(Result)^, size);
finally
free;
end;
end;
begin
if OpenDialog1.Execute then
begin
SFileName := OpenDialog1.FileName;
ADODataSet1.Edit;
ADODataSet1.FieldByName('FileMatter').AsString := filetostring(SFileName);
Adodataset1.Post;
end;
end;procedure TForm1.Button2Click(Sender: TObject);
var SFileName: string;
BS: TAdoBlobStream;
begin
BS := TAdoBlobStream.Create(TBlobField(ADODataSet1.FieldByName('FileMatter')), bmRead);
try
SFileName := Extractfilepath(application.ExeName) + 'tempfile.' + ADODataSet1.fieldbyname('FileExtra').AsString;
BS.SaveToFile(SFileName);
OleContainer1.CreateObjectFromFile(SFileName, false);
finally
BS.free;
end;
end;
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OleCtnrs, StdCtrls, DB, DBTables;type
TForm1 = class(TForm)
Table1: TTable;
OpenDialog1: TOpenDialog;
Button1: TButton;
Button2: TButton;
OleContainer1: TOleContainer;
DBNavigator1:TDBNavigator;
Database1: TDatabase;
Button3: TButton;
Button4: TButton;
Table1NAME: TStringField;
Table1SIZE1: TStringField;
Table1DOC: TBlobField;
Edit1:TEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
memsize:integer;
buffer:pchar;
myfile:tfilestream;
stream:tblobstream;
begin
myfile:=tfilestream.Create('c:\temp.tmp',fmcreate);
with table1 do
begin
open;
stream:=tblobstream.Create(fieldbyname('doc')as tblobfield,bmread);
memsize:=stream.Size;
inc(memsize);
buffer:=allocmem(memsize);
try
stream.Read(buffer^,memsize);
myfile.Write(buffer^,memsize);
finally
myfile.Free;
stream.Free;
end;
end;
if fileexists('c:\temp.doc') then
deletefile('c:\temp.doc');
if fileexists('c:\temp.tmp') then
begin
renamefile('c:\temp.tmp','c:\temp.doc');
OleContainer1.CreateObjectFromFile('c:\temp.doc',false);
OleContainer1.Run;
end;
end;procedure TForm1.Button2Click(Sender: TObject);
var
memsize:integer;
buffer:pchar;
myfile:tfilestream;
stream:tblobstream;
filename:string;
begin
opendialog1.filter:='(*.doc)|*.doc';
if opendialog1.Execute then
begin
filename:=opendialog1.FileName;
myfile:=tfilestream.Create(filename,fmopenread);
with table1 do
begin
open;
edit;
stream:=tblobstream.Create(fieldbyname('doc')as tblobfield,bmwrite);
memsize:=myfile.Size;
inc(memsize);
buffer:=allocmem(memsize);
try
stream.Seek(0,sofrombeginning);
myfile.Read(buffer^,memsize);
stream.Write(buffer^,memsize);
fieldbyname('name').AsString:=extractfilename(filename);
fieldbyname('size1').AsString:=inttostr(memsize-1);
finally
myfile.Free;
stream.Free;
end;
try
table1.Post;
except
showmessage('保存失败');
halt;
end;
showmessage('保存成功');
OleContainer1.createobjectfromfile(filename,false);
OleContainer1.run;
end;
end;
end;procedure TForm1.Button3Click(Sender: TObject);
begin
OleContainer1.CleanupInstance;
OleContainer1.Refresh;
end;
procedure TForm1.Button4Click(Sender: TObject)
begin
with table1 do
begin
indexfieldnames:='name';
if findkey([edit1.text]) then
end
end;
end;end.呵呵,这样就可以在edit1里输入你想查找的name,然后点击button4,查找到后,点击button1,激活ole,查看了。任务算是完成了,但是还有两点不足:
1. table的查询功能不如query强大,我希望还是可以用query来实现
2。ole不支持pdf的问题没有解决。嘿嘿,帖子暂时不结。等我进一步完善了再来和大家讨论吧。大家也要想想啊。
begin
DeskTopStream := TMemoryStream.Create;
dxFlowChart1.SaveToStream(DeskTopStream);
M0.pas_m.Close;
M0.pas_m.SQL.Text := 'select * from PAS_M where pas_m_id=' + '''' + sysuser + '''';
M0.pas_m.Open;
if not M0.pas_m.Eof then
begin
M0.pas_m.Edit;
TBlobField(M0.pas_m.FieldByName('Cust_DeskTop')).LoadFromStream(DeskTopStream);
M0.pas_m.FieldByName('Cust_BKColor').AsInteger := dxFlowChart1.Color;
M0.pas_m.UpdateBatch;
M0.pas_m.Close;
end;
DeskTopStream.Position := 0;
Mdi.dxFlowChart1.LoadFromStream(DeskTopStream);
Mdi.dxFlowChart1.Color := dxFlowChart1.Color;
Mdi.dxFlowChart1.Zoom := 0;
DeskTopStream.Free;
end; action := cafree;
end;
1。使用query肯定是没有问题的
2。ole显示 pdf应该是可以的,实在不行,acr提供了一个ocx,pdf.ocx ,acr开头的
我按照你说的方式对word文档进行存储,可是执行以后,数据库中午任何内容,不知怎么回事?还有那个database控件的用处是什么?如何设置?
我的毕业设计也快验收了,麻烦你给我讲一下。谢谢。
Hid(海涛) ,你说的问题我也发现了,后来改用loadfromfile,一句话搞定。你自己试试
savetofile就是query的一个字段名的savetofile。
OLE可以承载 PDF.
帮你U~~~~~~~~~~~~~~~~~P!
if OpenDialog.Execute then
begin
DataModule2.FILES.LoadFromFile(OpenDialog.FileName);
end;
end;用这个取代存入的那段代码。
我正在写论文,中间比较了这两种方法,请你讲讲ole怎么承载pdf.
我还是不明白,可否把你的那段存取word文档的代码发给我看看,我只是学习一下,并无它意。我的毕业设计快验收了,我真的很上火啊。我现在只想知道怎么存取word文档。[email protected]
---
var
MS:TMemoryStream;
sSQL,sSpecialityID:String;
begin
MS:=TMemoryStream.Create;
TJPEGImage(Image.Picture.Graphic).SaveToStream(MS);//将图像数据写入内存流
MS.Position:=0; ADOQuery.Open;
ADOQuery.Append;
TBlobField(ADOQuery.FieldbyName('Photo')).LoadFromStream(MS);
ADOQuery.Post;
MS.Free;
except
Application.MessageBox('保存信息失败,请重试!', '系统提示', MB_OK +
mb_IconExclamation);
end;end;--------读取:
---
var
MyJPEG:TJPEGImage;
MS:TMemoryStream;
bs:TBlobStream;
begin
{**取出相片**}
MyJPEG:=TJPEGImage.Create;
MS:=TMemoryStream.Create;
try
TBlobField(ADOQuery.FieldByName('Photo')).SaveToStream(MS);
MS.position :=0;
MyJPEG.LoadFromStream(MS);
//DBImage.picture.assign(MyJPEG);该控件的使用
Image.picture.assign(MyJPEG);
finally
MyJPEg.free;
MS.free;
end;
end;