Java e impressora matricial

Olá, amigos do GUJ !
Estou precisando desenvolver uma pequena aplicação para imprimir notas fiscais pela impressora matricial, porém não faço a mínima idéia de como fazer isso.
Já pesquisei aqui no GUJ e no Google, mas o que encontro não condiz com uma pessoa que esteja aprendendo a desenvolver esse tipo de aplicação, ou seja, começando do zero. Aqui no GUJ até encontrei um código pronto, mas o problema é entender como tal código funciona, o que faz cada linha do programa.
Também andei dando uma olhada em alguns tutoriais da SUN, mas são confusos e cada página que visito há uma infinidade de links adicionais. Com isso perco-me um pouco.
Alguém sabe onde posso encontrar um bom tutorial para conexão com a impressora matricial bem como um tutorial de como implementar esse programa de impressão de notas fiscais pela impressora matricial ? Pode ser apostila, link da web, até livro (nesse caso até prefiro, pois nos livros as coisas sempre vêm bem melhor explicadas, posso comprá-lo, se for o caso).

Desde já agradeço a ajuda.

Amigo, infelizmente não vou poder te ajudar com links… senão eu só iria pesquisar no Google, coisa que você já deve ter feito. rs
Mas posso lhe dizer que imprimir em uma impressora matricial é muito simples.
Basta você tratar como se estivesse escrevendo um arquivo de texto. O detalhe é que ao invés de especificar um caminho do sistema de arquivos, você especifica a porta da impressora (como a LPT1).
O próprio Java possui uma classe para isso, a PrintStream.

De maneira bem simples, isso imprimiria em uma impressora conectada à porta LPT1:

[code]try {
// Abre o Stream da impressora
FileOutputStream fos = new FileOutputStream(“LPT1”);
ps = new PrintStream(fos);

 // Imprime o texto
 ps.print("testando a impressao");

 // Quebra linha
 ps.print("\f");

 // Fecha o Stream da impressora
 ps.close();
 fos.close();

} catch (Exception ex) {
ex.printStackTrace();
}[/code]
Se quiser tentar e precisar de alguma ajuda, escreva.

Abraços,
Marcos Antonio Campos Jordão’’

Opa, Marco, que beleza !
Obrigadão pelo código ! Parece bem simples mesmo !
Mas o que vejo aí é que não há como posicionar o cursor da impressora em uma determinada coluna da linha, coisa necessária para se imprimir notas fiscais.
Vejo que há como quebrar a linha, mas como eu posiciono o cursor numa determinada posição da linha (coluna) ?
E outra coisa, andei lendo que vaira muito de impressora para impressora, por exemplo, a forma de impressão, formatação (tamanho do fonte, cor do fonte, etc…), variam de uma Epson para uma HP, por exemplo. Gostaria de saber como posso fazer isso. Acredito que numa nota fiscal há campos em que o tamanho do fonte seja diferente do tamanho do fonte de outro campo. Gostaria de saber isso também.
Se puder continuar ajudando, agradeço muito !
Quanto a testar o código, sim, irei testá-lo, mas antes preciso arrumar uma impressora matricial, mas isso eu dou um jeito.
Obrigado desde já.

Para “posicionar” o carro de impressão em uma coluna o método que eu uso é inserir espaços antes dos textos.
Precisei desses recursos justamente para impressão de Notas Fiscais (que aliás graças à Deus está sendo substituído pela NF-e).
Realmente como você disse há uma variação entre impressoras matriciais. O que mais percebi foi variação na “altura da linha”. Mas não é muita não.
Sua aplicação necessita ser utilizada por impressoras diferentes? Mas sempre matricial né?

Quando estava desenvolvendo essa impressão de Notas Fiscais, criei uma classe “genérica” para auxiliar a impressão.
Se quiser, posso lhe enviar o Código.

Mas uma coisa você não conseguirá escapar: testar muito até encontrar as posições corretas dos campos, de acordo com a impressora e principalmente de acordo com o formulário. É bem chatinho! rs

1 curtida

