Does anyone know whether generated reports can be combined ? Is there a way of concatenating archive files into 1 archive so that the combined archive can be printed as one printjob or seen within a single preview ?
Annick Van Hoof wrote: Yes, it's possible and it is quite simple. I post here a sample code. Currently I'm using RB Enterprise 5.51, I don't know whether it works with newer versions too. Use it like this:
BigArchive := TssArchiveStreamer.Create('Archive.raf'); for each TppReport do begin Print it to TempFile BigArchive.Add(TempFile); DeleteFile(TempFile); end; BigArchive.Close; // Important!!
// now let's see the result ArchiveReader.ArchiveFileName := BigArchive.FileName; ArchiveReader.Print;
if (FPageStream = nil) or (FPageEntryStream = nil) then CreateStreams;
Source := TFileStream.Create(aFileName, fmShareDenyWrite); try if Source.Read(lHeaderSize, SizeOf(Longint)) = SizeOf(Longint) then begin while Source.Position < lHeaderSize do begin Source.Read(lPageEntryRec, SizeOf(TppPageEntryRec)); inc(FPageCount); lPageEntryRec.AbsolutePageNo := FPageCount; Inc(lPageEntryRec.Position, FPageStream.Position); FPageEntryStream.Write(lPageEntryRec, SizeOf(TppPageEntryRec)); end; FPageStream.CopyFrom(Source, Source.Size - lHeaderSize); end; finally Source.Free; end;
end;
procedure TssArchiveStreamer.Close; var llPageDirectorySize: Longint; begin if FPageEntryStream = nil then Exit; llPageDirectorySize := FPageEntryStream.Position; FPageEntryStream.CopyFrom(FPageStream, 0);
{write the page directory size} FPageEntryStream.Position := 0; FPageEntryStream.Write(llPageDirectorySize, SizeOf(llPageDirectorySize)); {delete the temp file} DeleteFile(FTempFileName); end;
Comments
Yes, it's possible and it is quite simple. I post here a sample code.
Currently I'm using RB Enterprise 5.51, I don't know whether it works
with newer versions too.
Use it like this:
BigArchive := TssArchiveStreamer.Create('Archive.raf');
for each TppReport do
begin
Print it to TempFile
BigArchive.Add(TempFile);
DeleteFile(TempFile);
end;
BigArchive.Close; // Important!!
// now let's see the result
ArchiveReader.ArchiveFileName := BigArchive.FileName;
ArchiveReader.Print;
DeleteFile(BigArchive.FileName);
BigArchive.Free;
unit ssArStrm;
interface
uses classes;
type
TssArchiveStreamer = class
private
FFileName: string;
FPageCount: Longint;
protected
FPageStream : TFileStream;
FPageEntryStream : TFileStream;
FTempFileName: string;
procedure CreateStreams;
public
constructor Create(FileName: string);
destructor Destroy; override;
procedure Add(const aFileName : string);
procedure Close;
property FileName : string read FFileName;
property PageCount : integer read FPageCount;
end;
implementation
uses SysUtils, ppUtils, ppTypes;
constructor TssArchiveStreamer.Create(FileName: string);
begin
inherited Create;
FFileName := FileName;
end;
procedure TssArchiveStreamer.CreateStreams;
begin
FTempFileName := ppGetTempFileName(ppGetTempPath, 'tmp');
FPageStream := TFileStream.Create(FTempFileName, fmCreate or
fmShareExclusive);
FPageEntryStream := TFileStream.Create(FFileName, fmCreate or
fmShareExclusive);
FPageEntryStream.Position := SizeOf(Longint);
end;
destructor TssArchiveStreamer.Destroy;
begin
FPageStream.Free;
FPageEntryStream.Free;
inherited Destroy;
end;
procedure TssArchiveStreamer.Add(const aFileName: string);
var
lPageEntryRec: TppPageEntryRec;
Source : TFileStream;
lHeaderSize : longint;
begin
if (FPageStream = nil) or (FPageEntryStream = nil) then
CreateStreams;
Source := TFileStream.Create(aFileName, fmShareDenyWrite);
try
if Source.Read(lHeaderSize, SizeOf(Longint)) = SizeOf(Longint) then
begin
while Source.Position < lHeaderSize do
begin
Source.Read(lPageEntryRec, SizeOf(TppPageEntryRec));
inc(FPageCount);
lPageEntryRec.AbsolutePageNo := FPageCount;
Inc(lPageEntryRec.Position, FPageStream.Position);
FPageEntryStream.Write(lPageEntryRec, SizeOf(TppPageEntryRec));
end;
FPageStream.CopyFrom(Source, Source.Size - lHeaderSize);
end;
finally
Source.Free;
end;
end;
procedure TssArchiveStreamer.Close;
var
llPageDirectorySize: Longint;
begin
if FPageEntryStream = nil then Exit;
llPageDirectorySize := FPageEntryStream.Position;
FPageEntryStream.CopyFrom(FPageStream, 0);
{write the page directory size}
FPageEntryStream.Position := 0;
FPageEntryStream.Write(llPageDirectorySize,
SizeOf(llPageDirectorySize));
{delete the temp file}
DeleteFile(FTempFileName);
end;
end.