做过办公自动化的高手请进!我想做这么一个ActiveX控件,从数据库中把储存的word文件读出来,然后以表单提交的方式把word的内容传递给这个控件,控件负责把

L

lcdjj

Unregistered / Unconfirmed
GUEST, unregistred user!
做过办公自动化的高手请进!我想做这么一个ActiveX控件,从数据库中把储存的word文件读出来,然后以表单提交的方式把word的内容传递给这个控件,控件负责把word文件打开,就这么简单,可我一直不成功(300分)<br />谁能帮助我,万分感谢!
 
找到下面这篇文章,希望对你有帮助:

在Delphi中处理word文档与数据库的互联
(加入时间:2001-12-17 点击数:451)
转载自“泡吧”(文/江苏电力研究所计算中心 陈炎)
目前,Delphi被越来越多的人选中作为MIS系统开发中的前台工具。在以Delphi为前台,一些大型数据库为后台的MIS系统中,图形的处理不可避免;即从以Delphi开发的前台界面输入图形,并保存到相应的数据库字段中。在这种形式的图形处理中,BMP文件的处理比较简单,因为Delphi本身有Image和DBImage构件,用这些构件与数据库中可以保存图形的大型字段BLOB比较容易地进行数据交换。以这种方式进行图形处理已应用在许多MIS软件中,包括处理人员照片的人事档案系统等。

---- 但是,BMP文件一般都比较大。而且有时要录入的是自己在计算机上画的简图,并伴随大量文字说明。这种情况用Win95中的画图板等处理BMP文件的工具处理就比较困难。一般应用人员都喜欢用WORD画图和写说明文字,然后保存到数据库中。

---- 经过一段时间的摸索,我们解决了这个问题,并经过完善,在应用中运行较好。程序如下:

