Tuesday, September 28, 2010

How to save a report as PDF to a stream with FastReport

Recently I needed to save a report to a stream as PDF, I'm using FastReport for my reports.
I've searched a lot for a way to do this, but unfortunately I only found comments like „you can't export a report to a stream in PDF format with FastReport¯ and similar comments... so I started browsing the source code of the PDF exporter and 2 minutes later I saw that the exporter checks if property „Stream¯ is assigned, otherwise it will create a TFileStream instance using the report's „FileName¯ property — therefore assigning a TStream descendant to PDFExporter.Stream will make the exporter write the PDF data to THAT stream in stead of the file, without further chit-chat, let's see some code:
I took „PrintStringList¯ example from the Demo folder and modified it to show you how it's done, I've added a new button on the form and a save dialog, in the OnClick event of the button I've added the following code:

procedure TForm1.Button2Click(Sender: TObject);
var
// we use a file stream for example, but you can replace this
// with a memory stream or any type of stream which is a
// descendant of abstract class TStream
LFileStream: TFileStream;
begin
// allow the user to choose a file name
if SaveDialog1.Execute then begin
// create the file stream object
LFileStream := TFileStream.Create(SaveDialog1.FileName, fmCreate or fmShareDenyNone);
try
// set the range properties
StringDS.RangeEnd := reCount;
StringDS.RangeEndCount := sl.Count;
// THIS IS THE MAGIC
// assign the stream for the TfrxPDFExport component
frxPDFExport1.Stream := LFileStream;
// prepare the report
frxReport1.PrepareReport(True);
// export calls the PDFExport component in this case
frxReport1.Export(frxPDFExport1);
finally
// free the file stream object
FreeAndNil(LFileStream);
// NIL reference to the stream
frxPDFExport1.Stream := NIL;
end; // tryf
end; // if SaveDialog1.Execute then begin
end;