Ops, Legal, Marco, também tive essa idéia de inserir espaços em branco na linha até o carro chegar no lugar certo :lol:
E sei que é meio chato esse teste, já fiz isso quando estava aprendendo Clipper. tem que mandar a impressora imprimir x no formulário inteiro e ir contanto os espaços. Mjuito chato mesmo.
Se puder me enviar o código, agradeço muito mesmo ! Não tenho muita pressa para fazer isso, mas o quanto antes melhor.
Abraços !

Valder,

Segue duas classes.
Uma funciona como “auxiliar genérica” e a outra é uma implementação de impressão em uma LX300.
Acho que vai te ajudar.
Qualquer dúvida, escreva.

1 curtida

marco, mito obrigado pela tremenda ajuda que está me prestando, sou muito grato.
Arrumarei a impressora e começarei a fazer os testes.
Precisando de alguma coisa, envie mp ou poste aqui mesmo.
Valeu aí, rapaz !

Marco muito obrigado pela ajuda ai.
Seus códigos quebraram um galhão
Vlw

Marco na sua implementação vc nem usou o código esc-p da epson né?
Vc tem como explicar o código que vc fez do alinha esquedar, centro ,direita de como funciona.
Vc se basea em 80 colunas e vai imprimindo.
Se vc tiver como passar uma imagem da sua nota fical só pra eu ter uma ideia de como fica me ajudaria um pouco.
Obrigado

Usei o código Esc-P para imprimir em negrito (método “adicionarNegrito()”) e para dar um espaçamento na margem superior adequando ao formulário que eu deveria seguir (linha 2 do método “emitir()”).

Os métodos de alinhamento são bem simples.
Fiz um método auxiliar “getEspaco(int qtde)” que retorna a quantidade informada em espaços em branco.
No “alinharDireita()” e “alinharEsquerda()” eu pego o texto informado (parâmetro “String texto”) e completo com a quantidade de espaços necessária para que fique do tamanho informado (parametro “int tamanho”).
Segue com comentários:

[code]protected String alinharDireita(String texto, int tamanho) {
int diferenca;

  // Se o "texto" for null, retorna uma string com a quantidade de espaços de "tamanho"
  if (texto == null) {
	  return getEspaco(tamanho);
  } else {
          // Se o tamanho do "texto" já for maior que o "tamanho" especificado, corta a String pegando a parte da esquerda
      if (texto.length() > tamanho) {
          return texto.substring(0, tamanho);
      } else {
              // Acha a diferença entre o tamanho atual do "texto" e o "tamanho" informado
          diferenca = tamanho - texto.length();

              // Coloca a quantidade de espaços calculada como "diferenca" à esquerda e concatena o "texto" informado
          return getEspaco(diferenca) + texto;
      }
  }

}[/code]
O “alinharCentro()” só é diferente quanto ao cálculo para achar o centro. Ele calcula a diferença (espaços necessários para completar o “tamanho” informado) e divide essa diferença por 2, colocando metade dos espaços à esquerda e metade à direita.
Simples assim.

Agora a quantidade de quebra de linhas, quantidade de espaços, tudo isso você tem que ir testando e fazendo um “mapeamento” de como deve ser, de acordo com o formulário que tem que preencher. Pode por nisso vários formulários de teste. :slight_smile:

Infelizmente não tenho nenhum formulário digitalizado para enviar. Até porque a NF-e substituiu o que eu tinha implementado.
Fico devendo.

Abraços,
Marcos Antonio Campos Jordão’’

Olá, muito bom o seu código marcus.

Aqui está imprimindo, sendo que sem acentuação, como eu faço para conseguir imprimir com os acentos???

Obrigado desde já.

Vc tem que dizer pra impressora qual tabela de char vc quer usar.
Eu estou usando um impressora da epson e passa isso através dos comando ESC/P.
Muitas das coisas sobre este código peguei desta pagina
http://www.drayah.net/
Nesta página vc acha um biblioteca em java pronto com comando ESC/P
Existe também os manuais sobre os comandos esc/p
support.epson.ru/products/manuals/000350/part1.pdf
support.epson.ru/products/manuals/000351/part2.pdf
support.epson.ru/products/manuals/000352/part3.pdf
Espero que estas informações ajude vc.
Abraços

Olá Marcel,

Tentei entender como criar a classe ESCPrinter, mas não realidade não consegui entender nada, vc não teria como me mostrar algo prático???

Obrigado desde já pela atenção!!

