Exporting custom component
Suazael
Poland
Hello.
I have written component based on TfrxCustomMemoView with some additional drawing on it.
Is it possible to export report with this component to PDF?
Currently all components are "printed" on PDF sheet without my drawing.
procedure TMyFRCustomCell.Draw works fine with previewing and printing, but the additional text is not exported using TfrxPDFExport (or any other TfrxCustomExportFilter).
Does any one know how to make it work?
I guess I could override AddObject method in TfrxPDFExport, but is there a easier way? Or maybe someone already has solution for this?
Regards
Suazael
I have written component based on TfrxCustomMemoView with some additional drawing on it.
Is it possible to export report with this component to PDF?
Currently all components are "printed" on PDF sheet without my drawing.
type
TMyFRCustomCell = class(TfrxCustomMemoView)
protected
FCellText: string;
public
procedure Draw(Canvas: TCanvas; ScaleX, ScaleY, OffsetX, OffsetY: Extended); override;
// There is some additional text drawn within this method
end;
procedure TMyFRCustomCell.Draw(Canvas: TCanvas; ScaleX, ScaleY, OffsetX, OffsetY: Extended);
var tmpRect: TRect;
begin
tmpRect := Rect(FX + FFrameWidth, FY + FFrameWidth, FX1 - FFrameWidth, FY1 - FFrameWidth);
DrawText(Canvas.Handle, FCellText, -1, tmpRect, DT_SINGLELINE);
// There are some more actions taken here. This is just to show what my goal is.
end;
procedure TMyFRCustomCell.Draw works fine with previewing and printing, but the additional text is not exported using TfrxPDFExport (or any other TfrxCustomExportFilter).
Does any one know how to make it work?
I guess I could override AddObject method in TfrxPDFExport, but is there a easier way? Or maybe someone already has solution for this?
Regards
Suazael
Comments
Mick
The first one is easy to implement, but certainly not perfect. Every TfrxView component has the Tag property. The PDF export can process components differently regarding a value of this property. I can introduce the PictureTag property to the PDF export and when a TfrxView with Tag=PictureTag, it will be exported as a picture (JPEG picture, to say more precisely).
The second one is a bit more complex, but exhaustively solves your issue. The exporting process can be implemented as a chain of handler-routines, each of these routines exporting a specific kind of a component. The export will obtain a new method AttachHandler that will allow a developer to extend the export functionality without modifying the export's code. This may look like this:
function ExportMyMemoView(Obj: TfrxView): Boolean; // returns True if the passed component has been exported
begin
if (Obj is TMyMemoView) and ... then ...
end;
PDFExport.AttachHandler(ExportMyMemoView);
Report.Export(PDFExport);
After that every TfrxView component will be going through ExportMyMemoView that can either export it or just return "False", thus saying the export to pass the TfrxView further along the handlers chain.
If you're interested in this approach, I can give you a kind of HTML export (it'll appear in FR5) that implements the last approach and if you're familiar with HTML, you can try to write your handler and provide feedback about usability of the approach.
First approach sounds easy, but I don't know (for now) how to pass a single TfrxView (or it's descendant) as JPEG to TfrxPDFExport without "rebuilding" TfrxPDFExport on my own.
The second approach looks promising... I would definitely like to see some code for that. HTML export would be a good example and some "training" for me, how the export works (or will work in ver. 5).
So, if I may ask, please provide some HTML export.
Thank you
Best regards
Suazael
For the second approach see your private messages: I've sent you a link to the export. Here're some explanations regarding exporting objects. Find in the main module the function that exports rectangles:
This routine is intended to catch all TfrxShapeViews that are either rectangles or rounded rectangles. If the routine is called with a non-rectangle component it just returns False, thus saying to try to find a more applicable handler for the component. Otherwise it creates the DIV tag with CreateDiv and checks whether it's needed and possible to round corners. If a user set HTML5 to True and the TfrxShapeView is skRoundRectangle then it creates a CSS style, sets it CSS3-style named "border-radius" and adds the CSS style to the created DIV tag via the DIV's AddCSSClass method (it adds a new value to its "class" attribute). Note a call to LockStyle: this method adds a CSS style to an internal CSS stylesheet, assigns a name to it (like ".s123") and returns the classname (like "s123").
Now look at the constructor:
Here you can see a chain of exporting handlers. When a component is going to be exported, it's firstly sent to ExportTaggedView. If ExportTaggedView refuses to export the component, it's sent to ExportAllPictures and so on. At last, if all handlers refuse to export, ExportAsPicture is called and this last handler exports everything as a picture (it may be JPEG, PNG or some other format, depending on settings of the export). Thus you are able to add your own handler: just create an instance of the export in the usual way and then call to AttachHandler: your handler will be placed at the beginning of the chain and will be the first who accepts component from reports (in other words it will have the highest priority).
OK, maybe there is some misunderstanding... I can't find anything like PictureTag property (or anything which has similar functionality). I using FR version 4.10.18.
I think this will be introduced in next version?
As for the second approach: you are talking about the next version (5?). So for now I'm stuck.
Any way, thanks for the reply.
I will find some way to do what I want, and will wait for the next version of FasrReport. Then exporting will be easier (as seen in your posts).
Best regards
Suazael
Pieces of code that you see in my previous post are extracted from the HTML export that I sent you: see you private messages. You can find this code in that export.