Impressão de Notas Fiscais e Ordens de Serviço

Boas.
Estou desenvolvendo um sistema utilizando swing, num ambiente multiplataforma (windows / linux). Funciona em cliente/servidor e tem uma base de dados mysql.
Bem… tô precisando fazer impressão de Notas Fiscais e de Ordens de serviço. Ambas as impressões são feitas em impressoras matriciais.
Os dados virão do BD e deverão ser impressos nos campos de um formulário q já existe, feito em gráfica.
eu sinceramente faria como nos tempo do DOS (type xxx.txt > lpt1), mas nem isso sei fazer.

Agradeço muito se alguém puder ajudar aê, galera.

Vlw… []'s

Pow, vc terá que acessar a porta paralela dasua impressora…
Faça em C/C++…

* 

* example.c: Exemplo de como acessar a porta paralela 

* 

* Esse código basicamente escreve na porta paralela e lê dados 

* da porta paralela. OBS: Rode o programa como root 

*/ 


#include <stdio.h> 

#include <unistd.h> 

#include <asm/io.h> 


#define BASEPORT 0x378 /* lp1 */ 


int main() 

{ 

/* Setando a permissão para o acesso das portas */ 

if (ioperm(BASEPORT, 3, 1)) {perror("ioperm"); exit(1);} 



/* Resetando todos os pinos de dados da porta paralela*/ 

outb(0, BASEPORT); 



/* NOP por 1 segundo */ 

sleep(1); 



/* Lê a porta de status (BASE+1) e mostra o resultado na tela */ 

printf("status: %d\n", inb(BASEPORT + 1)); 


/* Liberando as portas */ 

if (ioperm(BASEPORT, 3, 0)) {perror("ioperm"); exit(1);} 


exit(0); 

} 


/* Fim do example.c */ 

IOPERM 

int ioperm(unsigned long from, unsigned long num, int turn_on) 

Ioperm seta a permissão de acesso de portas para “num” portas começando a partir do endereço da porta (“from”) para o valor “turn_on” (“1” para habilitar, “0” para desabilitar). Por exemplo ioperm(0x300,5,1) possibilitará o acesso das portas 0x300 a 0x304. O uso dessa função necessita de privilégios de administrador. Apenas as primeiras 0x3FF portas I/O podem ser liberadas dessa maneira. 

INB 

inb(unsigned long porta) 

Para receber dados das portas, utiliza-se a função inb que retorna o byte lido na porta. 

OUTB 

outb(unsigned long valor, unsigned long porta) 

Para enviar bytes para as portas utiliza-se o comando outb que envia o byte “valor” para a “porta” correspondente. 

SLEEP 

sleep(int tempo) 

Interrompe a execução do programa por um número de segundos igual ao valor “tempo”. 


APÊNDICE II – PINAGEM DA PORTA PARALELA 



Descrição das portas 

Porta de Dados (0x378) 

A porta de dados corresponde aos bits de saída de dados D0 a D7. 

Porta de Status (0x379) 

A porta de status é utilizada apenas para entrada e retorna o estado dos seguintes sinais: 

Bits 0, 1 e 2: Reservados 
Bit 3: Error 
Bit 4: Select 
Bit 5: Paper End 
Bit 6: Acknowledgement 
Bit 7: Busy (invertido) 
Porta de Controle (0x37A) 

A porta de controle é utilizada apenas para saída e controla os seguintes sinais: 

Bit 0: Strobe (invertido) 
Bit 1: Auto Feed (invertido) 
Bit 2: Init 
Bit 3: Select In (invertido) 
Bits 4, 5, 6 e 7: Reservados 
Descrição dos pinos 

Strobe (saída) 

O strobe line é o pino principal da porta paralela. Ela é responsável por avisar a impressora quando as infomações podem ser lidas na porta. Geralmente quando ela está em nível alto quando não existe a necessidade de transmissão e ela é zerada a informação já estão na porta de dados, prontas para serem transmitidas para a impressora. Sincronismo é fundamental aqui. Quando o pino de strobe é setado/zerado a informação deve estar estável nos pinos de dados. Numa impressora por exemplo, o tempo necessário para cada byte se estabilizar na porta é de cerca de meio microsegundo, após o strobe é zerado por cerca de 1 microsegundo logo após o strobe é setado novamente. Os dados ainda continuam nos pinos por cerca de meio microsegundo após o strobe ser setado. Portanto o tempo total para se transmitir um byte para porta paralela é por volta de 2 microsegundos. 

Data (saída) 

Esses 8 pinos carregam a informação a ser impressa e outros parâmetros como por exemplo, se o texto é negrito ou itálico. As informações aqui trafegam somente do computador para a o dispositivo que está conectado a porata paralela. Esse pinos funcionam com pradrões TTL. 

Acknowledge (entrada) 
Este pino é usado como uma confirmação de dados recebidos. Ele é normalmente está em nível alto e é zerado quando a informação foi recebida com sucesso, deixando o dispositivo pronto para a próxima informação. 

Busy (entrada) 
Como a transferencia de dados pela porta paralela pode acontecer numa taxa no qual a impressão não pode acompanhar existe a necessidade de haver meio que a impressora possa avisar o computador que a impressão ainda está sendo executada. Cada vez que que a impressora recebe um byte, ela seta o pino de busy, avisando assim o computador para parar a transmissão de dados. Quando o pino volta novamente para zero o próximo byte é enviado. 




