Is there a way I can send data to my PDF file, (fill in the fields/blanks), either manually or by a third party component, the PDF files have certain fields that can be modified by user, entering numbers.. checkboxes etc etc
how can I achieve this goal, an if it will require some third party component, which is the best, and what are the prices?
our Development IDE is delphi 2010 / Delphi 2011 XE
thanks :)
I guess you want your application to create some PDF content from User Interface field.
You can do this easily from code, using a report generator from code, then a PDF engine.
We propose an Open Source solution just for doing this, from Delphi 6 up to XE.
Here is a code extract from one demo, which create a reports, using some User Interface fields as source (e.g. edt1.Text or mmo1.Text):
procedure TForm1.btn1Click(Sender: TObject);
(...)
with TGDIPages.Create(self) do
try
// the name of the report is taken from main Window's caption
Caption := self.Caption;
// now we add some content to the report
BeginDoc;
(...)
// main content (automaticaly split on next pages)
NewHalfLine;
TextAlign := taJustified;
s := 'This is some big text which must be justified on multiple lines. ';
DrawText(s+s+s+s);
NewLine;
TextAlign := taLeft;
DrawTitle(edt1.Text,true);
for i := 1 to 10 do
DrawText('This is some text '+IntToStr(i));
NewLine;
DrawBMP(Bmp,maxInt,50,'Some bitmap in the report');
AddBookMark('bookmarkname');
WordWrapLeftCols := true;
AddColumns([10,20,50]);
AddColumnHeaders(['#','Two','Three'],true,true);
for i := 1 to 100 do
DrawTextAcrossCols([IntToStr(i),'Column '+IntToStr(i),'Some text here. '+s]);
NewLine;
DrawBMP(Bmp,maxInt,50,'Some bitmap in the report (twice)');
DrawTitle('This is your text',false,0,'','bookmarkname');
DrawText(mmo1.Text);
EndDoc;
// set optional PDF export options
// ExportPDFForceJPEGCompression := 80;
// ExportPDFEmbeddedTTF := true;
// ExportPDFUseUniscribe := true;
// ExportPDFA1 := true;
// show a preview form, and allow basic actions via the right click menu
// ShowPreviewForm;
// export as PDF
ExportPDF('test.pdf',false);
finally
Free;
end;
There are other solutions around, but this one is Open Source, and you can even draw whatever you want to the report (using a "standard" TCanvas property - you can even directly any graphical component using the PaintTo method), not only dedicated report generated methods like DrawTitle() or DrawText().
EDIT:
If your question was about creating PDF files with forms, this library won't work.
You should use some closed-source libraries like VeryPdf or QuickPdf. Google is your friend.
Related
I changed for Delphi 10.3 and its default TOpenDialog contains a preview pane. I made some searches and found the IFileDialogCustomize interface provided by Microsoft to customize standard WinAPI dialogs. I know I have to use the OnSelectionChange event handler to modify the picture of the pane. The big question for me is : how can I access the preview pane image by IFileDialogCustomize? What is the ItemID for this? I couldn't find any answer to this question on the net. Somebody know the answer? Then please share with me and the community! :)
I replaced some code fragments by ... for the sake of brevity, because these are trivial or app dependent sections.
procedure TMainWindow.OnSelectionChange( Sender : TObject );
var
dc : HDC;
aBMP : TBitmap;
function isSelectedFilePreviewAble : boolean;
begin
result := ...;
end;
functon getPreviewPictureDC : HDC;
var
iCustomize : IFileDialogCustomize;
h : THandle;
begin
if OpenDialog1.QueryInterface( IFileDialogCustomize, iCustomize ) = S_OK then
begin
h := iCustomize.??? this is the missing code fragment
result := GetDC( h );
end else
result := 0;
end;
procedure generatePreviewPicture;
begin
...
end;
begin
dc := getPreviewPictureDC;
if ( dc <> 0 ) then
begin
aBMP := TBitmap.Create;
try
if ( isSelectedFilePreviewAble ) then
generatePreviewPicture;
StretchBlt( aBMP.Handle, ...);
finally
aBMP.Free;
ReleaseDC( dc );
end;
end;
end;
I made some searches and found the IFileDialogCustomize interface provided by Microsoft to customize standard WinAPI dialogs.
First, IFileDialogCustomize does not "customize standard WinAPI dialogs". It customizes only IFileOpenDialog and IFileSaveDialog dialogs, no others.
Second, TOpenDialog primarily uses the legacy Win32 API GetOpenFileName() function. On Windows Vista+, GetOpenFileName() uses IFileOpenDialog internally with basic options enabled, so that legacy apps can still have a modern look.
Although, under the following conditions, TOpenDialog will instead use IFileOpenDialog directly rather than using GetOpenFileName():
Win32MajorVersion is >= 6 (Vista+)
UseLatestCommonDialogs is True
StyleServices.Enabled is True
TOpenDialog.Template is nil
TOpenDialog.OnIncludeItem, TOpenDialog.OnClose, and TOpenDialog.OnShow are unassigned.
But even so, TOpenDialog still does not give you access to its internal IFileOpenDialog interface, when it is used.
If you really want to access the dialog's IFileOpenDialog and thus its IFileDialogCustomize, you need to use TFileOpenDialog instead of TOpenDialog (just know that dialog won't work on XP and earlier systems, if you still need to support them).
The big question for me is : how can I access the preview pane image by IFileDialogCustomize?
You don't. The preview pane is not a dialog customization, so it can't be accessed via IFileDialogCustomize. Even if you could get a control ID for the preview pane (which you can't), there is no function of IFileDialogCustomize that would allow you to access the preview pane's HWND or HDC, or otherwise alter the content of the preview pane in any way. The preview pane is an integral and private component of IFileDialog for any file type that supports previews. It is not something that you can access and draw on directly. IFileOpenDialog itself will update the preview pane as needed when the user selects a file that has (or lacks) a preview to display.
My boss want to show previews for our own file formats.
The correct way to handle that on Vista+ is to create a Preview Handler for your custom file types. Then, any Shell component that wants to display previews of your files, including IFileOpenDialog, can use your handler.
I study preparing a dictionary programme with delphi. So far I have solved my problems about Word documents but I've got some problem about PDF documents.
I imported and installed the AcroPdf component with Delphi 7 and I want to get the word (or text) which was selected by dblclicking by user from pdf document which was viewed by the ACROPDF component in Delphi. If I can get it I'll send it the dictionary database directly.
If you help me I'll be glad. Thank you...
Remzi MAKAK
The following shows one way to get the selected text from a Pdf document which is
open in Adobe Acrobat Professional (v.8, English version).
Update The original version of this answer neglected to check the Boolean result of calling MenuItemExecute and specified the wrong argument to it. Both these points are fixed in the updated version of this answer. It turned out that the reason the call to MenuItemExecute was failing was that it is essential to call BringToFront on the Acrobat document before trying to copy the text selected in to to the clipboard.
Create a new Delphi VCL project.
In D7's IDE go to Projects | Import Type Library, and in the Import Type Library pop-up, scroll down until you see something like "Acrobat (Version 1.0) in the list of files, and
"TAcroApp, TAcroAVDoc..." in the Class names box. That is the one you need to import. Click the Create unit button/
In the project's main form file
a. Make sure it USES the Acrobat_Tlb.Pas unit from step 2. You may need to add the path to wherever you saved Acrobat_Tlb.Pas to the SearchPath of your project.
b. Drop a TButton on the form, name it btnGetSel. Drop a TEdit on the form and name it edSelection
Edit the source code of your main form unit as shown below.
Set a debugger breakpoint on Acrobat.MenuItemExecute('File->Copy'); Do not set a breakpoint within the GetSelection procedure as this is likely to defeat the call to BringToFront in it.
Close any running instance of Adobe Acrobat. Check in Task Manager that there are no hidden instances of it running. The reason for these step is to make sure that when you run your app, it "talks" to the instance of Acrobat that it starts, not another one.
Compile and run your app. Once the app and Acrobat are open, switch to Acrobat, select some text, switch back to your app and click the btnGetSel button.
Code:
uses ... Acrobat_Tlb, ClipBrd;
TDefaultForm = class(TForm)
[...]
private
FFileName: String;
procedure GetSelection;
public
Acrobat : CAcroApp;
PDDoc : CAcroPDDoc;
AVDoc : CAcroAVDoc;
end;
[...]
procedure TDefaultForm.FormCreate(Sender: TObject);
begin
// Adjust the following path to suit your system. My application is
// in a folder on drive D:
FFileName := ExtractfilePath(Application.ExeName) + 'Printed.Pdf';
Acrobat := CoAcroApp.Create;
Acrobat.Show;
AVDoc := CoAcroAVDoc.Create;
AVDoc.Open(FileName, FileName); // := Acrobat.GetAVDoc(0) as CAcroAVDoc; //
PDDoc := AVDoc.GetPDDoc as CAcroPDDoc;
end;
procedure TDefaultForm.btnGetSelClick(Sender: TObject);
begin
GetSelection;
end;
procedure TDefaultForm.GetSelection;
begin
// call this once some text is selected in Acrobat
edSelection.Text := '';
if AVDoc.BringToFront then // NB: This call to BringToFront is essential for the call to MenuItemExecute('Copy') to succeed
Caption := 'BringToFront ok'
else
Caption := 'BringToFront failed';
if Acrobat.MenuItemExecute('Copy') then
Caption := 'Copy ok'
else
Caption := 'BringToFront failed';
Sleep(100); // Normally I would avoid ever calling Sleep in a Delphi
// App's main thread. In this case, it is to allow Acrobat time to transfer the selected
// text to the clipboard before we attempt to read it.
try
edSelection.Text := Clipboard.AsText;
except
end;
end;
I've constructed a new component based on an Intraweb Button(Intraweb XIV)
and installed it in a new package, regulary installed on the ide.
The component works perfectly, the only trouble is that at design time I cannot see the component name, since the component is rendered as a little gray rectangle with a Iw logo, without any name or caption.
So that if I place several buttons on a form I cannot distinguish among them.
Any suggestion ?
Some more information :
Intraweb is a framework to implement web applications.
You place components on a special "fake" form, that exists only at design time, but that does not exists at run time.
At run time the infrastructure asks every component to render itself producing the final html code.
To this purpose every component has an overridable RenderHtml procedure that must return the html code.
What you see at design time is (probably) produced by another procedure
(the doc is rather lacking about it) that I'd like to override, but that I don't know about.
As I said, if I place on the form an original tIWButton, at design time I see a classical 3d gray button with the button caption on it.
If instead I place a NewButton I see a different darker gray flat button
with a little Iw logo on it.
This is the code of my component (something omitted).
I've created the component just to add an Image field and to render a different html code during run time, that I can customize via css.
This should have no impact on the design time appearance of the component.
Practicaly, all I would need to override should be the renderhtml function:
TNewButton = class(TIWButton)
protected
fImage : string;
published
property Image: string read fImage write fImage;
public
function RenderHTML(AContext: TIWBaseHTMLComponentContext): TIWHTMLTag; override;
end;
function tNewButton.RenderHTML(AContext: TIWBaseHTMLComponentContext): TIWHTMLTag;
var Elem : tIwTextElement;
txt : string;
disab : string;
begin
if enabled then disab := '' else disab := ' disabled="disabled" ';
txt := '<button class="newbutton" '+disab+'>';
if fimage <> '' then
txt := txt + '<img src="'+ fimage +'"/>';
txt := txt + '<span class="newbutton-text">' + Caption + '</span>';
txt := txt + '</button>';
Elem := tIwTextElement.Create(nil);
elem.text := txt;
Result := TIWHTMLTag.CreateTag('DIV');
Result.Contents.Add (Elem);
end;
Although you say your component is based on a "Button", this sounds more like the behaviour of a non-visual component similar to (e.g.) the TOpenDialog.
If that is the case then the display of the component name is subject to an IDE configuration setting. In the Tools > Options dialog, check the Form Designer settings. Specifically the "Show component captions" checkbox.
If this is OFF then non-visual components are represented only by the component palette icon.
With this option ON then the component Name is displayed underneath the component.
NOTE: Even with this option off you can locate any and all components on a form using the Structure View of the form at design-time where the component names are displayed in a hierarchy formed by the parent/child relationships of the controls (all non-visual components are listed as "root" components since they all have the form as their parent).
I am developing an application in Firemonkey (Delphi XE5) where I am using Fast report 4 for printing data. I am using TFrxUserDataSet to keep data and to print this, I am using MasterData band in fast report.
Now, I also need to print TBitamp with each row, so here the bitmap for each record will be different.
Does any body has any idea how can I do this?
Нou can load an external image file into a picture control in your report. I'm doing this with a script that is part of the report itself using the OnBeforePrint event as follows:
PROCEDURE Data2OnBeforePrint(Sender: TfrxComponent);
VAR
lFN : STRING;
lFP : STRING;
BEGIN
// Use the filename as found in the Media dataset fields
lFP := Trim(< Media."ImagePath">); // Images folder below Image Root Path
lFN := Trim(< Media."FileName1">); // Actual Image File Name
WITH Picture2 DO BEGIN
// NB: There is no checking in this example, it may be useful to do a
// couple of checks before trying to load the image, especially if
// the data is user entered
LoadFromFile(ImageRootPath + IncludeTrailingSlash(lFP) + lFN);
// Do whatever manipulations you want to with the loaded image...
AutoSize := False;
Width := 1620;
Height := 1080;
Top := 0;
Left := (1920 - Width) / 2;
HightQuality := True; // Note the typo in the property name... HighQuality?
KeepAspectRatio := True;
Transparent := True;
Stretched := NOT Picture3.AutoSize;
END;
END;
Note that I have added a few user functions like ImageRootPath IncludeTrailingSlash() to make the script easier. You could do similar to check for a valid file prior to attempting to load to avoid exceptions.
My devt environment is Delphi XE5 with FastReport FMX and it works just fine. I am in the midst of moving to XE6 and FR FMX 2, but am pretty sure this will work fine.
Sorry, background's a little convoluted on this one... I am in the process of converting a D5 project to DXE... It has a listbox with several thousand items. A full progressive text search is done on these items with each keystroke in the searchbox. In D5 (pre-virtual lists), I had to make my own virtual listbox using the LMD listbox (as there were several columns with headers in the listbox), a separate scrollbar and an Array of records. The Listbox would then be populated as the user navigated through the search results or by modifying the search. This performed very well but since now virtual listboxes are native to Delphi I was going to convert my custom listbox to the native one but I cannot find a listbox component with headers that is virtual-capable. Help?
Is there a component available that has virtual lists and headers/columns?
I forgot to mention: I am aware of Soft Gems VirtualTreeView components - these are excellent and is probably what I'll be using but... Is there a way in DXE to accomplish this without 3rd party utilities? I'm concerned that I'm missing something obvious in DXE as I've only been using it for about a month.
TListView is a thin wrapper around the Windows list view common control. Run it in virtual mode with report view style to achieve what I believe you are asking for.
In order to set up a virtual list view you need to set OwnerData to True and supply an OnData event handler.
procedure TVirtualListViewForm.FormCreate(Sender: TObject);
begin
ListView1.ViewStyle := vsReport;
ListView1.Columns.Add.Caption := 'Column1';
ListView1.Columns.Add.Caption := 'Column2';
ListView1.OwnerData := True;
ListView1.OnData := ListViewData;
ListView1.Items.Count := 42;
end;
procedure TVirtualListViewForm.ListViewData(Sender: TObject; Item: TListItem);
begin
Item.Caption := Format('Column 0, index %d', [Item.Index]);
Item.SubItems.Add(Format('Column 1, index %d', [Item.Index]));
end;
For your needs an OnDataFind may be needed to implement the progressive text search.
You can use my component TDzListHeader, available at GitHub: https://github.com/digao-dalpiaz/DzListHeader
This component allows you to create columns in a TCollection and you should drop a TListBox inside the TListHeader, and link them.
DzListHeader example
All usage and detailed documentation are available at github project.