API impresión
Hay una nueva versión en Android de la API de impresión, con más características, más flexible y más eficiente, cuyo módulo es independiente del framework, aunque siga invocándose desde el script.
Es preferible usarla frente a ésta, que será marcada obsoleta.
IMPRESIÓN
El control de impresión con XOne está implementado de forma que las órdenes se impriman directamente, mediante funciones SCRIPT, optimizando el uso de memoria que habitualmente consume este tipo de controles.
- La impresión está disponible en todas las plataformas excepto IPHONE.
- En Windows Mobile, el archivo printer.xml también tiene que estar pasado a .bin.
- En Windows Mobile, si NO se va a utilizar el fichero listdirect(antiguo método de impresión), es aconsejable no incluirlo en la instalación, de lo contrario, tendríamos un consumo de memoria innecesario.
- El método de impresión directo mediante SCRIPT está disponible también con el listdirect.
- En Android, no es necesario pasarle parámetros a startprint, pues la impresora se selecciona desde un menú.
- Recordar que cada impresora podría tener sus propios comandos de inicialización y los que sirven para una pueden no valer para otra.
- Las impresoras Bluetooth suelen usar el lenguaje de programación CPCL para comunicarse.
- En caso de no funcionar correctamente, comprobar si el modelo lo tenemos homologado y consultar la documentación de la impresora para ver los comandos de inicialización y tal.
Módulo impresión en Android
Para Android, es necesario instalar el .apk del servidor de impresoras. Para usarlo, antes de mandar algún documento a imprimir, se debe activar el bluetooth y sincronizar con la impresora.
Una vez hecho esto, mandar a imprimir el documento siguiendo el procedimiento descrito abajo, y tras invocar startprint, debería salir el menú de selección de impresora. Pulsar la tecla menú en el dispositivo y seleccionar scan.
Funciones de impresión
Se han implementado las siguientes funciones para controlar la impresión desde script sin necesidad de usar el fichero de plantillas listdirect.bin (antiguo método de impresión).
StartPrint (int nPrinterOption)
Conecta con la impresora que se indique por parámetro y queda preparada para imprimir.
Si la conexión es correcta devuelve 0, en caso contrario, un código de error.
StartPrint (String stPrinterType) [Android]
Versión del comando anterior específica para Android. Debemos especificar qué driver de impresión usar, si no, usará un driver genérico. Si no se especifica stPrinterType, cargará el driver de la impresora Datecs.
Valores posibles: brother, zebra, datecs.
Ejemplo de uso:
ui.StartPrint "zebra"
En el caso de seleccionar el driver de la brother, podemos concatenar “$$” seguido del modelo de impresora. Si no se especifica, cargará el modelo PJ-662.
Ejemplo de uso:
ui.StartPrint "brother$$PJ-562"
Print (String stText)
Imprime la cadena que recibe por parámetro.
Si la impresión es correcta devuelve 0, en caso contrario un código de error.
PrintLine (String stText)
Imprime la cadena que recibe por parámetro y realiza un salto de línea.
Si la impresión es correcta devuelve 0, en caso contrario un código de error.
PrintCommand (String stText)
Imprime comandos específicos de la impresora, mediante la cadena que recibe por parámetro.
Si la impresión es correcta devuelve 0, en caso contrario un código de error.
- Para escribir texto normal y que el control los interprete como ASCII, sería:
COMANDO | SALIDA |
---|---|
appdata.userinterface.printcommand “##TEXT##hola 130 15 ##END_TEXT##“ | “hola 130 15 “ |
appdata.userinterface.printcommand “##TEXT##! 0 200 200 210 1##END_TEXT##“ | ”! 0 200 200 210 1” |
- Cualquier valor que vaya entre comas sin las macros anteriores, será interpretado como un valor ASCII:
COMANDO | SALIDA |
---|---|
appdata.userinterface.printcommand “32,35,104,111,108,97,10“ | ” #hola” (el codigo ascii 10 es un linefeed) |
appdata.userinterface.printcommand “32,35,##TEXT##hola##END_TEXT##,10“ | ” #hola” (este comando es idéntico al anterior) |
PrintPDF (String stRuta)
Sólo disponible usando el driver de impresión brother.
Imprime el archivo PDF especificado en el primer parámetro. Si solamente se especifica el nombre del fichero, lo buscará en la carpeta files de la aplicación.
PrintImage (String stRuta, int width, int height, String stAlign, int dither)
Sólo disponible usando los driver de impresión zebra, brother, datecs. Si el nombre del fichero acaba en _TEMP, lo borrará al imprimir.
Imprime una imagen.
Primer argumento | Ruta en la cual buscará el fichero imagen a imprimir. Acepta ficheros .gif, .png, .jpg, y .bmp. Puede ser una URL. |
Segundo argumento | Especifica el ancho de la imagen a imprimir. Si éste o el tercer argumentos son igual a cero, no se reescalará la imagen. |
Tercer argumento | Especifica el alto de la imagen a imprimir. Si éste o el segundo argumentos son igual a cero, no se reescalará la imagen. |
Cuarto argumento | Alineación. |
Quinto argumento | No implementado. Poner 0 en su lugar. |
Ejemplo: ui.printimage “logo.png”, “100”, “100”, “center”, “0”
LineFeed (int nSaltos)
Realiza tantos saltos de línea como se indiquen por parámetro.
No retorna nada.
SetFeedMode(String feedMode)
Sólo Android y sólo implementado en el driver de la Brother, por características de esta. Configura si al terminar de imprimir, saca todo el papel hasta el final de la página o se queda ahí.
Valores posibles | endofpage, free, endofpageretract, fixedmode. |
PrintBarcode()
Sólo Android. Imprime un código de barras o QRCode.
Códigos de barras soportados | codabar, code11, code128, code25, code39, code93, datamatrix, ean128, ean13, ean8, isbn, issn, itf14, identcode, interleaved2of5, leitcode, msi, onecode, pdf417, planet, postnet, rm4scc, upca, upce. |
Ejemplo de uso:
ui.PrintBarcode "ean128", "(00)350123451234567894" , "ancho", "alto"
Para QRCode:
ui.PrintBarcode "qrcode", "BIZCARD:N:Pepito;X:Grillo;T:Programador informático;C:CGSoft;A:Dirección;B:+34921212121;F:+34924242424;M:+34902002255;E:email@servidor.com;;" , "ancho", "alto"
EndPrint ()
Finaliza la conexión a la impresora y destruye el objeto.
En Android, espera unos 15-20 segundos aproximadamente a que la impresora termine antes de dar timeout.
Retorna: |
-2 si el tiempo de espera ha pasado |
-1 si ha habido algún error |
0 si todo ha ido correcto |
En ocasiones nos topamos con impresoras más lentas o en las que hay que cargar cada hoja manualmente, como la Brother PJ-662, y hay que darle más tiempo de espera. Para ello, podemos pasarle como argumento un entero que indica en segundos el tiempo de espera.
Si se le especifica -1 como argumento, esperará de manera infinita a que termine o ocurra un error.
Ejemplo de utilización #1
(ejemplo antiguo)
Para poder imprimir, primero es necesario llamar a la función startprint, indicando como parámetro cual de las entradas del fichero printer.bin vamos a usar.
StartPrint 0 | –> Usaría la 1ª entrada del fichero printer.bin |
StartPrint 1 | –> Usaría la 2ª entrada del fichero printer.bin |
y finalizar con endprint.
result = appdata.userinterface.StartPrint( numimpre ) If result = 0 Then appdata.userinterface.PrintCommand "27,45,48" appdata.userinterface.PrintCommand "27,53" appdata.userinterface.PrintLine "HOLA..." appdata.userinterface.Print "ADIOSSS...." appdata.userinterface.LineFeed 4 appdata.userinterface.EndPrint End If
Ejemplo de utilización #2
Este ejemplo se ha probado en Android con la impresora Zebra MZ 220. Tened en cuenta la limitación de 30 caracteres por línea.
'err = appdata.userinterface.MsgBox("Texto", "Mensaje", 1) 'El tope máximo es de 30 caracteres por línea o pasarán cosas raras 'Usar cstr 'Añadir +chr(13)+chr(10) al final de cada PrintLine 'imprimirLiquidacion() da el tiket entero 'imprimirFormateado() imprime dos cadenas, la segunda alineada a la derecha 'imprimirFormateadoDetalle() hace el formato especial para tres cadenas 'By Reaper function imprimirInformeBonificaciones() Dim nreg, filtro coddelegacion = appdata.getCollection("Delegaciones")("ID",user("IDDELEGACION"))("CODIGO") appdata.userinterface.StartPrint "zebra" imprimirNormal("******************************") imprimirNormal("* * INFORME * *") imprimirNormal("* * BONIFICACIONES * *") imprimirNormal("******************************") imprimirFormateado "DELEGACION: "+cstr(coddelegacion), cstr(day(Now()))+"/"+cstr(month(Now()))+"/"+cstr(year(Now())) imprimirNormal("OPERADOR: "+user("CODIGOTRABAJADOR")) imprimirNormal(user("NOMBRETRABAJADOR")) imprimirNormal(" "+chr(13)+chr(10)+" ") imprimirNormal("CLIENTE") imprimirNormal("TIPO CONCEPTO IMPORTE") imprimirNormal("---- -------- -------") cambio=1 total=0 'Imprimir bonificaciones Set objBonificaciones = appdata.getCollection("BonificacionesListadoImprimir") objBonificaciones.startBrowse while not objBonificaciones.currentItem is nothing set objCLI=objBonificaciones.currentItem a=objCLI("MAP_CLIENTE") if cambio=1 then imprimirNormal(" ") imprimirNormal(objBonificaciones.currentItem("MAP_CLIENTE") + " " + objBonificaciones.currentItem("MAP_CLIENTE1")) imprimirNormal(" ") end if aux = objBonificaciones.currentItem("MAP_IMPORTE") imprimirFormateadoInformeBonificaciones objBonificaciones.currentItem("MAP_CODIGOBONIFICACION"), objBonificaciones.currentItem("MAP_BONIFICACION1"), aux total = total + aux objBonificaciones.moveNext if not objBonificaciones.currentItem is nothing then if cstr(a)<>cstr(objBonificaciones.currentItem("MAP_CLIENTE")) then cambio=1 else cambio=0 end if end if wend objBonificaciones.endBrowse set objBonificaciones = nothing 'Fin bonificaciones imprimirNormal(" -------") imprimirNormal(" ") imprimirFormateado "Total bonificaciones:", total imprimirNormal(" "+chr(13)+chr(10)+" "+chr(13)+chr(10)+" "+chr(13)+chr(10)+" ") appdata.userinterface.EndPrint end function function imprimirNormal(txtimpr01) txtimpr01 = cstr(txtimpr01) while (len(txtimpr01) > 30) aux = Mid(txtimpr01, 31, len(txtimpr01)) txtimpr01 = Mid(txtimpr01, 1, 30) appdata.userinterface.PrintLine(txtimpr01+chr(13)+chr(10)) txtimpr01 = aux wend appdata.userinterface.PrintLine(txtimpr01+chr(13)+chr(10)) end function function imprimirFormateado(txtimpr01, txtimpr02) txtimpr01 = cstr(txtimpr01) txtimpr02 = cstr(txtimpr02) txtimpr03 = txtimpr01+txtimpr02 if(len(txtimpr03) < 30) then diferencia = 29 - len(txtimpr03) for i=0 to diferencia txtimpr01 = txtimpr01+" " next txtimpr03 = txtimpr01+txtimpr02 end if imprimirNormal(txtimpr03) end function function imprimirFormateadoDetalle(txtimpr02, txtimpr03, txtimpr04) txtimpr01 = "EUR " txtimpr02 = cstr(txtimpr02) txtimpr03 = cstr(txtimpr03) txtimpr04 = cstr(txtimpr04) if(len(txtimpr02) < 5) then diferencia = 4 - len(txtimpr02) for i=0 to diferencia txtimpr01 = txtimpr01+" " next end if txtimpr01 = txtimpr01+txtimpr02+" " if(len(txtimpr03) < 5) then diferencia = 5 - len(txtimpr03) for i=0 to diferencia txtimpr01 = txtimpr01+" " next end if txtimpr01 = txtimpr01+txtimpr03+" "+txtimpr04 imprimirNormal(txtimpr01) end function
Nótese que esta impresora no está homologada aún, y que la documentación indica que se requiere añadir un retorno de carro [chr(13)] y un salto de línea [chr(10)] a cada comando, y por ello creamos la función imprimirNormal, que también divide el texto en varias líneas si supera el límite de caracteres.
Hemos imprimido retornos y saltos de línea al principio y al final para más velocidad de impresión y para que dé espacio para poder arrancar el ticket sin cargárnoslo.
La función imprimirFormateado sirve para alinear a la derecha la segunda cadena a imprimir.
En cambio, imprimirFormateadoDetalle es específico para un proyecto anterior, pero el código es reutilizable para imprimir otro content que tenga varios campos.