Paper Out (entrada) 
Quando o papel acaba na impressora, esse pino junto com o de busy line são setados pela a impressora e computador imediatamente para a transmissão. Sem esse pino não haveria um modo de o computador ser informado da falta de papel na impressora. 

Select (entrada) 
Essa linha permite o computador ser informado se há algum dispositivo conectado ao computador. Quando o pino esta setado o dispositivo está online pronto para ser usado. Caso contrário o dispositivo não está pronto e nenhum byte será transmitido. 



Auto Feed (saída) 

Nem todas as impressoras tratam o retorno de carro da mesma maneira. Algumas apenas irá ir pra o começo da próxima linha e outras além disso também tem a necessidade de avançar o papel uma linha abaixo. O pino de AutoFeed permite que o software faça isso pela a impressora. Quando o sinal está resetado a impressora irá acrescentar uma linha quando houver um retorno de carro. Quando o sinal está setado o software tem que mandar um sinal de line feed junto com o retorno de carro para obter o mesmo efeito. 

Error (entrada) 

Este é um pino de erro geral. Não existe maneira de se identificar qual o tipo de erro. Quando nenhum erro é detectado, o pino esta setado. Quando um erro é detectado o pino é resetado. Alguns erros possíveis são: tampa da impressora aberta, cabeçote da impressora emperrado. 


Initialize Printer (saída) 

Esse pino é utilizado para reiniciar a impressora. Para isso o computador apenas reseta o pino. 

Select Input (saída) 

Permite o acionamento da impressora a partir do computador. 

Ground 

Terra (Referência nível 0). 

Fonte:
http://www.pcs.usp.br/~jkinoshi/2005/exp2eduardo.doc

pensei nisso, mas aí vou cair em problemas de portabilidade, né?
eu preferiria utilizar msm java… senão vou precisar de uma versão do sistema pra cada plataforma.
vlw
[]'s

Também estou precisando fazer isso.

Será que não tem como fazer com Java?
Conseguiu resolver teu problema?

pow… aê: resolvi sim…
desculpa aê galera num ter postado a solução antes…

public class ImprimeNF extends JPanel implements Printable{
    NotaFiscal nf01;
    public ImprimeNF(NotaFiscal nf01){
        this.nf01 = nf01;
        
        JFrame f = new JFrame();
        f.getContentPane().add(this);
        Paper papel1 = new Paper();
        try{
            
            Double width = new Double(609.44);
            Double height = new Double(892.91);
            papel1.setSize(width, height);
            papel1.setImageableArea(0, 0, width, height);
            PageFormat pf = new PageFormat();
            pf.setPaper(papel1);
            PrinterJob printJob = PrinterJob.getPrinterJob();
            printJob.setPrintable(this, pf);
            if (printJob.printDialog()) {
                try {
                    printJob.print();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        } catch(Exception e){e.printStackTrace();}
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        escreve((Graphics2D) g);
    }
    
    public int print(Graphics g, PageFormat pf, int pi) throws PrinterException {
        if (pi >= 1) {
            return Printable.NO_SUCH_PAGE;
        }
        escreve((Graphics2D) g);
        return Printable.PAGE_EXISTS;
    }

    private void escreve(Graphics2D g){
        DecimalFormat formatador  = new DecimalFormat();
y=100;
        // Imprimir Razão Social
        g.drawString(nf01.getRazaoSocial(), 25, y);
        // Imprimir CNPJ
        g.drawString(nf01.getCnpj(), 380, y);
        // Imprimir Data de emissão
        g.drawString(formatoBR.format(nf01.getDataEmissao()), 530, y);
y=200;
...
...
        g.dispose();
    }
}

Essa aí acima foi uma das soluções que encontrei.
A outra:

public class ImprimePedido {
    private void EmitePedido(){ 
        Frame f = new Frame();
        f.pack();
        Toolkit tk = f.getToolkit();
        PrintJob pj = tk.getPrintJob(f, "Pedido", null);
        if (pj!=null) {
            Graphics g = pj.getGraphics();
            g.setFont(new Font("Dialog",Font.BOLD, 12));
            formatador.applyPattern("00000");
            g.drawString("Pedido número: " + pedidoNumero, 25, 50);
            g.drawString(razaoSocial, 25, 65);
            g.drawString("Dt. pedido: " + dataPedido, 420, 50);
            g.drawString("Dt. entrega: " + dataEntrega, 420, 65);
            g.drawString("Observação: " + observacao, 25, 80);
            g.drawLine(25, 85, 550, 85);
            g.dispose();
            pj.end();
        }
        f.dispose();
    }

Essa foi a outra solução.

Mas na verdade nem estou usando mais nenhuma delas.
Parti pra web e tô usando Jasper Reports. Ele cria a impressão pra mim e eu mando pro cliente em PDF, e ele pode salvar e/ou imprimir.

Sei que os códigos acima num estão nem um pouco otimizados… mas funcionam.
Quem tiver sugestões de melhoria, post plz…

vlw
[]´s
Artur Sampaio