Печать данных и графических элементов, таких как цифровые подписи, является распространенной задачей при разработке приложений для розничной торговли, банковского сектора и других областей. В Delphi для работы с печатью традиционно используется компонент TPrinter, но у начинающих разработчиков часто возникают сложности с его использованием, особенно при попытке вывода графики.
Проблема и анализ кода
Как видно из приведенного контекста, пользователь столкнулся с несколькими проблемами:
Ошибка "undeclared identifier" при использовании методов TextOut, DrawText и TextRect
Проблемы с выводом цифровой подписи на принтер GO Link GL-28
Неправильная инициализация принтера
Основные ошибки в исходном коде:
Printer := TPrinter.Create; // Неправильное создание объекта принтера
Printer.Canvas.TextOut(...) // Метод TextOut не существует в FireMonkey
Решение для Windows-приложений
Для Windows-приложений правильный подход к печати выглядит следующим образом:
uses
Vcl.Printers;
procedure TForm1.PrintReceiptWithSignature(const AData: string; ASignature: TBitmap);
var
YPos: Integer;
PrintRect: TRect;
begin
if PrintDialog1.Execute then
begin
Printer.BeginDoc;
try
YPos := 100; // Начальная позиция по вертикали
// Печать текста
Printer.Canvas.Font.Name := 'Courier New';
Printer.Canvas.Font.Size := 10;
Printer.Canvas.TextOut(100, YPos, AData);
Inc(YPos, 200);
// Печать подписи
if Assigned(ASignature) then
begin
Printer.Canvas.StretchDraw(
Rect(100, YPos, 100 + ASignature.Width, YPos + ASignature.Height),
ASignature
);
end;
finally
Printer.EndDoc;
end;
end;
end;
Решение для мобильных приложений (Android/iOS)
Для мобильных устройств подход отличается, так как используется FireMonkey framework:
uses
FMX.Printer, FMX.Graphics;
procedure TForm1.PrintMobileReceipt(const AData: string; ASignature: TBitmap);
var
DestRect: TRectF;
Printer: TPrinter;
begin
Printer := TPrinter.Current;
if Printer = nil then Exit;
Printer.DefaultPrinter;
Printer.Title := 'Receipt with Signature';
Printer.BeginDoc;
try
// Печать текста
Printer.Canvas.Font.Size := 12;
Printer.Canvas.FillText(
RectF(50, 50, Printer.PageWidth - 50, 100),
AData,
False, 1, [], TTextAlign.Leading
);
// Печать подписи
if Assigned(ASignature) then
begin
DestRect := RectF(
50, 150,
50 + ASignature.Width,
150 + ASignature.Height
);
Printer.Canvas.DrawBitmap(
ASignature,
RectF(0, 0, ASignature.Width, ASignature.Height),
DestRect,
1
);
end;
finally
Printer.EndDoc;
end;
end;
Работа с Bluetooth-принтерами
Для специализированных принтеров, таких как GO Link GL-28, может потребоваться прямое подключение через Bluetooth и отправка команд на языке ESC/POS:
uses
System.Bluetooth, System.Classes;
procedure TForm1.PrintToBluetoothPrinter(const AData: string; ASignature: TBitmap);
var
BluetoothManager: TBluetoothManager;
Devices: TBluetoothDeviceList;
Socket: TBluetoothSocket;
Data: TBytes;
MS: TMemoryStream;
begin
BluetoothManager := TBluetoothManager.Current;
Devices := BluetoothManager.GetPairedDevices;
// Поиск нужного принтера (пример)
for var Device in Devices do
begin
if Pos('GL-28', Device.DeviceName) > 0 then
begin
Socket := Device.CreateClientSocket(StringToGUID('{00001101-0000-1000-8000-00805F9B34FB}'), False);
try
if Socket.Connect then
begin
// Инициализация принтера
Data := TEncoding.ASCII.GetBytes(#27'@');
Socket.SendData(Data);
// Отправка текста
Data := TEncoding.ASCII.GetBytes(AData + #10#13);
Socket.SendData(Data);
// Конвертация подписи в монохромное изображение и отправка
if Assigned(ASignature) then
begin
MS := TMemoryStream.Create;
try
ConvertToEscPos(ASignature, MS); // Специальная функция конвертации
Socket.SendData(MS.ToBytes);
finally
MS.Free;
end;
end;
// Отрезание бумаги
Data := TEncoding.ASCII.GetBytes(#29'V'#66#0);
Socket.SendData(Data);
end;
finally
Socket.Close;
end;
Break;
end;
end;
end;
Конвертация цифровой подписи
Для преобразования векторной подписи в растровое изображение:
function TForm1.SignatureToBitmap(ACanvas: TCanvas; AWidth, AHeight: Integer): TBitmap;
var
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
try
Bitmap.SetSize(AWidth, AHeight);
Bitmap.Canvas.BeginScene;
try
Bitmap.Canvas.Clear(TAlphaColors.White);
// Здесь рисуем подпись на Bitmap.Canvas
// Например, копируем из исходного Canvas
Bitmap.Canvas.DrawCanvas(
RectF(0, 0, AWidth, AHeight),
ACanvas,
RectF(0, 0, ACanvas.Width, ACanvas.Height)
);
finally
Bitmap.Canvas.EndScene;
end;
Result := Bitmap;
except
Bitmap.Free;
raise;
end;
end;
Альтернативные решения
Использование отчетов:
FastReport
ReportBuilder
Rave Reports
Пример с FastReport:
procedure TForm1.PrintWithFastReport(const AData: string; ASignature: TBitmap);
begin
frxReport1.LoadFromFile('Receipt.fr3');
// Передача данных
TfrxMemoView(frxReport1.FindObject('Memo1')).Text := AData;
// Передача изображения
if Assigned(ASignature) then
begin
TfrxPictureView(frxReport1.FindObject('Picture1')).Picture.Assign(ASignature);
end;
frxReport1.ShowReport;
end;
Генерация PDF:
Использование PDF-принтеров
Библиотеки типа SynPDF, PDFtoolkit
uses
SynPDF;
procedure TForm1.GeneratePDF(const AData: string; ASignature: TBitmap);
var
PDF: TPDFDocument;
Page: TPDFPage;
begin
PDF := TPDFDocument.Create;
try
PDF.DefaultPaperSize := psA4;
PDF.DefaultOrientation := ppoPortrait;
Page := PDF.AddPage;
Page.AddText(10, 10, AData);
if Assigned(ASignature) then
begin
Page.AddImage(
10, 100,
ASignature.Width / 3, ASignature.Height / 3,
ASignature
);
end;
PDF.SaveToFile('Receipt.pdf');
finally
PDF.Free;
end;
end;
Заключение
Печать данных с цифровой подписью в Delphi требует понимания платформы, для которой разрабатывается приложение. Для Windows-приложений можно использовать стандартный компонент TPrinter из Vcl.Printers, для мобильных - TPrinter из FMX.Printer. Специализированные принтеры могут потребовать прямого подключения через Bluetooth и отправки команд на их собственном языке.
Ключевые моменты для успешной печати: 1. Правильная инициализация принтера 2. Учет различий между VCL и FireMonkey 3. Конвертация графических элементов в подходящий формат 4. Обработка ошибок подключения для Bluetooth-устройств
Приведенные примеры кода демонстрируют различные подходы к решению задачи печати, и вы можете выбрать наиболее подходящий для вашего конкретного случая.
Статья описывает методы печати данных и цифровых подписей в Delphi, включая решения для Windows, мобильных приложений и Bluetooth-принтеров.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.