请教:“文件→OleContainer→Stream→数据库”,如何还原出文件? ( 积分: 200 )

  • 主题发起人 主题发起人 赵抄
  • 开始时间 开始时间

赵抄

Unregistered / Unconfirmed
GUEST, unregistred user!
我将文件通过OleContainer保存到数据库(文件→OleContainer→Stream→数据库),
逆过程却只能做到OleContainer(数据库→Stream→OleConainer),我希望通过执行
OleContainer.SaveAsDocument得到原来的文件,但生成的文件无法打开,
据分析是在文件头尾加了OLE描述信息。

请有经验的朋友指点一下,谢谢!
 
我将文件通过OleContainer保存到数据库(文件→OleContainer→Stream→数据库),
逆过程却只能做到OleContainer(数据库→Stream→OleConainer),我希望通过执行
OleContainer.SaveAsDocument得到原来的文件,但生成的文件无法打开,
据分析是在文件头尾加了OLE描述信息。

请有经验的朋友指点一下,谢谢!
 
有详细的方案更好。
 
高手,请现身。
 
试试:若是WORD 文档
OleContainer1.SaveAsDocument(SaveDialog1.FileName+'.doc');
 
这是我的一段代码,看看对你有用否
type
TStreamHead = record
Signature: Integer; //$434F4442
DrawAspect: Integer; //1
DataSize: Integer; //stream.size;
end;

Ttree=record
id:string;
wjlx:string;
mc:string;
end;

........
取出
procedure Tfrmword.tv1Change(Sender: TObject; Node: TTreeNode);
var
rtree:ptree;
word_id:string;
mem :Tmemorystream;
Stream1:Tstream;
st:TStringStream;
blobstream:Tblobstream;
head: TStreamHead;
ms ,stream: Tmemorystream;
begin
if node.Level=0 then
begin
self.pm1.Items[0].Visible :=true; //添加子项
self.pm1.Items[1].Visible :=true; //添加子项
exit
end
else
begin
self.pm1.Items[0].Visible :=false; //添加子项
self.pm1.Items[1].Visible :=false; //添加子项
end;

