 
   Delphi - объектно-ориентированный язык программирования, разработанный компанией Borland в 1995 году. Он основан на языке программирования Pascal, но имеет более расширенные возможности и добавлены новые функции.
 
   Delphi является интегрированной средой разработки (IDE), которая позволяет разрабатывать программное обеспечение для различных платформ, включая Windows, macOS, Android и iOS. Delphi достигает многоплатформенности с помощью...
Под Win16 Вы можете использовать функцию SpoolFile, или Passthrough escape, если принтер поддерживает последнее. Под Win32 Вы можете использовать WritePrinter.
Ниже пример открытия принтера и записи чистого потока данных в принтер. Учтите, что Вы должны передать корректное имя принтера, такое, как "HP LaserJet 5MP", чтобы функция сработала успешно.
Конечно, Вы можете включать в поток данных любые необходимые управляющие коды, которые могут потребоваться.
uses WinSpool;
procedure WriteRawStringToPrinter(PrinterName:string; S:string);
var
  Handle: THandle;
  N: DWORD;
  DocInfo1: TDocInfo1;
begin
  if not OpenPrinter(PChar(PrinterName), Handle, nil) then
  begin
    ShowMessage('Error ' + IntToStr(GetLastError));
    Exit;
  end;
  with DocInfo1 do
  begin
    pDocName := PChar('test doc');
    pOutputFile := nil;
    pDataType := 'RAW';
  end;
  StartDocPrinter(Handle, 1, @DocInfo1);
  StartPagePrinter(Handle);
  WritePrinter(Handle, PChar(S), Length(S), N);
  EndPagePrinter(Handle);
  EndDocPrinter(Handle);
  ClosePrinter(Handle);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  WriteRawStringToPrinter('HP', 'Test This');
end;
Посмотри и доделай как тебе надо:
unit TextPrinter;
interface
uses
  Windows, Controls, Forms, Dialogs;
type
  TTextPrinter = class(TObject)
    FNumberOfBytesWritten: Integer;
    FHandle: THandle;
    FPrinterOpen: Boolean;
    FErrorString: PChar;
    procedure SetErrorString;
  public
    constructor Create;
    procedure write(const Str: string);
    procedure WriteLn(const Str: string);
    destructor Destroy; override;
  published
    property NumberOfBytesWritten: Integer read FNumberOfBytesWritten;
end;
implementation
{TTextPrinter}
constructor TTextPrinter.Create;
begin
  FHandle := CreateFile('LPT1', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ
  or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
  if FHandle = INVALID_HANDLE_VALUE then
  begin
    SetErrorString;
    raise Exception.Create(FErrorString);
  end
  else
    FPrinterOpen := True;
end;
procedure TTextPrinter.SetErrorString;
begin
  if FErrorString <> nil then
  LocalFree(Integer(FErrorString));
  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,
  nil, GetLastError(), LANG_USER_DEFAULT, @FErrorString, 0, nil);
end;
procedure TTextPrinter.write(const Str: string);
var
  OEMStr: PChar;
  NumberOfBytesToWrite: Integer;
begin
  if not FPrinterOpen then
    Exit;
  NumberOfBytesToWrite := Length(Str);
  OEMStr := PChar(LocalAlloc(LMEM_FIXED, NumberOfBytesToWrite + 1));
  try
    CharToOem(PChar(Str), OEMStr);
    if not WriteFile(FHandle, OEMStr^, NumberOfBytesToWrite, FNumberOfBytesWritten, nil) then
    begin
      SetErrorString;
      raise Exception.Create(FErrorString);
    end;
  finally
    LocalFree(Integer(OEMStr));
  end;
end;
procedure TTextPrinter.WriteLn(const Str: string);
begin
  Self.write(Str);
  Self.write(#10);
end;
destructor TTextPrinter.Destroy;
begin
  CloseHandle(FHandle);
  if FErrorString <> nil then
    LocalFree(Integer(FErrorString));
end;
end.
P.S. В принципе, вместо LPT1 может стоять что угодно, даже сетевой сервер печати (serverprn) - все равно печатает. Можно и параметр в конструктор вставить и т.д.