【问题标题】:Creating Word document from Delphi, saving as Doc and as PDF从 Delphi 创建 Word 文档,保存为 Doc 和 PDF
【发布时间】:2011-12-06 18:23:26
【问题描述】:

我需要使用特定模板从 Delphi 创建一个 Word 文档,将文档保存为具有给定名称的 Word 文档,然后将同一个文档以相同的名称保存为 PDF 文件。 (在 Word 2007 中,可以使用 SaveAsPdf... 插件来完成。在 Word 2010 中,它是一个内置功能)

如何使用 Delphi XE 做到这一点?

【问题讨论】:

  • 我用 vbscript 来做。这会有帮助吗?
  • @TLama 无意冒犯,就我而言,离开 Delphi 已经很长时间了(当然是流着泪),我认为所有人都应该如此。
  • 你已经拥有了什么?您知道如何在 Word 中打开文档吗?客户端将提供哪些 Word 版本?如果是Word 2010,应该不是很难。只需使用COM打开文档并将其保存为pdf,正是你想要的。

标签: delphi templates ms-word automation


【解决方案1】:

首先使用 Components | 将“Microsoft Word 12 Objects”(MS Word 2007)类型库导入您的项目中。导入组件菜单项。然后,您可以使用此示例代码加载 MS Word 文件,并使用内部 PDF 转换器将其保存为 PDF。如果您使用的是 Microsoft Word 2010,请加载其类型库而不是 Word 2007。

unit fMain;

interface

uses
  Windows, SysUtils, Variants, Classes, Controls, Forms, Dialogs, StdCtrls,
  Word_TLB;

type
  TfrmMain = class(TForm)
    btnLoad: TButton;
    btnSaveAs: TButton;
    FileOpenDialog1: TFileOpenDialog;
    FileSaveDialog1: TFileSaveDialog;
    procedure btnLoadClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure btnSaveAsClick(Sender: TObject);
  private
    FWordApp : WordApplication;
    FWordDoc : WordDocument;
    procedure InitializeApp;
    procedure FinalizeApp;
    function LoadFile(const AFileName: string): WordDocument;
    procedure SaveAsPdf(ADocument: WordDocument; const AFileName: string);
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

uses ComObj;

{$R *.dfm}

procedure TfrmMain.btnLoadClick(Sender: TObject);
begin
  if FileOpenDialog1.Execute then
    FWordDoc := LoadFile(FileOpenDialog1.FileName);
end;

procedure TfrmMain.btnSaveAsClick(Sender: TObject);
begin
  if FileSaveDialog1.Execute then
  begin
    if Assigned(FWordDoc) then
      SaveAsPdf(FWordDoc, FileSaveDialog1.FileName);
  end;
end;

procedure TfrmMain.FinalizeApp;
var
  SaveChanges: OleVariant;
begin
  if Assigned(FWordApp) then
  begin
    SaveChanges := False;
    FWordApp.Quit(SaveChanges, EmptyParam, EmptyParam);
    FWordApp := nil;
  end;
end;

procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FinalizeApp;
end;

procedure TfrmMain.InitializeApp;
begin
  FWordApp := createOleObject('Word.Application') as WordApplication;
  if Assigned(FWordApp) then
  begin
    FWordApp.Visible := False;
  end
  else
    raise Exception.Create('Cannot initialize Word application');
end;

function TfrmMain.LoadFile(const AFileName: string): WordDocument;
var
  FileName: OleVariant;
  Doc : WordDocument;
begin
  if not Assigned(FWordApp) then
    InitializeApp;

  FileName := AFileName;
  Doc := FWordApp.Documents.Open(FileName, EmptyParam, EmptyParam, EmptyParam,
                                 EmptyParam, EmptyParam, EmptyParam, EmptyParam,
                                 EmptyParam, EmptyParam, EmptyParam, EmptyParam,
                                 EmptyParam, EmptyParam, EmptyParam, EmptyParam);
  Result := Doc;
end;

procedure TfrmMain.SaveAsPdf(ADocument: WordDocument; const AFileName: string);
var
  FileName,
  FileFormat : OleVariant;