Marcelo


package Utilities;

import Main.Nota_Fiscal;



public abstract class EmissorNotaFiscal {


	protected StringBuffer destino;

	public EmissorNotaFiscal(StringBuffer destino) {

		this.destino = destino;
	}

	/*** Métodos abstratos ***/
	public abstract void emitir(Nota_Fiscal nota);



	protected void adicionar(String texto) {
		this.destino.append(texto);
	}

	protected void darEspaco(int qtde) {
		this.destino.append(getEspaco(qtde));
	}

	

	protected void quebrarLinha(int qtde) {
		for (int x1 = 1; x1 <= qtde; x1++) {
			quebrarLinha();
		}
	}

	protected String getEspaco(int qtde) {
		String result = "";
		for (int x2 = 1; x2 <= qtde; x2++) {
			result += " ";
		}

		return result;
	}

    //negrito
    protected void adicionarNegrito(String texto) {
    
		adicionar(ESC + E + texto + ESC + F);

	}

    public void inic(){
        //reset default settings
        adicionar(ESC + AT);
    }

    //define tabela de caracteres
    
    public void setCharacterSet(String charset) {
        //assign character table
        adicionar(ESC + PARENTHESIS_LEFT + t + ARGUMENT_3 + ARGUMENT_0 + ARGUMENT_1 + charset + ARGUMENT_0);
        //adicionar("\u001B" + "(t" + (char)3 + (char)0 + (char)0 + (char)25 + (char)0);
        
        
        //select character table
        adicionar(ESC + t + ARGUMENT_1);
        //adicionar("\u001B" + "t" + (char)0);
        //Character.toString( ESC);
        
    }
    //pula linha
    public void quebrarLinha() {
          
        adicionar(CR + LINE_FEED);//according to epson esc/p ref. manual always send carriage return before line feed
    }

    /**
     * Ejeta folha
     */
    public void ejectFolha() {
        //post: ejects single sheet
        adicionar(CR + FF );
        
    }
    public void comecoPag(){
        adicionar(CR);
    }


    /**
     * pre: centimeters >= 0p
     * post: advances horizontal print position approx. centimeters
     * @param centimeters
     */
    public void avancaHorizontal(float cem) {
        //pre: centimeters >= 0
        //post: advances horizontal print position approx. centimeters
        float inches = cem / CM_PER_INCH;
        int units_low = (int) (inches * 120) % 256;
        int units_high = (int) (inches * 120) / 256;

        adicionar(ESC + BACKSLASH + (char) units_low + (char) units_high);

    }

    /**
     * pre: centimenters >= 0 (cm)
     * post: sets absolute horizontal print position to x centimeters from left margin
     * @param centimeters
     */
    public void avancaAbsHorizontal(float cem) {

        float inches = cem / CM_PER_INCH;
        int units_low = (int) (inches * 60) % 256;
        int units_high = (int) (inches * 60) / 256;

        adicionar(ESC + $ + (char) units_low + (char) units_high);

    }

    public void avancaVertical(float cem) {
        /*
        float inches = cem*256 / CM_PER_INCH;
        adicionar(ESC + J + (char) inches);
         * */
        //pre: centimeters >= 0 (cm)
        //post: advances vertical print position approx. y centimeters (not precise due to truncation)
        float inches = cem / CM_PER_INCH;
        int units = (int) (inches * 216);

        while (units > 0) {
            char n;
            if (units > MAX_UNITS)
                n = (char) MAX_UNITS; //want to move more than range of parameter allows (0 - 255) so move max amount
            else
                n = (char) units; //want to move a distance which fits in range of parameter (0 - 255)

           adicionar(ESC + J + (char) n);

           units -= MAX_UNITS;
        }

    }

    /**
     * //pre: tabs >= 0
     * //post: performs horizontal tabs tabs number of times
     * @param tabs
     */
    public void horizontalTab(int tabs) {
        //pre: tabs >= 0
        //post: performs horizontal tabs tabs number of times
        for (int i = 0; i < tabs; i++)
            adicionar(TAB+"");
    }