procedure TsampleForm.OpenDOCClick(Sender: TObject);
var
MemSize: Integer;
Buffer: PChar;
MyFile: TFileStream;
Stream: TBlobStream;
begin
OpenDialog1.Filter:='WORD文档(*.DOC)|*.DOC'
;{从对话窗选择文件}
if OpenDialog1.Execute then begin
MyFile:=TFileStream.Create
(OpenDialog1.FileName,fmOpenRead);
with table1 do {‘table1’为含BLOB字段的表名}
begin
Open;
Edit;
Stream := TBlobStream.Create(FieldByName('Doc')
as TBlobField, bmWrite);
{‘Doc’为BLOB字段名}
MemSize := MyFile.Size;
Inc(MemSize)
{Make room for the
buffer's null terminator.}
Buffer := AllocMem(MemSize)

{Allocate the memory.}
try
Stream.Seek(0, soFromBeginning);
{Seek 0 bytes from the stream's end point}
MyFile.Read(Buffer^,MemSize);
Stream.Write(Buffer^,MemSize);
finally
MyFile.Free;
Stream.Free;
end;
try
Post;
except
on E: EDatabaseError do
if HandelException(E)< >0 then exit
else
raise;
end;
end;
Doc_ole.CreateObjectFromFile
(OpenDialog1.FileName,False);
Doc_ole.Run;{Doc_ole为ToleContainer构件名}
end;
end;

---- 以上为向数据库中写入的程序,应用中从对话窗取出文件在ToleContainer构件中显示的同时存入数据库。

procedure TsampleForm.GetDocClick
(Sender: TObject);
var
MemSize: Integer;
Buffer: PChar;
MyFile: TFileStream;
Stream: TBlobStream;
begin
MyFile:=TFileStream.Create('c:/temp.tmp',fmCreate);
with Query1 do
begin
Stream := TBlobStream.Create
(FieldByName('Doc') as TBlobField, bmRead);
MemSize := Stream.Size;
Inc(MemSize)

{Make room for the buffer's null terminator.}
Buffer := AllocMem(MemSize)

{Allocate the memory.}
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');
Doc_ole.CreateObjectFromFile
('c:/temp.DOC',False);
Doc_ole.Run;
end;
end;

---- 以上程序为从数据库从将WORD文档取出,并放在temp.doc的临时文件上并在ToleContainer构件中显示。

---- 在程序的其他部份应准确控制表记录指针,使WORD文档的存取发生在正确的记录位置。
 
怎样存储、读取DOC文件我已解决,关键是如何把从数据读出的DOC文件传输到本地。
各位大虾们,希望大家给我点启示!我的Email:1941@peoplemail.com.cn
 
我以前写的一个小程序的一部分

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, ADODB, ComCtrls,shellapi, ExtCtrls, ImgList;

type
TForm1 = class(TForm)
ADOConnection1: TADOConnection;
ADOQuery1: TADOQuery;
OpenDialog1: TOpenDialog;
Button1: TButton;
Button2: TButton;
Button3: TButton;
SaveDialog1: TSaveDialog;
TreeView1: TTreeView;
ImageList1: TImageList;
Label1: TLabel;
Timer1: TTimer;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure TreeView1DblClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormClose(Sender: TObject
var Action: TCloseAction);

private
procedure relist();
function ExecuteFile(AppHandle:integer
const FileName,
Params, DefaultDir: string
ShowCmd: Integer;
var ProcessHandle: Longint): THandle;
function GetFileLastAccessTime(sFileName:string;uFlag:integer):TDateTime;
function IsFileInUse(fName : string) : boolean;
public

{ Public declarations }
end;

var
Form1: TForm1;
filenameex:string;

implementation

{$R *.dfm}

function tform1.IsFileInUse(fName : string) : boolean
//判断一个文件是否正在被使用
var
HFileRes : HFILE;
begin
Result := false;
if not FileExists(fName) then
exit;
HFileRes := CreateFile(pchar(fName), GENERIC_READ or GENERIC_WRITE, 0 {this is the trick!}, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
Result := (HFileRes = INVALID_HANDLE_VALUE);
if not Result then
CloseHandle(HFileRes);
end;

function Tform1.GetFileLastAccessTime(sFileName:string;uFlag:integer):TDateTime
//获得文件的创建、修改及最后访问时间
var
ffd:TWin32FindData;
dft:DWord;
lft:TFileTime;
h:THandle;
begin
h:=FindFirstFile(PChar(sFileName),ffd);
if h<>INVALID_HANDLE_value then
begin
case uFlag of
1:FileTimeToLocalFileTime(ffd.ftCreationTime,lft);
2:FileTimeToLocalFileTime(ffd.ftLastWriteTime,lft);
3:FileTimeToLocalFileTime(ffd.ftLastAccessTime,lft);
else
FileTimeToLocalFileTime(ffd.ftLastAccessTime,lft);
end;
FileTimeToDosDateTime(lft,LongRec(dft).Hi,LongRec(dft).Lo);
Result:=FileDateToDateTime(dft);
windows.FindClose(h);
end
else
result:=0;
end;


function TForm1.ExecuteFile(AppHandle:integer
const FileName, //执行外部文件
Params, DefaultDir: string
ShowCmd: Integer;
var ProcessHandle: Longint): THandle;
var
info: TShellExecuteInfoA;
begin
info.cbSize := sizeof(info);
info.Wnd := AppHandle;
info.lpFile := PChar(FileName);
info.lpVerb := PChar('open');
info.lpParameters := PChar(params);
info.lpDirectory := PChar(DefaultDir);
info.nShow := ShowCmd;
info.fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_NO_UI;
ShellExecuteEx(@info);
ProcessHandle := info.hProcess;
result := info.hInstApp;
end;




procedure tform1.relist()
//刷新treeview
var
i:integer;
TreeNodes:TTreeNodes;

begin

treeview1.Items.Clear;
TreeNodes:=TreeView1.Items;
adoquery1.Close;
adoquery1.sql.text:='select * from myfile where fileowner=''lijp'' ';
adoquery1.open;
for i:=0 to adoquery1.RecordCount-1 do
begin
TreeNodes.Add(Nil,adoquery1.fieldbyname('filename').AsString);
adoquery1.Next;
end;
end;

procedure TForm1.Button1Click(Sender: TObject)
//上传文件
var FileName :String;
begin
if opendialog1.Execute then
if opendialog1.FileName<>'' then
begin
FileName := ExtractFileName(OpenDialog1.FileName);
with adoquery1 do
begin
Close;
Sql.text:='INSERT INTO myfile (filename,savefile,fileowner) VALUES :)FileName,:FileSource,:fileowner)';
Parameters.ParamByName('FileName').Value:=filename;// .AsString:= FileName;
Parameters.ParamByName('FileSource').LoadFromFile(OpenDialog1.FileName,ftBlob);
parameters.parambyname('fileowner').value:='lijp';
Prepared;
ExecSQL;
application.ProcessMessages;
messagebox(0,'文档上传完毕!','提示',0);
self.relist;
end;
end;
end;

procedure TForm1.Button2Click(Sender: TObject)
//update文件
var
FileName,filedir :String;
begin
if savedialog1.Execute then
if (savedialog1.FileName<>'')and (treeview1.Selected<>nil) then
begin
filedir:= ExtractFileName(savedialog1.FileName);
with adoquery1 do
begin
Close;
Sql.text:=format('SELECT * FROM myfile WHERE FileName = ''%s''',[treeview1.selected.text]);;
Open;
FileName :=FieldByName('FileName').AsString;
(FieldByName('savefile') AS TBlobField).SaveToFile(FileName);
end;
end;
end;

procedure TForm1.Button3Click(Sender: TObject)
//下载文件
var FileName :String;
begin
if opendialog1.Execute then
if opendialog1.FileName<>'' then
begin
FileName := ExtractFileName(OpenDialog1.FileName);
with adoquery1 do
begin
close;
sql.text:='select * from myfile';
open;
Edit;
fieldbyname('filename').Value:=filename;
(FieldByName('savefile') AS TBlobField).LoadFromFile(OpenDialog1.FileName);
post;
messagebox(0,'文档更新完毕!','提示',0);
self.relist;
end;
end;
end;

procedure TForm1.FormCreate(Sender: TObject)
//系统初始化时建一个为‘c:/mypdm'的放文件的临时目录

begin
{$I-}
mkdir('c:/mypdm');
setCurrentDir('c:/mypdm');
{$I+}
self.relist;
end;

procedure TForm1.TreeView1DblClick(Sender: TObject)
//双击treeeview时下载文件,并使其可以 编辑,发生修改后提示,是否保存.
var
FileName,filedir:String;
iProcessHandle:integer;
i:integer;
begin

// filedir:='c:/mypdm/';
with adoquery1 do
begin
Close;
Sql.text:=format('SELECT * FROM myfile WHERE FileName = ''%s''',[treeview1.selected.text]);;
Open;
FileName :=FieldByName('FileName').AsString;
(FieldByName('savefile') AS TBlobField).SaveToFile(filedir+FileName);
end;
ExecuteFile(self.Handle,filename,'','',SW_SHOW,iProcessHandle);
for i:=0 to 100 do
begin
end;
adoquery1.Close;
adoquery1.SQL.Text:=format('update myfile set updatetime=''%s'' where filename=''%s''',[datetimetostr(getfilelastaccesstime(filename,2)),treeview1.selected.text]);
adoquery1.execsql;
memo1.Lines.Add(adoquery1.SQL.Text);
filenameex:=filename;
self.Timer1.Enabled:=true;
end;


procedure TForm1.Timer1Timer(Sender: TObject);
begin
label1.Caption:=datetimetostr(getfilelastaccesstime(filenameex,2));
// if not IsFileInUse(filenameex) then
adoquery1.Close;
adoquery1.SQL.Text:=format('select count(*) as count from myfile where filename=''%s'' and updatetime<''%s''',[filenameex,datetimetostr(getfilelastaccesstime(filenameex,2))]);
adoquery1.Open;
memo1.Lines.Add(adoquery1.SQL.Text);
if (adoquery1.FieldByName('count').AsInteger=1) and not(IsFileInUse(filenameex)) then
// if FileExists(filenameex) then
begin
self.Timer1.Enabled:=false;
if messagedlg('是否保存?',mtconfirmation,[mbyes,mbno],0)=mryes then
with adoquery1 do
begin
close;
sql.text:=format('select * from myfile where filename=''%s''',[filenameex]);
open;
Edit;
(FieldByName('savefile') AS TBlobField).LoadFromFile(filenameex);
fieldbyname('updatetime').Value:=datetimetostr(now);
post;
end;
end;
// end;
end;

procedure TForm1.FormClose(Sender: TObject
var Action: TCloseAction)
//关闭系统时清空'c:/mypdm'文件夹上的所有检出的文件
var
sr: TSearchRec;
FileAttrs: Integer;
begin
fileattrs:=faAnyFile;
if FindFirst('c:/mypdm/*.*', FileAttrs, sr) = 0 then

begin
repeat
if (sr.Attr and FileAttrs) = sr.Attr then
begin
DeleteFile(sr.Name);
end;
until FindNext(sr) <> 0;
FindClose(sr);
end

end;

end.
 
"如何把从数据读出的DOC文件传输到本地"
是指什么意思?是保存到本地吗?
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
947
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
顶部