Impressão cupom não fiscal?

Como posso fazer impressão de um cupom não fiscal no java? Considerando que o cliente pode ter uma Bematech, Daruma, ou até mesmo uma matricial antiga LPT1.

Fazendo um relatório no IReport configurando o tamanho da bobina dá certo?

Qual a melhor forma de se fazer isso?

Deixa eu adivinhar. Você esta trabalhando com SAT! se for, o Extrato do CF-e-SAT não pode ser impresso em impressora matricial porque ela não imprime o qrcode. aqui eu fiz esta impressão verificando pelo registro do windows e o wmic par descobrir qual a impressora, e depois carregar as dll da impressora para poder imprimir pelo JNA. Se você for usar a solução de imprimir direto pela dll, tem exemplos no dite das duas fabricantes que você mencionou, mas em cada uma, os comandos e a quantidade de colunas são diferentes.

Entendi, e criando um relatório no IReport com o tamanho da bobina e enviando para a impressora funciona? E como posso identificar qual modelo de impressora está instalada na máquina?

Eu estou com a mesma duvida, porém cheguei a resolução de deixar que o Windows se encarregue de fazer a impressão só passando qual impressora vou usar, pois nesta situação independente de qual impressora modelo ou marca o cliente use não preciso criar N funções para todas as marcas.

Mas e as DLLs que são diferentes dependendo da marca?

Então pensei no meu caso fazer a instalação como uma impressora do Windows normal, e depois usar a biblioteca de impressão para enviar o impresso pra ela, mas estou me deparando com o problema de configurar as dimensões do impresso.

Claytonquintiliano, eu tinha testado isso aqui, mas não deu muito certo não, eu não consegui pelo spoiler do windows descobrir a quantidade de colunas da impressora e também não consegui fazer a Bemtatech imprimir o qrcode pelo spoiler do windows, somente a Daruma. Você consegui fazer isso pelo spoiler do windows? ou o usuário informa qual impressora esta usando? você testou isso com impressoras de diversos fabricantes?

Murilo, na realidade a impressão do SAT eu já faço pelo spoiler do Windows já testei com os 2 modelos da Bematech e com impressoras da Sweda acredito que com as Darumas e outras não devo ter problemas.
Porém na forma que fiz ao realizar a impressão abre a tela de impressão do windows para selecionar a mesma e isso que gostaria de retirar mas sem sucesso, dai no caso estou pensando em mudar a forma com que faço a impressão. E as dimensões da impressão eu faço pelo Graphics do Java.

Poderiam me dar um exemplo de como faço isso?

Rodrigo, espera só um pouquinho para descurtirmos qual a melhor forma de fazer esta comunicação.

Então cara, é que to boiando, nunca trabalhei com impressão nessas impressoras não fiscal de bobina.
O certo seria eu fazer tipo um arquivo de configuração para configurar a impressora que está instalada e fazer a programação para cada tipo de marca de impressora?

Claytonquintiliano, tive uma outra aplicação a uns anos atrás que imprimia em uma folha A4, o usuário só selecionava em uma combobox a impressora que ele queria uma vez e eu guardava o nome da impressora em arquivo.

O modo como você manda para o Windows é parecido com isso?

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;

/**
 * @author Murilo de Mello P. Oliveira
 */
public class ImpressoraGUJ {

    public static void main(String[] args) {
        String nomeImpressoras[] = listaImpressora();
        for (String nome : nomeImpressoras) {
            System.out.println(nome);
        }
        PrintService impress = selectImpress(nomeImpressoras[0]); // neste caso a primeira
        if (imprimir(impress, "Meu cupom!!!")) {
            System.out.println("impresso com sucesso!");
        }
    }

