Creating Word document from Delphi, saving as Doc and as PDF

21,589

First import "Microsoft Word 12 Objects" (MS Word 2007) type library into your project by using Components | Import Components menu item. Then you can use this sample code to load a MS Word file, and save it as PDF using the internal PDF converter. If you are using Microsoft Word 2010, load its type library instead of 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.

I just wrote the code and ran it once, it works, but I have not tested it thoroughly, so there might be some glitches.

Share:
21,589
OZ8HP
Author by

OZ8HP

Mainly VBA and Delphi

Updated on February 26, 2020

Comments

  • OZ8HP
    OZ8HP over 4 years

    I need to create a Word document from Delphi using a specific template, save the document as a Word document with a given name and then save the same document with the same name but as a PDF file. (In Word 2007 it can be done using the SaveAsPdf... plugin. In Word 2010 it is a built in feature)

    How can this be done using Delphi XE?

  • Marjan Venema
    Marjan Venema over 12 years
    OP is asking explicitely to create a new word document using a specific template...?
  • vcldeveloper
    vcldeveloper over 12 years
    @Marjan Venema, what I got from the title and the description was that he/she has a problem with saving the document in a specific format, not in creating a new document. I added LoadFile() to be able to test the code and make sure it actually converts a given MS Word document into PDF.
  • Marjan Venema
    Marjan Venema over 12 years
    @vcldeveloper I do agree that the savetopdf seems important, but I read the post as a general call for help on word automation; the "create" (in the title) doesn't read like "load" and OP's first sentence is also pretty explicit.
  • OZ8HP
    OZ8HP over 12 years
    I will give your code a try tomorrow -it's almost 2200 here :-) so it's time for some TV and a bed.
  • vcldeveloper
    vcldeveloper over 12 years
    @Marjan Venema, OP mentioned in the description that he could solve his problem in MS Word 2007, using SaveAsPlugin, so my conclusion was that his main problem was with saving the document as PDF. If he also has problem with creating a new document, it can be done easily by calling FWordApp.Documents.Add() method, and if necessary, I can edit the answer, and add that part too.
  • Marjan Venema
    Marjan Venema over 12 years
    @vcldeveloper No worries. We all read/interpret things differently. Which is good as it often means that at least one of us "reads the OP's mind" when questions are not all that well formulated. :-) (And OP can always comment, and ask for further help).
  • OZ8HP
    OZ8HP over 12 years
    @vcldeveloper Have you an edited version that creates a doc using a specific template? If so I would like to see it :-)
  • vcldeveloper
    vcldeveloper over 12 years
    @OZ8HP, no, I just wrote the code above off the cuff, after seeing your question. However to create a document using a specific template, you can use FWordApp.Documents.Add instead of FWordApp.Documents.Open method. The first parameter sent to Add method is the name of template you want to use, and for the rest of parameters you can use EmptyParam. Here is the MSDN explanation about Add method: msdn.microsoft.com/en-us/library/…
  • OZ8HP
    OZ8HP over 12 years
    I have now got a procedure for creating a document using a specific template working - or allmost working When the document is created and I try to create another doc, I get an 'RPC server not available' error To bypass this I have made it so I save the doc and reopen it just after that using ShellExecute - and then there is no problem. (I would like to add my code here, but haven't figured out how)
  • vcldeveloper
    vcldeveloper over 12 years
    @OZ8HP, if you want to add your code here to ask a solution for that RPC error, you can edit your question, and add the new code and a short description of your current problem there. If your code is working fine, and you want to share it with others as a solution, click on Add Answer button, and add your code as an answer. You can even select your own answer as the accepted one.
  • vcldeveloper
    vcldeveloper over 12 years
    If you need to create and save several documents, you don't have to call InitializeWord and FinializeWord for each of them; just Initialize Word once, and Finalize it once when you do not need the word application any more. When you are finished with a document, close it by calling its Close method.