OleContainer1.Visible :=false;
rtree:=node.Data;
word_id:=rtree.id;
with qry1 do
begin
close;
sql.Clear;
sql.Add('select * from word where id='''+word_id+'''');
open;
end;
stream:=TMemoryStream.Create;
ms := TMemoryStream.Create;
TBlobfield(qry1.FieldByName('内容')).SaveToStream(stream); //"内容"字段为Image类型
if stream.Size = 0 then
begin
stream.Free;
exit;
end;
frmWait :=TfrmWait.Create(self);
frmWait.Show;
frmWait.Update;
with head do
begin
Signature := $434F4442;
DrawAspect := 1;
DataSize := stream.size;
end;
ms.WriteBuffer(head,sizeof(head));
ms.CopyFrom(stream,0) ;
ms.Position := 0;
olecontainer1.LoadFromStream(ms);
self.OleContainer1.Visible :=true;
OleContainer1.DoVerb (1);
self.OleContainer1.Align :=AlClient;
// olecontainer1.OleObject.application.CommandBars['Standard'].Visible:=false;
//// olecontainer1.OleObject.application.CommandBars['Formatting'].Visible:=false;
// olecontainer1.OleObject.application.CommandBars['Tables and Borders'].Visible:=false;
tv1.SetFocus; //为了去除菜单
frmWait.Free;
frmWait :=nil;
{tblobfield(qry1.FieldByName('内容')).SaveToFile('d:/test.doc');
self.OleContainer1.CreateObjectFromFile(tmppath,false);
self.OleContainer1.DoVerb(1) ;
tv1.SetFocus;
这段语句也没有问题,只不过通过外部文件过渡,时间效率都很慢 }
end;


--------
以下为保存
procedure Tfrmword.btn1Click(Sender: TObject);
var
rptree:ptree;
begin
if tv1.Selected.Level=0 then
begin
getmsg('information','请选择子节点');
exit;
end
else
begin
rptree:=tv1.Selected.Data;
if dlgopen1.Execute then
begin
qry1.Close;
qry1.SQL.Clear;
qry1.SQL.Add('select * from word where id='''+rptree.id+'''');
qry1.open;
qry1.edit;
TBlobField(qry1.FieldByName('内容')).LoadFromFile(dlgopen1.FileName);
qry1.Post;
self.OleContainer1.CreateObjectFromFile(dlgopen1.FileName,false);
self.OleContainer1.Visible :=true;
self.OleContainer1.DoVerb(1);
tv1.SetFocus;
end;
end;

end;
 
》huanghq123,
试过了,生成的文件已经跟原来的不一样,在头部加了OLE的相关信息。
谢谢你的热情!

》yf168
我看了你的代码,你是直接将文件用STREAM方式保存到BLOB字段,而我是用OleContainer的SaveToStream保存到BLOB字段,你代码中没有关于去掉Ole附件信息的方法,因此不能解决我的问题。
非常感谢你的热情!!

欢迎继续关注此题。
 
TStreamHead = record
Signature: Integer; //$434F4442
DrawAspect: Integer; //1
DataSize: Integer; //stream.size;
end;
这个是吗?with head do
begin
Signature := $434F4442;
DrawAspect := 1;
DataSize := stream.size;
end;
ms.WriteBuffer(head,sizeof(head));
ms.CopyFrom(stream,0) ;
ms.Position := 0;
olecontainer1.LoadFromStream(ms);
 
你写的这段是给Stream加个头。
 
你写这段跟如下代码效果相同(优点是不用生成临时文件):
Stream.SaveToFile('C:/temp.DOC');
Olecontainer1.CreateObjectFromFile('C:/temp.DOC',False');
 
没人解决过这个问题吗?若嫌分少,可以加到1000分。
 
呵呵,我会。你给多少分?
 
to 2ys
既然会就讲一下嘛,怎么不给分就不讲吗?
 
to 2ys
如果方案可行,可以给你1000分。如对本人信誉有任何怀疑,可以去查查我以前是如何给分的。
 
用word中的wordapplication和worddocument,分别命名为wain和wdin编程如下:
存入:procedure TForm3.BitBtn1Click(Sender: TObject);
begin
inherited;
waIn.Connect;
newdocument:=waIn.Documents.Add(EmptyParam,EmptyParam,EmptyParam,EmptyParam);
wdIn.Connectto(newdocument);
waIn.Visible:=true;
waIn.Disconnect;
wdIn.SaveAs(nrFilename);
end;
取出:procedure TForm5.BitBtn1Click(Sender: TObject);
begin
inherited;
if datamodule2.ADOQuery5.IsEmpty then
begin
Application.Messagebox('没有选中习题!', '系统提示', MB_OK + MB_ICONWARNING);
end;
nrFileName:=extractfilepath(application.EXEName)+'question/'+ datamodule2.ADOQuery5.FieldByName('题目ID').AsString +'题内容.doc';
TBlobField(datamodule2.ADOQuery5.FieldByName('题目内容')).SaveToFile(nrFileName);
waIn.Connect;
newdocument:=waIn.Documents.Open(nrFileName,EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam);
wdIn.Connectto(newdocument);
waIn.Visible:=true;
waIn.Disconnect;
end;
运行结果我不能抓图上传,这是我几年前的一个作品教师出题系统,用到了word现在把它奉贤给大家,其中要引用单元adodb,word2000,wordxp,注意引用单元,有问题可以咨询175534968
 
FileName,nrFileName,daFileName:olevariant;
newDocument:_Document;
 
to 温柔剑客:
你的方案解决了这样的问题“文件→Stream→数据库;数据库→Stream→File→OleContainer”。

而我的需求是,文件由“File→OleContainer→Stream→数据库”这样的过程存储到数据库,我希望通过反向操作还原出原来的文件。问题是,但我经过反向操作得到的文件已经无法双击打开,原因是OleContainer在文件中添加了额外的信息(问题是如何去掉文件中这额外的信息)。
 
我的软件作品,欢迎使用,下载地址:
http://download.enet.com.cn/html/010142005112101.html
 
想请问一个问题!不知在ole 中嵌入word 后,怎么才能保存!
谢谢各位!
 
OleContainer附加的信息是不需要处理的,OleContainer自然可以认识,我认为你是在读取的时候少加了一句话而已。
读取之前,你试试加上stream.postion:=0吧。
读取之前还是之后我忘记了,你trytry
 
后退
顶部