    public static String[] listaImpressora() {
        PrintService[] ps = PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.AUTOSENSE, null);
        String[] nomes = new String[ps.length];
        for (int i = 0, l = nomes.length; i < l; i++) {
            nomes[i] = ps[i].getName();
        }
        return nomes;
    }

    private static PrintService selectImpress(String imp) {
        PrintService[] ps = PrintServiceLookup.lookupPrintServices(
                DocFlavor.INPUT_STREAM.AUTOSENSE, null);
        for (PrintService p : ps) {
            if (p.getName().equals(imp)) {
                return p;
            }
        }
        return null;
    }

    private static boolean imprimir(PrintService impressora, String texto) {
        try {
            DocPrintJob dpj = impressora.createPrintJob();
            InputStream is = new ByteArrayInputStream(texto.getBytes());
            SimpleDoc sd = new SimpleDoc(is, DocFlavor.INPUT_STREAM.AUTOSENSE,
                    null);
            dpj.print(sd, null);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

}

A forma com que eu faço é a seguinte:

Tenho o seguinte método

imprimir.java

   ........
   public void imprimir(String paramentro1, String parametro2) {

   
    // cria um frame temporário, onde será  desenhado  o texto a ser impresso       
    Frame f = new Frame("Frame temporário");
    f.setSize((int) 283.46, 500);
    f.pack();

    // pega o Toolkit do Frame       
    Toolkit tk = f.getToolkit();

    // Pega os serviços de impressão existentes no computador,       
    // para que seja escolhida uma impressora.      
    // Também pode ser uma impressora de rede     
     PrintJob pj = tk.getPrintJob(f, "IMPRESSAO", null);
    // Aqui se inicia a impressão     
     if (tk != null) {
    Graphics g = pj.getGraphics();
   // Graphics g = null;

    g.setFont(new Font("Arial", Font.PLAIN, 9));//Define o tipo da fonte e o tamanho  

    g.drawString("Parametro:" + parametro1, 0, 10);

    g.drawString("Parametro:" + parametro2, 0, 20);

     // libera os recursos gráficos      
    g.dispose();

     // encerra a impressão      
     pj.end();

     f.dispose();
     }
     ....

Dai no caso ao final deste processo o Windows pergunta qual impressora quer usar.

Dai no caso o QRCODE eu gero uma imagem e depois coloco a imagem no frame que gerei acima.

Usando relatório do IReport como mencionei dá certo?

É realmente, e chato a cada impressão selecionar a impressora, mas acho que tem como contornar isso, não esta 100% até mesmo porque eu não estou com uma impressora Bematech aqui para testar, mas acho que assim (com poucas alterações), será possível imprimir sem ter que selecionar a impressora toda vez.

public class ImpreByGUJ {

    public static void main(String[] args) {
        String[] impressoras = listaImpressora();
        System.out.println("Selecione a impressora");
        for (String imp : impressoras) {
            System.out.println(imp);
        }
        System.out.println("informe o indice da impressora");
        String impressSelec = impressoras[2];
        System.out.println(impressSelec);
        ImpreByGUJ ibguj = new ImpreByGUJ();
        ibguj.imprimir("Ola", "Mundo", impressSelec);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
        }
        ibguj.imprimir("Ola", "novamente", impressSelec);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
        }
        ibguj.imprimir("nao", "abra selecao", impressSelec);
    }

    public Rectangle r = null;

    public void imprimir(String paramentro1, String parametro2, String impressNome) {
        Frame f = new Frame("Frame temporário");
        f.setSize((int) 283.46, 500);
        f.pack();
        Toolkit tk = f.getToolkit();
        if (tk != null) {

            if (r == null) {
                PrintJob pj = tk.getPrintJob(f, "IMPRESSAO", null);
                sun.print.PrintJob2D pjd = (sun.print.PrintJob2D) pj;
                Graphics g = pj.getGraphics();
                r = g.getClipBounds();
                pj.end();
            }
            BufferedImage bImage = new BufferedImage(r.width, r.width,
                    BufferedImage.TYPE_INT_RGB);
            sun.print.ProxyPrintGraphics ppg = new sun.print.ProxyPrintGraphics(bImage.getGraphics(), new sun.print.PrintJob2D(f, "temp2", null));

            ppg.setFont(new Font("Arial", Font.PLAIN, 9));//Define o tipo da fonte e o tamanho  
            ppg.drawString("Parametro:" + paramentro1, 0, 10);
            ppg.drawString("Parametro:" + parametro2, 0, 20);
            ppg.dispose();
            PrintService ps = selectImpress(impressNome);
            DocPrintJob dpj = ps.createPrintJob();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            try {
                ImageIO.write(bImage, "png", baos);

            } catch (IOException ex) {
                ex.printStackTrace();
            }
            SimpleDoc dimpDoc = new SimpleDoc(baos.toByteArray(), DocFlavor.BYTE_ARRAY.PNG, null);
            try {
                dpj.print(dimpDoc, null);

                System.out.println("imprimiu");
            } catch (PrintException ex) {
                System.out.println("Erro");
            }
            f.dispose();
        }
    }

    public static PrintService selectImpress(String imp) {
        PrintService[] ps = PrintServiceLookup.lookupPrintServices(
                DocFlavor.INPUT_STREAM.AUTOSENSE, null);
        for (PrintService p : ps) {
            if (p.getName().equals(imp)) {
                return p;
            }
        }
        return null;
    }

    public static String[] listaImpressora() {
        PrintService[] ps = PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.AUTOSENSE, null);
        String[] nomes = new String[ps.length];
        for (int i = 0, l = nomes.length; i < l; i++) {
            nomes[i] = ps[i].getName();
        }
        return nomes;
    }

}

Rodrigo, utilizando o IReport você terá que fazer a saída e depois fazer a leitura desta saída para uma forma de imprimir, já pensei em fazer desta porém não achei muito conveniente pois ia gerar um pdf ou alguma outra extensão em um diretório e depois fazer a leitura deste arquivo para imprimir, no caso vão ser 2 trabalhos que você pode limitar a 1 só.