    /**
     * pre: columnsLeft > 0 && <= 255, columnsRight > 0 && <= 255
     * post: sets left margin to columnsLeft columns and right margin to columnsRight columns
     * @param columnsLeft
     * @param columnsRight
     */
    public void setMargem(int colunaEsq, int colunaDir) {
        //esquerda
        adicionar(ESC + l + (char) colunaEsq);

        //direita
        adicionar(ESC + Q + (char) colunaDir);
    }


    /**
     * This command sets the page length in 1-inch increments only.
     * Set the page length before paper is loaded or when the print position is at the top-ofform
     * position. Otherwise, the current print position becomes the top-of-form position.
     * Setting the page length cancels the top and bottom-margin settings.
     * @param tam
     */
    public void setTamPag(float tam){
        float inches = tam / CM_PER_INCH;
        adicionar(ESC + C + NULL+ (char) inches);
    }
    /**
     * ESC k 0 -Roman
     * ESC k 1 -Sans serif
     * @param fonte
     */
    public void setFonte(int fonte){
        adicionar(ESC + k + (char) fonte);
    }

    public void setCondensado(){
         adicionar(SI);
    }

    public void setRascunho() { //set draft quality printing
        adicionar(ESC+ x +(char) 48);
    }

    public void setLQ() { //set letter quality printing
        adicionar(ESC+ x +(char) 49);
    }
    public void set10CPI() { //10 characters per inch (condensed available)
        adicionar(ESC+ P);
    }

    
    
    private static int MAX_UNITS = 127; //for vertical positioning range is between 0 - 255 (0 <= n <= 255) according to epson ref. but 255 gives weird errors at 1.5f, 127 as max (0 - 128) seems to be working
    private static final float CM_PER_INCH = 2.54f;

    /* decimal ascii values for epson ESC/P commands */
    
    private static final String ESC = "\u001B"; //escape
    private static final String AT =(char) 64+""; //@
    private static final String LINE_FEED = (char) 10+""; //line feed/new line
    private static final String PARENTHESIS_LEFT = (char)40+"";
    private static final String BACKSLASH = (char)92+"";
    private static final String CR = (char)13+""; //carriage return
    private static final String TAB = (char)9+""; //horizontal tab
    private static final String FF = (char)12+""; //form feed
    private static final String SI = (char)15+""; //condense
    private static final String g = (char)103+""; //15cpi pitch
    private static final String p = (char)112+""; //used for choosing proportional mode or fixed-pitch
    private static final String t = (char)116+""; //used for Stringacter set assignment/selection
    private static final String k = (char)107+""; //used for font
    private static final String l = (char)108+""; //used for setting left margin
    private static final String x = (char)120+""; //used for setting draft or letter quality (LQ) printing
    private static final String C = (char)67+""; //used for page lenght
    private static final String E = (char)69+""; //bold font on
    private static final String F = (char)70+""; //bold font off
    private static final String J = (char)74+""; //used for advancing paper vertically
    private static final String P = (char)80+""; //10cpi pitch
    private static final String Q = (char)81+""; //used for setting right margin
    private static final String NULL = (char)0 +""; //used for setting right margin

    private static final String $ = (char)36+""; //used for absolute horizontal positioning
    private static final String ARGUMENT_0 = (char)0+"";
    private static final String ARGUMENT_1 = (char)1+"";
    private static final String ARGUMENT_2 = (char)2+"";
    private static final String ARGUMENT_3 = (char)3+"";
    private static final String ARGUMENT_4 = (char)4+"";
    private static final String ARGUMENT_5 = (char)5+"";
    private static final String ARGUMENT_6 = (char)6+"";
    private static final String ARGUMENT_7 = (char)7+"";
    private static final String ARGUMENT_25 = (char)25+"";

    /* Stringacter sets */
    public static final String USA = ARGUMENT_1;
    public static final String BRAZIL = ARGUMENT_25;

    

}

Este código foi adaptado daquele biblioteca que eu passei e foi adaptado e usado como o marco utiliza no código dele

[quote=raci0nal]Valder,

Segue duas classes.
Uma funciona como “auxiliar genérica” e a outra é uma implementação de impressão em uma LX300.
Acho que vai te ajudar.
Qualquer dúvida, escreva.
[/quote]
Bom dia!
como eu posso adaptar essa sua classe para imprimir contra-cheques? Se tiver como você me dar uma ajuda ficarei grato.