[RESOLVIDO]Imprimindo Bematech Não Fiscal USB Java (uso do modelo: MP-4200TH)

Boa tarde pessoal.

Estou utilizando para testes o modelo MP-4200TH da Bematech devidamente instalada em uma porta USB do meu computador.
A instalação, pra quem precisar, encontrei numa página da própria Bematech:clique aqui!

Bom, depois de instalada, mesmo ela sendo USB, o trabalho é como se ela fosse uma impressora serial normal.
Para uso no Java, ou melhor, para imprimir no java uso a estrutura abaixo.
Pra quem quiser usar… fica a vontade.

Primeiro eu listo todas as impressoras instaladas no computador. Monto esse List em um JComboBox numa tela de configuração.
E salvo o nome da impressora nas configurações no sistema (pode ser numa tabela de banco de dados ou até mesmo num arquivo .txt)

public static List<String> retornaImressoras(){
        try {
            List<String> listaImpressoras = new ArrayList<>();
            DocFlavor df = DocFlavor.SERVICE_FORMATTED.PRINTABLE;  
            PrintService[] ps = PrintServiceLookup.lookupPrintServices(df, null);  
            for (PrintService p : ps) {  
                listaImpressoras.add(p.getName());     
            }  
            return listaImpressoras;
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return null;
    }

Depois, antes de imprimir, é feita uma detecção da impressora. Essa parte, é salvo uma referência a ela num atributo de nome impressora.

private static PrintService impressora; // O Atributo citado anteriormente

public void detectaImpressoras(String impressoraSelecionada) {  //Passa por parâmetro o nome salvo da impressora
        try {  
            DocFlavor df = DocFlavor.SERVICE_FORMATTED.PRINTABLE;  
            PrintService[] ps = PrintServiceLookup.lookupPrintServices(df, null);  
            for (PrintService p : ps) {  
                if(p.getName()!=null && p.getName().contains(impressoraSelecionada)){  
                    impressora = p;  
                }     
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }

Próximo passo, é a impressão. Super simples o método. Você passa por parâmetro o que quer imprimir.

public  boolean imprime(String texto) {  
  
        if (impressora == null) {  
            JOptionPane.showMessageDialog(null, "Nennhuma impressora foi encontrada. Instale uma impressora padrão \r\n(Generic Text Only) e reinicie o programa."); 
        } else {  
            try {  
                DocPrintJob dpj = impressora.createPrintJob();  
                InputStream stream = new ByteArrayInputStream((texto + "\n").getBytes());  
                DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;  
                Doc doc = new SimpleDoc(stream, flavor, null);  
                dpj.print(doc, null);  
                return true;  
            } catch (PrintException e) {  
                e.printStackTrace();  
            }  
        }  
        return false;  
    }

Aí chega a minha dúvida. Espero que alguém já tenha passado por isso.
Fiz um método que concatena alguns caracteres para que a impressora execute algumas ações. Como cortar o papel, imprimir em negrito, itálico e etc.
Para a guilhotina eu consegui fazer.

public void acionarGuilhotina(){
        imprime(""+(char)27+(char)109);
    }

Alguém sabe a combinação para se fazer o negrito e as outras opções de formatação de texto?

Vou continuar a pesquisa, quando eu encontrar, volto aqui e fecho o tópico e adiciono como eu fiz.
Do mais, fica a dica de como imprimir.
Abraço!

veja se isso lhe ajuda, aqui comigo funciona,

    /*
     * decimal ascii values for epson ESC/P commands
     */
    private static final char ESC = 27; //escape
    private static final char AT = 64; //@
    private static final char LINE_FEED = 10; //line feed/new line
    private static final char PARENTHESIS_LEFT = 40;
    private static final char BACKSLASH = 92;
    private static final char CR = 13; //carriage return
    private static final char TAB = 9; //horizontal tab
    private static final char FF = 12; //form feed
    private static final char P = 80; //10cpi pitch
    private static final char M = 77; //12cpi pitch
    private static final char g = 103; //15cpi pitch
    private static final char p = 112; //used for choosing proportional mode or fixed-pitch
    private static final char t = 116; //used for character set assignment/selection
    private static final char l = 108; //used for setting left margin
    private static final char x = 120; //used for setting draft or letter quality (LQ) printing
    private static final char E = 69; //bold font on
    private static final char F = 70; //bold font off
    private static final char J = 74; //used for advancing paper vertically
    private static final char Q = 81; //used for setting right margin
    private static final char $ = 36; //used for absolute horizontal positioning
    public static final char ITALIC_ON = 52; //set font italic
    public static final char ITALIC_OFF = 53; //unset font italic
    public static final char CONDENSED_ON = 15;
    public static final char CONDENSED_OFF = 18;

Olá, bom dia.

Pode até ser que me ajude. Problema mesmo é como eu consigo montar isso numa String para enviar p/ a impressora.
Na Epson, você sabe como envia?

Cara muito boa a sua dica, estava pensando aqui como fazer, a dicas dos comandos é essa:
Liguei para a assistência da bematech 08006447277 e eles me passaram esses comandos para condensado e negrito
29 + 249+32+0+27+116+8+ 15 (texto)+18
o 15 é condensado e o 18 encerra

O suporte deles é bem legal.
Consegui várias informações de como imprimir coisas na mini-impressora.
Consegui inclusive como imprimir código de barras.
Segue código:

String tipo = ("" + (char) 29 + (char) 107 + (char) 73 + (char) 28);//Cod 128 - tipo código barras

Depois você junta isso com o código de barras em sí e finaliza com um \n pra poder imprimir.

oi, sou novo por aqui, estou tendo problema pra conseguir realizar a impressão nela, quando eu mando um texto para ela que contenha caractere especial ela até imprime o caractere, mas antecedido por um simbolo parecido com T minusculo, ex: quero imprimir a letra ç, mando pra ela “”+(char)135, ela imprime Tç, ela está com a configuração default dela (tabela de códigos 850), estou usando esse mesmo código que o Marcos Roberto da Fonseca postou, a propósito, obrigado pela postagem do código, ajudou muito ^^

Quando eu quero imprimir está me retornando o seguinte erro:

sun.print.PrintJobFlavorException: invalid flavor
at sun.print.UnixPrintJob.print(UnixPrintJob.java:313)
at test.Impresora.imprime(Impresora.java:42)
at test.Main.main(Main.java:23)

Se eu verificar as DocFlavors suportados pela impressora retorna me nulo.

Eu entendo que este post é antigo, mas se alguém puder me ajudar eu agradeço muito.

Também estou precisando reviver o tópico, a função PrintServiceLookup.lookupPrintServices(df, null); não lista a minha impressora instalada na porta serial. Caso tenha resolvido pode me ajudar?

Que isso amigo!
E quanto a acentuação, eu nunca consegui fazer funcionar direito. A conclusão foi: criar um método que remove acentos e demais caracteres especiais e passar as Strings que serão impressas por teste método antes.

public static String removeAcentos(String str) { CharSequence cs = new StringBuilder(str == null ? "" : str); return Normalizer.normalize(cs, Normalizer.Form.NFKD).replaceAll("\\p{InCombiningDiacriticalMarks}+", ""); }

Olá amigos! Estou desenvolvendo uma aplicação WEB que dentre suas funcionalidades tenho que imprimir um boleto diretamente em uma impressora não fiscal da Bematech (MP 4200 - TH) e usando as dicas do Marcos Roberto consegui implementar as rotinas e identificar as impressoras no meu ambiente. Quando subi a aplicação para o provedor (Kinghost) a mesma rotina não funciona, pois acredito que esteja tentando identificar as impressoras que estão instalados no servidor, ou seja, não retorna nada. Não dá erro, mas não consigo enxergar as impressoras do usuário.
Como proceder para identificar as impressoras via WEB no client do usuário?

Olá!
Quanto a WEB, amigo, creio que esteja se comportando assim pelo fato mesmo, de estar procurando no servidor, porque a aplicação é executada lá no servidor.
A solução, poderia ser usando java applet.
Eu nunca tive a oportunidade de fazer uso, também não sei se ainda está em vigor nas versões atuais do java. Sempre ouvi dizer que o problema era com relação a não ser tão estável.

A saí pra isto: porque você não cria um relatório Jaspereport comum no lugar de imprimir em modo texto? Daí no report seu você reconfigura a largura do relatório, ao invés de 21,0cm pra 80mm.

Não sei se consegui ser claro, mas se ainda restar dúvidas, é só perguntar aqui que eu respondo amanhã!
Forte abraço!

Olá Marcos! Obrigado pela resposta. Vou tentar esta solução em ireport. Atualmente já faço uso em outros relatórios, mas por gerarem em PDF e depender de uma ação do usuário para envio para a impressora, achei que deveria tentar alguma coisa mais direta que automaticamente emitisse na impressora. Vou ver se tem algum jeito de eliminar esta ação do usuário e enviar pelo ireport direto para a impressora. Se tiver alguma dica sobre isto agradeço. Mais uma vez, obrigado pela ajuda!

Amigo, estou tentando imprimir codigo da barras a dias…peguei o seu exemplo mas não consegui implementá-lo, como que seria a junção do codigo de barras em si? é o texto que será impresso?

Boa tarde.
Pra código de barras, faço assim:

String tipo = ("" + (char) 29 + (char) 107 + (char) 73 + (char) 28);//Cod 128 - tipo código barras String codigoBarra = config + SEU_CODIGO_BARRA + (char) 0+ "\n";

Você abre com o char 29, 107, 73 e 28, concatena com seu código de barra, depois + char 8 e um \n pra imprimir.

Oi, pessoal.

Estou tentando fazer uma impressão na mesma impressora: Bematech 4200.

Segui o passo a passo, consigo listar a impressora, mas não imprime, nem da erro.

Será que alguém consegue me ajudar com essa?

Muito obrigado!

Opa. Funcionou!

Tirei e coloquei o cabo serial e funcionou.

Só não consegui fazer o corte adicionando esse (char)27+(char)109… =/

Mas não existe uma outra forma de fazer isso? Só por meio dessa função, ter que aplicar ela no código e depois sair testando recibos se o sistema é grande ou coisa do tipo fica enviável, não teria como configurar diretamente na impressora bematech?