begin
  if Assigned(ADocument) then
  begin
    FileName := AFileName;
    FileFormat := wdFormatPDF;
    ADocument.SaveAs(FileName, FileFormat, EmptyParam, EmptyParam, EmptyParam,
                     EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
                     EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
                     EmptyParam);
  end;
end;

end.

我只是写了代码并运行了一次,它可以工作,但我没有彻底测试它,所以可能会有一些小故障。

【讨论】:

  • OP 明确要求使用特定模板创建新的 Word 文档...?
  • @Marjan Venema,我从标题和描述中得到的是,他/她在以特定格式保存文档时遇到问题,而不是在创建新文档时。我添加了 LoadFile() 以便能够测试代码并确保它实际上将给定的 MS Word 文档转换为 PDF。
  • @vcldeveloper 我确实同意 savetopdf 似乎很重要,但我将这篇文章作为对单词自动化帮助的一般呼吁; “create”(在标题中)读起来不像“load”,而且 OP 的第一句话也很明确。
  • 我明天试试你的代码 - 这里快 2200 了 :-) 所以是时候买电视和床了。
  • @Marjan Venema,OP 在描述中提到他可以使用 SaveAsPlugin 在 MS Word 2007 中解决他的问题,所以我的结论是他的主要问题是将文档保存为 PDF。如果他也有创建新文档的问题,可以通过调用 FWordApp.Documents.Add() 方法轻松完成,如果需要,我可以编辑答案,并添加该部分。
【解决方案2】:

这段代码对我有用,但正如您所见,我必须立即保存文档并使用 ShellExecute 重新打开它。如果没有,我会收到我之前提到的“RPC 服务器不可用”错误。

procedure TfrmJobsearchAdverts.FileCreate;
var
  TempName: OleVariant;
  FileDoc: OleVariant;
  FileFormat: OleVariant;
  Doc : WordDocument;
  WordTemplate: string;
  WordFile: string;
  BookName: OleVariant;
begin
  SaveRecord;
  WordFile := Advert.CreateDocname(qryAdverts.FieldByName('fldadvert_date').AsDateTime);
  WordTemplate := JobsearchTemplate(Self);
  if (WordFile <> '') and (WordTemplate <> '') then
    begin
      Advert.SaveDocname(qryAdverts.FieldByName('fldadvert_guid').AsString, WordFile);
      if not Assigned(fWordApp) then
        InitializeWord;
      TempName := WordTemplate;
      FileDoc := WordFile;
      Doc := FWordApp.Documents.Add(TempName, EmptyParam, EmptyParam, EmptyParam);
      BookName := 'fldCompany';
      if Doc.Bookmarks.Exists(BookName) then
        Doc.Bookmarks.Item(BookName).Range.Text := Company.Name;
      BookName := 'fldAddress1';
      if Doc.Bookmarks.Exists(BookName) then
        Doc.Bookmarks.Item(BookName).Range.Text := Company.Address1;
      BookName := 'fldAddress2';
      if Doc.Bookmarks.Exists(BookName) then
        Doc.Bookmarks.Item(BookName).Range.Text := Company.Address2;
      BookName := 'fldZip';
      if Doc.Bookmarks.Exists(BookName) then
        Doc.Bookmarks.Item(BookName).Range.Text := Company.Zip;
      BookName := 'fldCity';
      if Doc.Bookmarks.Exists(BookName) then
        Doc.Bookmarks.Item(BookName).Range.Text := Company.City;
      FileFormat := wdFormatDocument;
      Doc.SaveAs(FileDoc, EmptyParam, EmptyParam, EmptyParam,
                 EmptyParam, EmptyParam, EmptyParam, EmptyParam,
                 EmptyParam, EmptyParam, EmptyParam, EmptyParam,
                 EmptyParam, EmptyParam, EmptyParam, EmptyParam);
      FinalizeWord;
      Files.ExecuteAndWait(WordFile);
    end;
end;

【讨论】:

  • 如果您需要创建和保存多个文档,您不必为每个文档调用 InitializeWord 和 FinializeWord;只需初始化一次Word,不再需要Word应用程序时完成一次。完成文档后,通过调用其 Close 方法将其关闭。
猜你喜欢
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-28
  • 1970-01-01
  • 2017-12-06
  • 2012-07-31
  • 1970-01-01
相关资源
最近更新 更多