Viewing & Printing an embedded PDF File
Hi,
I have a request from a client who would like to be able to print a
pre-compiled PDF file from within their application. (Not to save to a
PDF, but to bring up a report that shows the content of an existing
PDF), with the option to print.
They don't want to use external viewers such as Adobe reader - they want
this all done from within my application.
I was wondering if there is any way to achieve this with reportbuilder.
Is it possible to embed a PDF file within a report?
Thanks & Regards
Adam.
I have a request from a client who would like to be able to print a
pre-compiled PDF file from within their application. (Not to save to a
PDF, but to bring up a report that shows the content of an existing
PDF), with the option to print.
They don't want to use external viewers such as Adobe reader - they want
this all done from within my application.
I was wondering if there is any way to achieve this with reportbuilder.
Is it possible to embed a PDF file within a report?
Thanks & Regards
Adam.
This discussion has been closed.
Comments
From the description, I would try embedding a PDF viewer in your
application. One option is to use ActiveX/COm interface to Adobe Acrobat.
This is installed with Acrobat and you can easily import it into Delphi.
Couple of links to examples..
http://delphi.about.com/cs/howto/ht/htpdf.htm
http://edn.embarcadero.com/article/22101
Best regards,
-
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
I've been working with WPCubed's WPViewPDF lib:
http://www.wpcubed.com/pdf/products/pdfviewer/
I've managed to incoporate loading and printing of PDF files as a
sub-report.
When a PDF document is required, it is loaded into WPViewPDF object.
The subreport has a single ppGraphic (full page size) with a
jitPipeline feeding it, and the pipeline recordCount is set to the PDF
pagecount.
As each page/"record" of the subreport is printed, that corresponding
PDF page is converted to an EMF file (as memory stream) and and is
loaded into ppGraphic.
The way I'm doing it, the 'preview' is of medium quality, but the print
is very good quality. I haven't had time to investigate how to improve
the preview quality (note that WPViewPDF does very nice rendering
normally - my problem is that the way I'm loading/displaying, the
rendering is done as though the document has screen resolution - not
original document resolution).
I've promised Nico a sample program - I got a bit busy, but will try
and send it to him this weekend.
Cheers,
EdB
Thanks for your reply. Unfortunately I was hoping to embed the PDF file
into a report for viewing with Reportbuilder as there are other pages
that reportbuilder will also print to view this.
Ed has an idea on how to do this so I'll check out his approach.
Thanks & Regards
Adam.
Thanks very much for that - exactly what I'm trying to achieve.
So basically we need to utilise graphics in this instance. Good idea
with EMF - I was thinking something similar but using a different
format. EMF makes much more sense when it comes to quality.
Thanks again for your help.
Best Regards
Adam.
If you're going to work with WPCubed's stuff, this should save you some
time...
This is part of my demo (set up to test for a particular project). t's
basically a manufacturing work order, with a lot of operations - the
PDFs are sign-off sheets or assembly instructions - and need to be
printed *after* the main work order. There could be 0-n PDF docs, and
each PDF can have 1-n pages.
In the test project, I read a number of detail records and build a list
of PDFs that need to be printed AFTER the main report. "Build a list"
means populate a local ClientDataSet with a string field called PDFName.
A ppDBPipeline is configured with a single field, cleverly called
"jppFldName",
The subreport lives in the group footer band, is assigned to the
ppDBPipeLine, and has a single, page-wide and page-high ppDBGraphic
with DataField = jppFldName,
In Form Create:
DocList := TStringList.Create;
FPicture := TPicture.Create;
FCurDocName :='';
// get PDF viewer ready for use in conversion
FWPViewPDF := TWPViewPDF.Create(Self);
FWPViewPDF.Name := 'WPViewPDF1';
FWPViewPDF.Parent := Self;
FWPViewPDF.Visible := False;
FWPViewPDF.ViewControls := [];
FWPViewPDF.ViewOptions := [];
FWPViewPDF.SecurityOptions := [wpDisableSave, wpDisableCopy,
wpDisableForms, wpDisableEdit, wpDisablePDFSecurityOverride];
FWPViewPDF.AllowMovePages := False;
FWPViewPDF.ViewerStart('', your_lic_name, your_lic_key,
your_lic_code);
FWPViewPDF.Command(140{COMPDF_NoViewer}, 1);
FWPViewPDF.Command(132{COMPDF_DisableAntiAlias}, 0);
// testing for view quality
FWPViewPDF.Command(141, 1); // use gdi
FWPViewPDF.Command(145, 0); // use gdi
In GroupHeaderBand BeforePrint:
// < process detail records for current work order and >
// < build list of PDF files to print (the "docList") >
// < set GroupFooterBand visibility >
// if this is first page of this group break
if (ppReport1.Groups[0].FirstPageNo = ppReport1.AbsolutePageNo) then
begin
wono:=ppDBPipeline1['work_order_no'];
DocList.Clear;
cds2.SetRange([wono],[wono]);
cds2.First;
while not cds2.Eof do begin
DocList.Add(cds2CalcWOBDwgFn.AsString);
cds2.Next;
end;
cds2.CancelRange;
end;
ppGroupFooterBand1.Visible := (docList.Count>0);
In GroupFooter BeforePrint:
// DocList holds a list of PDF filenames
if DocList.Count>0 then begin
FCurDocName:= DocList[0];
// delete the first (current) doc
FDocList.Delete(0);
FWPViewPDF.LoadFromFile(FCurDocName);
ppJITPipeline1.RecordCount:= FWPViewPDF.PageCount;procedure
procedure TForm1.ppGroupFooterBand1AfterPrint(Sender: TObject);
begin
FWPViewPDF.Clear;
end;
procedure TForm1.ppDBImage1GetPicture(Sender: TObject; aPicture:
TPicture);
var
lPicture: TPicture;
begin
// call DataPipeline.GetFieldAsPicture method
lPicture := ppJITPipeline1.GetFieldAsPicture('jppFldFName');
if lPicture <> nil then
aPicture.Assign(lPicture)
else
aPicture.Graphic:=nil;
end;
function TForm1.ppJITPipeline1GetFieldAsPicture( aFieldName: String):
TPicture;
var
fName: string;
pgNo: Integer;
mf : TMetafile;
begin
// note that because the WPViewPDF object loads the PDF file in the
// GroupFooter, we ignore aFieldName - and just use the RecordIndex
// to get the approproiate page
result:=nil;
pgNo := ppJITPipeline1.RecordIndex;
mf:=FWPViewPDF.GetMetafilePrn(pgNo);
FPicture.Metafile.Assign(mf);
Result := FPicture;
mf.Free;
end;
NOTE: the way I've defined this, if a user is looking at a rendered pdf
page and sends to printer, they will get a blank page (because the
FViewPDF has been cleared by this time). I did it this way to avoid
loading the entire PDF for every page (load it ONCE in footer before
print).
Hope this helps - have fun!
Cheers,
EdB
You've been very helpful.
Cheers
Adam.