Customized Printing in Delphi
Delphi provides modern full text and graphics printing facility. We can print texts, images and shapes in different formats by using several Delphi classes and members. We can also access printers installed on system and can change their properties Print and printer setup dialog in Delphi. Delphi provides TPrintDialog and TPrinterSetupDialog components to confirm printing and to set printer properties. Delphi also provides Printer object which provides functions to access printers details and to print any text or image on canvas. In this blog I will show how to use TPrintDialog and TPrinterSetUpDialog. I will also explain with examples on how to print TRichedit text, how to print TListView data and how to print custom data on Printer.Canvas.
Using Print dialog and Printer Setup dialog
It is a good practice that we display the printer dialog so that user can control printing. We will show a print dialog that allows the user to select all pages, or a range of pages. We can also set printer properties using Printer setup dialog.
TPrinterSetupDialog
TPrinterSetupDialog is used to change printer and paper options.
object PrinterSetupDialog1: TPrinterSetupDialog
Left = 184
Top = 160
End
Execute the dialog.
procedure TForm1.btnPrinterSetupClick(Sender: TObject);
begin
if PrinterSetupDialog1.Execute then
begin
ShowMessage('Printer SetUp is done.');
end;
end;
TPrintDialog
TPrintdialog component is used to show a dialog for select printer and to change their options. It also allows users to cancel the print.
object PrintDialog1: TPrintDialog
Left = 184
Top = 80
End
Set printer options
//allowed pages//
printdialog1.MinPage := 1;
printdialog1.MaxPage := 10;
//page range to print//
printdialog1.FromPage := 5;
printdialog1.ToPage := 10;
//allow page range selection//
printdialog1.Options := [poPageNums];
Execute the dialog.
procedure TForm1.btnPrintClick(Sender: TObject);
begin
if PrintDialog1.Execute then
begin
ShowMessage('Print is done.');
end;
end;
How to print text or image ?
For normal text we can use TRichEdit control or we can use Printer.Canvas for custom printing. But for Image we can use Report builder or we can use Printer.Canvas.
So lets first see how to print texts using TRichedit control.
Print TRichedit Text
Printing texts using TRichEdit is very easy, we just need to call Richedit.Print method and what ever the texts in TRichedit will be printed.
First put a TRichedit control on a form and set some lines data. We can change the font of TRichedit control's text as needed. Then on button click just call RichEdit.Print method.
procedure TForm1.btnPrintClick(Sender: TObject);
begin
if PrintDialog1.Execute then
begin
RichEdit1.Print('Print Rich Edit Data');
ShowMessage('Print is done.');
end;
end;
I selected XPS Viewer for print.
Using of Printer object
Printer object provides canvas to draw texts or images. It also provides lots of procedures to print the drawn data in canvas. Writing directly to the printer's canvas provides more control than using someone else's components.
To use Printer object add Printers unit to your uses clause and use the Printer function to access the global object of TPrinter. Following are some important functions of TPrinter object.
• Printer.EndDoc stops the print job and sends it to the printer
• Printer.Title sets print job title
• Printer.Orientation sets printer page orientation
• Printer.Copies set number of copies be printed
• Printer.NewPage create and forces a new page
• Printer.Canvas is used to generate the output page
• Printer.Printers returns list of printers installed on system
• Printer.Abort aborts printing job
• Printer.Printing returns as printing going on or finished
• Printer.Aborted printing is aborted or not
So first lets see with a simple text print and then we will how to print images or shapes.
Print Text using Printer.Canvas
Here we will try to print a Memo control’s text. So I have put a TMemo control and a button control. On button click I am printing texts in memo with using Delphi Printer object.
procedure TForm1.btnPrintClick(Sender: TObject);
var
rectPage: TRect;
sText: string;
begin
if PrintDialog1.Execute then
begin
rectPage := Rect(0, 0, Printer.PageWidth, Printer.PageHeight);
with Printer do
begin
//start printing
BeginDoc;
sText := memo1.Text;
//setting font details//
Canvas.Font.Name := 'Verdana';
Canvas.Font.Size := 11;
Canvas.Font.Color := clRed;
//draws the text to print//
Canvas.TextRect(rectPage, sText, [tfWordBreak]);
//finish printing
EndDoc;
end;
ShowMessage('Print is done.');
end;
end;
Print Image using Printer.Canvas
Now I am going to show you how to print an image from a file. First I will put a TImage control and will load an image from file with writing code and then will print the image by using Printer object.
procedure TForm1.btnPrintClick(Sender: TObject);
var
rectPage: TRect;
image1: TBitmap;
begin
if PrintDialog1.Execute then
begin
rectPage := Rect(0, 0, Printer.PageWidth, Printer.PageHeight);
with Printer do
begin
//start printing
BeginDoc;
image1 := TBitmap.Create;
image1.LoadFromFile('C:\jitendra\clock.bmp');
Canvas.StretchDraw(Rect(500, 1000, 1500, 2000), image1);
image1.Free;
//finish printing
EndDoc;
end;
ShowMessage('Print is done.');
end;
end;
Print Line and Shapes using Printer.Canvas
We can draw any kind of shape on Printer.Canvas and can print that drawn shape. More about drawing shapes in Delphi.
procedure TForm1.btnPrintClick(Sender: TObject);
var
rectPage: TRect;
begin
if PrintDialog1.Execute then
begin
rectPage := Rect(0, 0, Printer.PageWidth, Printer.PageHeight);
with Printer do
begin
//start printing
BeginDoc;
Canvas.Pen.Width := 3;
Canvas.Pen.Color := clBlue;
Canvas.MoveTo(500, 2200);
Canvas.LineTo(rectPage.Width-500, 2200);
Canvas.Brush.Color := clRed;
Canvas.Rectangle(1000, 2500, 2000, 3500);
Canvas.Brush.Color := clYellow;
Canvas.Ellipse(1000, 3000, 2000, 4000);
//finish printing
EndDoc;
end;
ShowMessage('Print is done.');
end;
end;
Now I am putting all in one…
procedure TForm1.btnPrintClick(Sender: TObject);
var
rectPage: TRect;
rectText: TRect;
sText: string;
sReportHeader: string;
image1: TBitmap;
begin
if PrintDialog1.Execute then
begin
rectPage := Rect(0, 0, Printer.PageWidth, Printer.PageHeight);
with Printer do
begin
//start printing
BeginDoc;
sReportHeader := 'Report Header';
sText := RichEdit1.Lines.Text;
Canvas.Font.Name := 'Verdana';
Canvas.Font.Size := 11;
Canvas.Font.Color := clBlack;
Canvas.Font.Style := [fsBold];
Canvas.TextRect(rectPage, (rectPage.Width-Canvas.TextWidth(sReportHeader)) div 2,
10, sReportHeader);
Canvas.Font.Color := clRed;
Canvas.Font.Style := [];
rectText := Rect(100, 300, rectPage.Width-200, 1000);
Canvas.TextRect(rectText, sText, [tfWordBreak]);
image1 := TBitmap.Create;
image1.LoadFromFile('C:\jitendra\clock.bmp');
Canvas.StretchDraw(Rect(500, 1000, 1500, 2000), image1);
image1.Free;
Canvas.Pen.Width := 3;
Canvas.Pen.Color := clBlue;
Canvas.MoveTo(500, 2200);
Canvas.LineTo(rectPage.Width-500, 2200);
Canvas.Brush.Color := clRed;
Canvas.Rectangle(1000, 2500, 2000, 3500);
Canvas.Brush.Color := clYellow;
Canvas.Ellipse(1000, 3000, 2000, 4000);
//finish printing
EndDoc;
end;
ShowMessage('Print is done.');
end;
end;
Print TListView data using Printer.canvas
Here in following example I showed how to print Listview data and also added NewPage to print another ListView control data. I have put 2 Listview control, 2 Button control and on button click I am filling Listview data. And on Print button click I am printing the filled data.
So lets see…
//fill employee data//
procedure TForm1.btnLoadEmpdataClick(Sender: TObject);
begin
with listviewEmp do
begin
with Items.Add do
begin
Caption := '1';
SubItems.Add('Messi');
end;
with Items.Add do
begin
Caption := '2';
SubItems.Add('Sachin');
end;
with Items.Add do
begin
Caption := '3';
SubItems.Add('Phillip');
end;
with Items.Add do
begin
Caption := '4';
SubItems.Add('Mike');
end;
with Items.Add do
begin
Caption := '5';
SubItems.Add('Shane');
end;
with Items.Add do
begin
Caption := '6';
SubItems.Add('Ramos');
end;
with Items.Add do
begin
Caption := '7';
SubItems.Add('Polluck');
end;
with Items.Add do
begin
Caption := '8';
SubItems.Add('Jorge');
end;
with Items.Add do
begin
Caption := '9';
SubItems.Add('Gayle');
end;
with Items.Add do
begin
Caption := '10';
SubItems.Add('John');
end;
end;
end;
//fill city – country data//
procedure TForm1.btnLoadCitydataClick(Sender: TObject);
begin
with listviewCity do
begin
with Items.Add do
begin
Caption := 'Delhi';
SubItems.Add('India');
end;
with Items.Add do
begin
Caption := 'Beijing';
SubItems.Add('China');
end;
with Items.Add do
begin
Caption := 'Denver';
SubItems.Add('USA');
end;
with Items.Add do
begin
Caption := 'London';
SubItems.Add('UK');
end;
with Items.Add do
begin
Caption := 'Sydney';
SubItems.Add('Australia');
end;
with Items.Add do
begin
Caption := 'Captown';
SubItems.Add('S. Africa');
end;
with Items.Add do
begin
Caption := 'Kinsasha';
SubItems.Add('Congo');
end;
with Items.Add do
begin
Caption := 'Timphu';
SubItems.Add('Bhutan');
end;
with Items.Add do
begin
Caption := 'Paris';
SubItems.Add('France');
end;
with Items.Add do
begin
Caption := 'Toronto';
SubItems.Add('Canada');
end;
end;
end;
On Print click…
procedure TForm1.btnPrintClick(Sender: TObject);
var
sText: string;
sReportHeader: string;
image1: TBitmap;
i: Integer;
iTop: Integer;
begin
if PrintDialog1.Execute then
begin
with Printer do
begin
//start printing
BeginDoc;
Canvas.Font.Size := 15;
Canvas.Font.Color := clRed;
Canvas.Font.Style := [fsBold];
sReportHeader := 'Employee Details';
Canvas.TextOut((Printer.PageWidth-Canvas.TextWidth(sReportHeader)) div 2, 100, sReportHeader);
Canvas.MoveTo(200, 500);
Canvas.LineTo(Printer.PageWidth-200, 500);
Canvas.Font.Size := 12;
Canvas.Font.Color := clBlue;
Canvas.Font.Style := [fsBold];
Canvas.TextOut(400, 600, listviewEmp.Column[0].Caption);
Canvas.TextOut(1000, 600, listviewEmp.Column[1].Caption);
Canvas.MoveTo(200, 800);
Canvas.LineTo(Printer.PageWidth-200, 800);
Canvas.Font.Size := 10;
Canvas.Font.Color := clBlack;
Canvas.Font.Style := [];
iTop := 900;
for I := 0 to listviewEmp.Items.Count-1 do
begin
Canvas.TextOut(400, iTop, listviewEmp.Items[i].Caption);
Canvas.TextOut(1000, iTop, listviewEmp.Items[i].SubItems[0]);
iTop := iTop + 250;
end;
iTop := iTop+250;
Canvas.MoveTo(200, iTop);
Canvas.LineTo(Printer.PageWidth-200, iTop);
Canvas.TextOut((Printer.PageWidth-Canvas.TextWidth(sReportHeader)) div 2, iTop + 100, DateToStr(Now)+' - Page:'+IntToStr(PageNumber));
NewPage;
Canvas.Font.Size := 15;
Canvas.Font.Color := clRed;
Canvas.Font.Style := [fsBold];
sReportHeader := 'City - Country Details';
Canvas.TextOut((Printer.PageWidth-Canvas.TextWidth(sReportHeader)) div 2, 100, sReportHeader);
Canvas.MoveTo(200, 500);
Canvas.LineTo(Printer.PageWidth-200, 500);
Canvas.Font.Size := 12;
Canvas.Font.Color := clBlue;
Canvas.Font.Style := [fsBold];
Canvas.TextOut(400, 600, listviewCity.Column[0].Caption);
Canvas.TextOut(2000, 600, listviewCity.Column[1].Caption);
Canvas.MoveTo(200, 800);
Canvas.LineTo(Printer.PageWidth-200, 800);
Canvas.Font.Size := 10;
Canvas.Font.Color := clBlack;
Canvas.Font.Style := [];
iTop := 900;
for I := 0 to listviewCity.Items.Count-1 do
begin
Canvas.TextOut(400, iTop, listviewCity.Items[i].Caption);
Canvas.TextOut(2000, iTop, listviewCity.Items[i].SubItems[0]);
iTop := iTop + 250;
end;
iTop := iTop+250;
Canvas.MoveTo(200, iTop);
Canvas.LineTo(Printer.PageWidth-200, iTop);
Canvas.TextOut((Printer.PageWidth-Canvas.TextWidth(sReportHeader)) div 2, iTop + 100, DateToStr(Now)+' - Page:'+IntToStr(PageNumber));
//finish printing
EndDoc;
end;
ShowMessage('Print is done.');
end;
end;
Cancel a Printing Job
Sometime while printing a complexity and larger size than simple one then it may be important to provide a Cancel print option to user so that User can cancel the print for unwanted printing.
procedure TForm1.btnCanelPrintClick(Sender: TObject);
begin
// Now user has pressed cancel, we abort the printing //
if Printer.Printing then
begin
Printer.Abort;
ShowMessage('Printing aborted');
end;
end;
Get Printers list installed in our System
Printer.Printers property returns list of printers installed in our system. As it’s a TStrings type property we can assign the property to combobox property. In following example, on form create I am filling combobox items with Printers list.
begin
ComboBox1.Items.Assign(Printer.Printers);
end;
To get default printer set on our system
Printer.PrinterIndex returns default printer set on our system.
ComboBox1.ItemIndex := Printer.PrinterIndex;
Print existing files from Delphi using ShellExecute
We can use ShellExecute procedure to print existing PDF, DOC, XLS, HTML, RTF, DOCX, TXT documents. ShellExecute can be used launch application, open Windows Explorer or prints the specified file. ShellExecute always uses the default printer for the "print" action.
ShellExecute: Print
ShellExecute(Handle, 'print', PChar('c:\jitendra\file1.doc'), nil, nil, SW_HIDE) ;
Using the above call, document " file1.doc" located on the root of the C drive will be sent to the Windows default printer and will be printed.
ShellExecute: PrintTo
Print a file to a specific printer. So for that, first we are adding list of printers to a combobox and then we will print the file to selected printer. Drop a ComboBox on a form. Name it "cboPrinter". Set Style to csDropDownEdit.
On form create
//have available printers in the combo box
cboPrinter.Items.Assign(printer.Printers);
//pre-select the default / active printer
cboPrinter.ItemIndex := printer.PrinterIndex;
uses
shellapi, printers;
.....
procedure PrintDocument(const documentToPrint : string) ;
var
printCommand : string;
printerInfo : string;
Device, Driver, Port: array[0..255] of Char;
hDeviceMode: THandle;
begin
if Printer.PrinterIndex = cboPrinter.ItemIndex then
begin
printCommand := 'print';
printerInfo := '';
end;
else
begin
printCommand := 'printto';
Printer.PrinterIndex := cboPrinter.ItemIndex;
Printer.GetPrinter(Device, Driver, Port, hDeviceMode) ;
printerInfo := Format('"%s" "%s" "%s"', [Device, Driver, Port]) ;
end;
ShellExecute(Application.Handle, PChar(printCommand), PChar(documentToPrint), PChar(printerInfo), nil, SW_HIDE) ;
end;
Hey,
ReplyDeleteThis information has been very useful, This blog has provided me proper knowledge and understanding regarding the issue, I have tried this printing accordingly as mentioned and is impressed by the result and the different ways that this printing can be done.Though at the start there was an unknown error called lexmark 900 firmware error, this error has been solved by switching the printer off and letting it delete and reset the memory and then switching it for solving the issue.
Initially I was facing trouble while using Epson printer, but figured out it to be a driver issue, directly related to error code 0x97
ReplyDeletewhich was responsible for the issue.
Being a tech professional I got this blog is very informative it is based on Customized Printing in Delphi, which I found very relevant. If your printer do issue and
ReplyDeletecanon printer not printing black then you can check it out.
Lovely blog! The customized fashion is intelligent trendy, and at the same time comfortable.
ReplyDeleteGarmentprinting
Easy language you written in this article. Thanks for sharing.
ReplyDeleteOceanapart Technologies - Printer Setup
Many thanks for taking the time to discuss this, I really feel strongly about it and love learning much more on this topic.I hope we get new updates related to the blog.
ReplyDeleteCustomised Drinkware
My Testimony Hello everyone. Am here to testify how I got my loan from Mr. Benjamin after I applied several times from various loan lenders who promised to help but they never gave me the loan. Until a friend of mine introduced me to Mr.Benjamin Lee promised to help me and indeed he did as he promised without any form of delay.I never thought there are still reliable loan lenders until I met Mr. Benjamin Lee, who indeed helped with the loan and changed my belief. I don't know if you are in any way in need of a genuine and urgent loan, Be free to contact Mr. Benjamin via WhatsApp +1-989-394-3740 and his email: Lfdsloans@outlook.com thank you.
ReplyDeleteWe are providing UK Printing services of printing the HR manuals and documents. Online ordering service is available 24/7 to save your time and effort.
ReplyDeleteAmazing product thanks for sharing with us It is very informative. If you need any type of boxes you can visit the link.
ReplyDeleteCandy packaging Connecticut
custom made Bath Bomb boxes
It is very informative post thanks for sharing the information..
ReplyDeletepersonalized Lingerie Boxes
Holiday Party boxes New York
Embroidery Denver - Rocky Mountain Apparel in Denver, Colorado, has been producing high quality screen printing, embroidery, promotional products, banners and graphic design services for over 25 years to Colorado. To contact Rocky Mountain Apparel or to obtain a free quote, please complete the fields below and click SUBMIT.
ReplyDeleteNice Post!
ReplyDeletecustom clothing solutions
screen printing services
I like the post Its has nice article It's really effective and very impressive, We hope this information will help everyone.Corporate Gifts Printing Services in Bangalore
ReplyDeleteThank you for your post, myself very happy to read it because it can give me more insight, thanks.Perfect Cut Vinyl
ReplyDeletePretty good useful information you shared with us.About the background of printer and also functions of a printer
ReplyDeleteThe cultural sensitivity and awareness you bring to your topics are commendable. You navigate diverse subjects with respect and insight.
ReplyDeleteMarble Floor Polishing in Dubai
Thanks for the insightful post! The capabilities of Delphi for printing are fantastic, especially when it comes to producing personalised corporate gifts
ReplyDeleteand bulk corporate gifts I’m eager to see how you’ll showcase TPrintDialog and TPrinterSetupDialog in action. It sounds like a valuable resource for custom printing needs!
This blog is absolutely fantastic! The content is not only informative but also engaging. I really appreciate the effort and detail put into each post. Highly recommended for anyone looking for valuable insights. For more great content, feel free to visit my website as wellDigital Marketing Services in Pakistan
ReplyDelete