Por último queda el método a usar, existen varios que conozca, a través de un report, tipo memo y por código de impresora, yo he usado los dos últimos, pero no descarto otros métodos más, hablo de los que he leído y de aquí en adelante de los que yo uso, para ello os pongo el código de las funciones que uso que suelo usar para ambos casos ya que más adelante aparecerá y sin esta parte será más compliacado entenderlo
Código Delphi
[-]unit uimpticket;
interface
uses printers, WinSpool, Windows, Sysutils, Dialogs, StrUtils;
function WriteRawDataToPrinter(PrinterName: String; Str: String): Boolean;
Function GetImpresora(Impre:String):Integer;
function MyTextReplace(Texto:String):String;
function CenterString(aStr: String; Len: Integer): String;
implementation
function WriteRawDataToPrinter(PrinterName: String; Str: String): Boolean;
var
PrinterHandle: THandle;
DocInfo: TDocInfo1;
i: Integer;
B: Byte;
Escritos: DWORD;
begin
Result:= FALSE;
if OpenPrinter(PChar(PrinterName), PrinterHandle, nil) then
try
FillChar(DocInfo,Sizeof(DocInfo),#0);
with DocInfo do
begin
pDocName:= PChar('Printer Test');
pOutputFile:= nil;
pDataType:= 'RAW';
end;
if StartDocPrinter(PrinterHandle, 1, @DocInfo) <> 0 then
try
if StartPagePrinter(PrinterHandle) then
try
while Length(Str) > 0 do
begin
if Copy(Str, 1, 1) = '\' then
begin
if Uppercase(Copy(Str, 2, 1)) = 'X' then
Str[2]:= '$';
if not TryStrToInt(Copy(Str, 2, 3),i) then
Exit;
B:= Byte(i);
Delete(Str, 1, 3);
end else B:= Byte(Str[1]);
Delete(Str,1,1);
WritePrinter(PrinterHandle, @B, 1, Escritos);
end;
Result:= TRUE;
finally
EndPagePrinter(PrinterHandle);
end;
finally
EndDocPrinter(PrinterHandle);
end;
finally
ClosePrinter(PrinterHandle);
end;
end;
Function GetImpresora(Impre:String):Integer;
Var
nCont:Integer;
lSearch:Boolean;
cNewLIne:String;
begin
lSearch:=False;
cNewLine:=Chr(10)+Chr(13);
For nCont:=0 to Printer.Printers.Count - 1 do begin
if Pos(impre, Printer.Printers[nCont]) <> 0 then
begin
lSearch:=True;
Result:=nCont;
Break;
end;
end;
if lSearch = False then
begin
ShowMessage('Impresora no encontrada.'+impre+cNewLine+'Se utilizará la predeterminda.');
Result:=-1
end;
end;
function MyTextReplace(Texto:String):String;
begin
if Texto<>'' then begin
Texto:= AnsiReplaceStr(Texto,'Ñ', #165);
Texto:= AnsiReplaceStr(Texto,'ñ', #164);
Texto:= AnsiReplaceStr(Texto,'á', #160);
Texto:= AnsiReplaceStr(Texto,'é', #101); Texto:= AnsiReplaceStr(Texto,'í', #161);
Texto:= AnsiReplaceStr(Texto,'ó', #162);
Texto:= AnsiReplaceStr(Texto,'ú', #163);
Texto:= AnsiReplaceStr(Texto,'Á', #65);
Texto:= AnsiReplaceStr(Texto,'É', #144);
Texto:= AnsiReplaceStr(Texto,'Í', #73);
Texto:= AnsiReplaceStr(Texto,'Ó', #79);
Texto:= AnsiReplaceStr(Texto,'Ú', #85);
Texto:= AnsiReplaceStr(Texto,'Ü', #85);
Texto:= AnsiReplaceStr(Texto,'Ü', #129);
Result:=Texto;
end;
end;
function CenterString(aStr: String; Len: Integer): String;
var
posStr : integer;
begin
if Length(aStr)>Len then
Result := Copy(aStr, 1, Len)
else
begin
posStr := (len - Length(aStr)) div 2;
Result := Format('%*s', [len, aStr + Format('%-*s', [posStr, ''])]);
end;
end;
end.
el WriteRawDataToPrinte es del maestro SEONE
el GetImpresora es del maestro Marcos Zorrilla
el MyTextReplace es bajado de Planetadelphi.com
Y CenterString no estoy seguro si es mía o la baje de algún lado
Yo personalmente uso ambos sistemas y dejo que el cliente decida si quiere imprimir por código o ticket simple, esto lo hace en configuración mediante el campo método de impresión con dos valores posibles 1 o 2.
Pongo una imagen de mi visor de tickets
en esta me queda varias cosas que corregir, detalles como nº de artículos, ya que hace referencia al número de lineas y no de artículos, etc, pero os vale de ejemplo.
El método por código es un poco más trabajoso y debemos tener en cuenta que en cualquier momento el cliente puede cambiar de impresora, resultando que los códigos ya no son válidos, el método de usar un memo, es 100% fiable ya que imprimimos nada más que un texto plano y podemos salvar que nuestra impresora admita acentos o no ya que los sustituiremos gracias a la función MyTextReplace, permitiendo imprimir en cualquier impresora que admita los códigos ASCII, por la tanto en todas, salvo especificas para otros países que no tengan la posibilidad de cambiar el idioma /(ejemplo caracteres, chino, cirilicos o árabes)
Pongo el código de unos de mis primeros tickets por código y memo con selección de impresora normal o no (ya digo mi antiguo método
Código Delphi
[-]var
r: TRect;
i,p: Integer;
begin
if DM.DsConfi.DataSet.FieldByName('USARTICKETNORMAL').Value='S' then
begin if not DsTicket.DataSet.IsEmpty then
begin
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie ldByName('TEXTINICIAR').Value);
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie ldByName('RETROCEDER').Value);
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie ldByName('RETROCEDER').Value);
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie ldByName('TEXGRANDE').Value);
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,CenterString(DM.DsConf i.DataSet.FieldByName('EMPRESA').Value,35));
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie ldByName('TEXCOMPRIMIDO').Value);
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(MyTextReplace ('Calle:'+DM.DsConfi.DataSet.FieldByName('DIRECCION').Value),42,0));
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(MyTextReplace ('Población:'+DM.DsConfi.DataSet.FieldByName('POBLACION').Value),42,0));
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(MyTextReplace ('C.P.:'+DM.DsConfi.DataSet.FieldByName('CODIGOPOSTAL').Value+' Provincia:'+DM.DsConfi.DataSet.FieldByName('PROVINCIA').Value),42,0));
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(MyTextReplace ('Tf.:'+DM.DsConfi.DataSet.FieldByName('TELEFONO').Value+' CIF:'+DM.DsConfi.DataSet.FieldByName('CIF').Value),42,0));
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(MyTextReplace ('Email:'+DM.DsConfi.DataSet.FieldByName('EMAIL').Value),42,0));
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(MyTextReplace ('Web:'+DM.DsConfi.DataSet.FieldByName('WEB').Value),42,0));
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(' ',42,0));
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,Espacios(MyTextReplace ('Número: ')+DsTicket.DataSet.FieldByName('NUMERO').AsString+
' '+DsTicket.DataSet.FieldByName('FECHA').AsString+
' '+DsTicket.DataSet.FieldByName('HORA').AsString,42,0));
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(' ',42,0));
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,Espacios('Cant.',6,0)+ espacios('Producto',20,0)+espacios('Dto.',6,0)+espacios('Sub-total',10,0));
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('--------------------------------------------',42,0));
with DsDetalle.DataSet do
begin
First;
while not Eof do
begin
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(DsDetalle.Dat aSet.FieldByName('UNIDADES').AsString,5,1)+' '+
espacios(Copy(MyTextReplace(DsDetalle.DataSet.FieldByName('DESCRIPCION').AsString),1,19),19,0)+' '+
espacios(FormatFloat('#,##0.00',DsDetalle.DataSet.FieldByName('DESCUENTO').Value),5,1)+' '+
espacios(FormatFloat('#,##0.00',DsDetalle.DataSet.FieldByName('SUBTOTAL').value),10,1));
Next;
end;
end;
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('--------------------------------------------',42,0));
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie ldByName('TEXTCOMPRIMIDANEGRITA').Value);
if not DsTicket.DataSet.FieldByName('TOTAL').IsNull then WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('Total: ',32,1)+Espacios(FormatFloat('#,##0.00',DsTicket.DataSet.FieldByName('TOTAL').Value),10,1))
else WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('Total: ',32,1)+Espacios(FormatFloat('#,##0.00',0),10,1));
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie ldByName('TEXCOMPRIMIDO').Value);
if not DsTicket.DataSet.FieldByName('ENTREGADO').IsNull then WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('Entregado: ',32,1)+Espacios(FormatFloat('#,##0.00',DsTicket.DataSet.FieldByName('ENTREGADO').Value),10,1))
else WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('Entregado: ',32,1)+Espacios(FormatFloat('#,##0.00',0),10,1));
if DsTicket.DataSet.FieldByName('SINPAGAR').AsString='N' then
begin
if not DsTicket.DataSet.FieldByName('DEVUELTO').IsNull then WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('Devuelto: ',32,1)+Espacios(FormatFloat('#,##0.00',DsTicket.DataSet.FieldByName('DEVUELTO').Value),10,1))
else WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios('Devuelto: ',32,1)+Espacios(FormatFloat('#,##0.00',0),10,1));
end else
begin
if not DsTicket.DataSet.FieldByName('DEVUELTO').IsNull then WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,Espacios('SinP.[x]',10,0)+espacios('Devuelto: ',22,1)+Espacios(FormatFloat('#,##0.00',DsTicket.DataSet.FieldByName('DEVUELTO').Value),10,1))
else WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,Espacios('SinP.[x]',10,0)+espacios('Devuelto: ',22,1)+Espacios(FormatFloat('#,##0.00',0),10,1));
end;
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,espacios(' ',44,0));
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,CenterString(MyTextRep lace(DM.DsConfi.DataSet.FieldByName('FRASECIERRE').Value),44));
for i := 1 to 7 do WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie ldByName('TEXTAVANZAR').Value);
end;
end else
begin
with Printer do
begin
PrinterIndex:=GetImpresora(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value);
r := Rect(100,100,(Pagewidth - 100),(PageHeight - 100));
BeginDoc;
Canvas.Brush.Style := bsClear;
for i := 0 to Memo1.Lines.Count do
Canvas.TextOut(100,180 + (i * Canvas.TextHeight(Memo1.Lines.Strings[i])),
Memo1.Lines.Strings[i]);
Canvas.Brush.Color := clBlack;
Canvas.FrameRect(r);
EndDoc;
end;
end;
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie ldByName('TEXTCORTE').Value);
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie ldByName('CODIGOAPERTURACAJA').Value);
WriteRawDataToPrinter(DM.DsConfi.DataSet.FieldByName('IMPRESORATICKET').Value,DM.DsConfi.DataSet.Fie ldByName('TEXTINICIAR').Value);
end;
Como veis lo que hago es diversas llamadas a la tabla de configuración donde tengo definidos los campos con su código tipo TEXTCORTE, TEXTINICIAR, etc.