Header 通过 Delphi XE5 的 word 文件

Header of a word file via Delphi XE5

我想调整Delphi生成的word文件的header,第一行加粗,第二行不加粗。

但由于 header 的字符串是一个字符串,我似乎无法使第二行正常。

如何保证word文件header的第二行不是粗体?

procedure Print;
var v:olevariant;
    procedure HeaderandFooter;
    var adoc:olevariant;
    begin
    v.Selection.Font.Bold:=1;

    adoc:= v.Documents.Add(EmptyParam, EmptyParam);
    adoc.Sections.Item(1).Headers.Item(wdHeaderFooterPrimary).Range.Text :=
    'Line one of the header which is bold' +#13
    + 'Line two of the header which is normal';
    end

以下内容适用于我使用 D7 和 Word 2007,但应该适用于两者的更高版本。

我不确定你是如何得到你的代码的,但我创建了我的部分,它通过在 MS Word 中录制一个宏来插入和格式化 header,然后 "translating" 它到 Delphi,在途中编辑掉一些多余的 "fluff"。我的代码使用 "late binding"(即它通过变体访问 MS Word objects),但我认为使用 Word2000 单元中定义的接口 objects 可以直接 re-write 它(即早期绑定)。

uses ... ComObj, Word2000 ...;

procedure TForm1.MakeDocWithHeader;
var
  MSWord,
  Document : OleVariant;
  AFileName,
  DocText : String;
begin
  MSWord := CreateOleObject('Word.Application');
  MSWord.Visible := True;

  Document := MSWord.Documents.Add;
  //  First, insert some text into the new document's body
  DocText := 'Hello Word!';
  MSWord.Selection.TypeText(DocText);

  //  Next, make the Header window the active one
  if MSWord.ActiveWindow.View.SplitSpecial <> wdPaneNone then
      MSWord.ActiveWindow.Panes(2).Close;
  if (MSWord.ActiveWindow.ActivePane.View.Type = wdNormalView) or (MSWord.ActiveWindow.ActivePane.View.Type = wdOutlineView) then
      MSWord.ActiveWindow.ActivePane.View.Type := wdPrintView;
  MSWord.ActiveWindow.ActivePane.View.SeekView := wdSeekCurrentPageHeader;

  //  Now, add three lines of text to the header
  MSWord.Selection.TypeText( Text:='Header line 1');
  MSWord.Selection.TypeParagraph;
  MSWord.Selection.TypeText( Text:='Header line 2');
  MSWord.Selection.TypeParagraph;
  MSWord.Selection.TypeText( Text:='Header line 3');

  //  Next, make the first line bold
  MSWord.Selection.HomeKey( Unit:=wdStory);
  MSWord.Selection.EndKey( Unit:=wdLine, Extend:=wdExtend);
  MSWord.Selection.Font.Bold := True;
  MSWord.Selection.HomeKey (Unit:=wdLine);

  //  Finally, return the caret to the main body of the document
  MSWord.Selection.GoTo(What:=wdGoToPage, Which:=wdGoToNext, Count:=1);

  AFileName := 'd:\aaad7\officeauto\worddocwithheader.docx';
  Document.SaveAs(AFileName);
  ShowMessage('Paused');
  Document.Close;
end;

更新:我添加了 Delphi Cindy Meister 解决方案的实现。

procedure TForm1.MakeDocWithHeader2;
var
  MSWord,
  Document,
  rngDocument,
  rngHeade,
  Headers : OleVariant;
  DocText : String;
begin
  MSWord := CreateOleObject('Word.Application');
  MSWord.Visible := True;

  Document := MSWord.Documents.Add;
  DocText := 'Hello Word!'#13;

  // Following is a Delphi adaptation of the implementation in Cindy Meister's answer.
  rngDocument := Document.Content;
  rngDocument.Text := DocText;

  Headers := Document.Sections.Item(1).Headers;
  rngHeader := Headers.Item(wdHeaderFooterPrimary).Range;

  rngHeader.Text := 'Header Line 1'#13;
  rngHeader.Font.Bold := True;
  rngHeader.Collapse(wdCollapseEnd);
  rngHeader.Text := 'Header Line 2';
  rngHeader.Font.Bold := False;
end;

我不能给你 Delphi 代码,但我可以给你 VBA 代码,它采用与 Martyn 提议的方法略有不同的方法。

宏记录器的一个缺点是它模仿用户的操作,而不是直接使用对象模型。这通常较慢,会导致屏幕闪烁并且不太可靠,因为用户可以点击屏幕上的某处,从而改变选择。

使用 RANGE 对象更可靠,尤其是因为它避免了 SeekView,这肯定是错误的。这是一个您可以比较的示例;请注意,该方法比建议的答案更类似于原始方法:

Dim rngDoc as Word.Range
Dim rngHeader as Word.Range

Set rngDoc = Document.Content
Set rngHeader = Document.Sections(1).Headers(Word.WdHeaderIndex.wdHeaderFooterPrimary).Range
rngDoc.Text = DocText
rngHeader.Text = "Header Line 1" & Chr(13)
rngHeader.Font.Bold = -1
rngHeader.Collapse Word.WdCollapseDirection.wdCollapseEnd£
rngHeader.Text = "Header Line 2" & Chr(13) & "Header Line 3"
rngHeader.Font.Bold = 0

使用此方法的 "trick" 是在应用格式之后和继续新文本之前 "collapse" 其 end-point 的范围。