经过一些测试,我发现 TOleContainer.LoadFromStream 方法始终有效。问题是这个方法需要一个 OLE 流,而不是一个包含 word 文档的流。我对 OLE 流的格式进行了逆向工程,并通过编写页眉、word 文档和页脚手动创建了一个。看起来,页脚由偶数 256 字节的 ASCII-0 组成。
以下是创建 OLE 流的代码:
function OLEStreamFromDoc(const inDocFileName : String) : TMemoryStream;
var
aFileStream : TMemoryStream;
aPadding : Array[1..256] of byte;
aHeader : Array[1..12] of byte;
aSize : int64;
i : integer;
begin
for i := low(aHeader) to High(aHeader) do
aHeader[i] := 0;
for i := low(aPadding) to High(aPadding) do
aPadding[i] := 0;
Result := TMemoryStream.Create;
aFileStream := TMemoryStream.Create;
try
aFileStream.LoadFromFile(inDocFileName);
aFileStream.Seek(0,0);
aSize := aFileStream.Size + SizeOf(aPadding);
aHeader[1] := Ord('B');
aHeader[2] := Ord('D');
aHeader[3] := Ord('O');
aHeader[4] := Ord('C');
aHeader[5] := 1;
aHeader[9] := aSize and 255;
aHeader[10] := (aSize shr 8) and 255;
aHeader[11] := (aSize shr 16) and 255;
aHeader[12] := (aSize shr 24) and 255;
Result.Write(aHeader, SizeOf(aHeader));
aFileStream.SaveToStream(Result);
Result.Write(aPadding, sizeof(aPadding));
Result.Seek(0,0);
finally
aFileStream.Free;
end;
end;