RESOLVIDO - Completar string com Zeros

26 respostas
catia.alessandra

Por favor, antes de me criticarem e dizerem que existem milhoes de posts na net sobre isso, deixem-me explicar o meu caso :) pois tentei implementar todos eles.

Meu código é os eguinte:

protected String doIt() throws Exception {
        PreparedStatement pstm = null;
        ResultSet rs = null;
        String trx = null;
        String sql = " SELECT cbp.name2, cmr.grandtotal                                               "+
        " FROM c_commissionrun cmr                                                                           "+
        " INNER JOIN c_commission cm ON cmr.c_commission_id = cm.c_commission_id  "+
        " INNER JOIN c_bpartner cbp ON cm.c_bpartner_id = cbp.c_bpartner_id               "+
        " WHERE cmr.startdate = ?                                                                                ";
        try    {    
            pstm = DB.prepareStatement(sql, trx);    
            pstm.setTimestamp(1, p_Date);
            rs = pstm.executeQuery();
            while(rs.next())
            {

                String Nome2 = rs.getString("name2");
                BigDecimal ValorTotal = rs.getBigDecimal("grandtotal");
                BufferedWriter arquivo;  
                String Nome = String.format ("%08d", Nome2);
                String valores = "460-"+ Nome + "-00322-" + ValorTotal;  
                try {  
                    arquivo = new BufferedWriter(new FileWriter("TBDIGI004.txt", true));  
                    arquivo.write(valores);  
                    arquivo.newLine();  
                    arquivo.flush();  
                    arquivo.close();   
                }  
                catch (IOException erro)  
                {  
                // trata o erro  
                }  
                if(Nome2 == "")
                    continue;
            }
        }catch(Exception ex){ 
            //
            }
        finally {
            DB.close(rs, pstm);
            pstm = null;
            rs = null; 
            }
    return null;
    }
É um processo que exporta dados para um Txt. Só que tanto o Nome, quanto o valor total, eu tenho que completar com zeros, o nome tem q ter ao total 8 digitos e o valor 18. Primeiro, o valor eu vou ter que converter para integer, ou seja, colocar os numeros depois da virgula, antes dela, como se fosse um só (ex 1,50 = 150) porque o programa que vai importar o txt sabe que os dois ultimos campos são os centavos. E isso não estou conseguindo fazer. O outro problema, é que essa parte aqui
String Nome = String.format ("%08d", Nome2);
que deveria completar com os zeros é executada, e daí ele não passa no restante do código, ou seja, não gera o Txt!

Estou fazendo algo errado???

Tentei usar o DecimalFormat também, mas acontecia a mesma coisa, ele pulava o restante do código.

Desde já agradeço se alguém puder me ajudar, pois não sei o que estou fazendo de errado! :?: :?

26 Respostas

jpjcjbr

Bom dia Catia,

Tente usar a classe StringUtils que fica no projeto commons-lang da apache

Exemplo de uso:

import org.apache.commons.lang.StringUtils;

public class TesteCompletarComZeros {
	
	public static void main(String[] args) {
		String numero = "123";
		
		// completar com 'a' a esquerda
		// resultado aaaaaaaaaaaa123
		System.out.println(StringUtils.leftPad(numero, 15, "a"));
		
		// completar com '0' a esquerda
		// resultado 000000000000123
		System.out.println(StringUtils.leftPad(numero, 15, "0"));
		
		// completar com '0' a direita
		// resultado 123000000000000
		System.out.println(StringUtils.rightPad(numero, 15, "0"));
	}
	
}

O link para download da lib é: http://commons.apache.org/lang/download_lang.cgi

Espero ter ajudado

catia.alessandra

Muito Obrigada, funcionou! :lol:

Essa é uma amostra da linha que recebo:

460-00100575-00322-46267.00000000000000

Agora só falta formatar o último valor, deixar só os dois primeiros números depois do ponto e tirar o ponto! :smiley:

Francisco_Silva

Não da certo porque a variavel Nome2 é do tipo String… e no caso do “%08d” só formata se for um Integer.
Para dar certo tera que converter de String para Integer… Assim:

String Nome = String.format ("%08d", Integer.parseInt(Nome2));

Acho que não entendi direito… mas se for só para tirar o ponto é só utilizar o replace… Ex:

BigDecimal valor = new BigDecimal(1.50); System.out.print((valor+"").replace(".", ""));

catia.alessandra

A parte do replace funcionou, dos zeros ja tinha funcionado.
Uma última pergunta:

Nesse meu campo valor, ele mostra 14 digitos após a virgula oO
como posso fazer para mostrar só os dois q interessam? porque o resto é tudo zero :?: :oops:

Francisco_Silva

Se o resto do numero é tudo zero na hora que é armazenado no objeto BigDecimal ele automaticamente desconsidera os zeros…

BigDecimal valor = new BigDecimal(1.[telefone removido]); System.out.print((valor+"").replace(".", ""))
O resultado sera: “15”.

C
Você pode fazer um método que faça isso, exemplo:
public static String StrZeroDireita(String value, int n) {

		String s = value.trim();
		StringBuffer resp = new StringBuffer();

		int fim = n - s.length();

		for (int x = 0; x < fim; x++)
			resp.append('0');

		return s + resp;

	}
Assim você passa a variável e quantos 0 deve preencher.
catia.alessandra

Pra definir quantas casas decimais, foi só fazer um setScale(2).

Obrigado pela ajuda :slight_smile:

Priuli

Segue proj. de utils opensource, com varias funções que usamos direto…caso interesse é só baixar, o código esta no svn no googlecode.
Para este post teria as funções StringUtils.rightPad(String, int, String) e StringUtils.leftPad(String, int, String) e na pro versao StringUtils.truncAndRightPad e truncAndLeftPad

http://code.google.com/p/opensutils-br4j/w/list

http://www.guj.com.br/java/225445-opensutils-br4j—biblioteca-de-utilitarios-utils

catia.alessandra

Olá novamente!
Bom, meu código ta funcionando certinho, beleza.
Só que eu queria implementar que o usuário pudesse escolher onde salvar o arquivo. Tentei fazer com o JFileChooser, só que eu preciso assim:
Que ele ja abra o JFileChooser pre-definido em uma pasta, pq vai ficar salvo la, mas caso o usuário deseje mudar de local, ele possa; e que o nome do arquivo fique sempre o mesmo.
Tem como fazer isso?
Tentei implantar, mas dai me confundi na parte da escrita do arquivo, porque fica dentro de um While, e o JFileChooser não pode ir dentro do while, senão enquanto tiver algum arquivo ele vai ficar abrindo :?:

Alguma dica??
Desde já, obrigada! :slight_smile:

Eric_Yuzo

Pode passar um File ou a String com o caminho pelo construtor:

JFileChooser chooser = new JFileChooser("/home/username/Desktop");Ou então passar o File representando o caminho pelo método setCurrentDirectory.

1 - Permita que o usuário possa selecionar apenas diretórios:

chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);2 - Pegue o caminho do diretório e crie o arquivo com o nome fixo:

new File(chooser.getSelectedFile().getPath() + "nomeDoArquivo.txt");

Pode selecionar o caminho antes do while e apenas escrever no arquivo dentro do laço.

catia.alessandra

Ok, mas nessa parte aqui

arquivo = new BufferedWriter(new FileWriter("TBDIGI004.txt", true));

o que eu coloco entre os parênteses?
porque ali que vai o caminho e o nome do arquivo :?: :?

Eric_Yuzo

String fileName = chooser.getSelectedFile().getPath() + System.getProperty("file.separator") + "TBDIGI004.txt"; arquivo = new BufferedWriter(new FileWriter(fileName, true));
chooser.getSelectedFile().getPath() => Pega o caminho do diretório selecionado;
System.getProperty(“file.separator”) => Pega o tipo de separador (barra) do SO;

catia.alessandra
Ok, adaptei meu código e ficou assim:
protected String doIt() throws Exception {
        PreparedStatement pstm = null;
        ResultSet rs = null;
        String trx = null;
        String sql = " SELECT cbp.name2, cmr.grandtotal, cmr.startdate    "+
        " FROM c_commissionrun cmr                                                               "+
        " INNER JOIN c_commission cm ON cmr.c_commission_id = cm.c_commission_id            "+
        " INNER JOIN c_bpartner cbp ON cm.c_bpartner_id = cbp.c_bpartner_id                    "+
        " WHERE cmr.startdate = ?                                                            ";
        try    {    
            pstm = DB.prepareStatement(sql, trx);    
            pstm.setTimestamp(1, p_Date);
            rs = pstm.executeQuery();
            JFileChooser chooser = new JFileChooser();
            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            int acao = chooser.showOpenDialog(chooser);  
            switch(acao){  
                case JFileChooser.APPROVE_OPTION:
                    String fileName = chooser.getSelectedFile().getPath() + System.getProperty("file.separator") + "TBDIGI.004";
            break;  
            case JFileChooser.CANCEL_OPTION:  
                return null;  
            }     
            while(rs.next())
            {
                String Nome2 = rs.getString("name2");
                BigDecimal ValorTotal = rs.getBigDecimal("grandtotal");
                BufferedWriter arquivo;  
                String Nome = StringUtils.leftPad(Nome2, 8, "0");
                String Total = StringUtils.leftPad(ValorTotal.setScale(2).toString().replace(".", ""), 18, "0"); 
                String valores = "460"+ Nome + "00322" + Total;  

                arquivo = new BufferedWriter(new FileWriter(fileName, true));
                arquivo.write(valores);  
                arquivo.newLine();  
                arquivo.flush();  
                arquivo.close(); 
                if(Nome2 == "")
                    continue;
            }    
        }catch(Exception ex){ 
            //
            }
        finally {
            DB.close(rs, pstm);
            pstm = null;
            rs = null; 
            }
    return null;
    }
}
Mas ta dando erro na linha
arquivo = new BufferedWriter(new FileWriter(fileName, true));
porque ele não encontra o filename... isso é mto consfuso pra mim :? :?:
Eric_Yuzo

Você criou a String chamada fileName? É ela que guarda o caminho selecionado pelo usuário mais o nome do arquivo.

String fileName = chooser.getSelectedFile().getPath() + System.getProperty("file.separator") + "TBDIGI004.txt";
catia.alessandra

Sim, ela está lá no Switch case!

Eric_Yuzo

A tá. Eu tinha olhado por cima e não tinha achado.

A variável fileName não está sendo encontrada por que ela está sendo criada dentro do switch, portanto o escopo dela é este. A partir do momento que está fora do switch, fileName já não existe mais.

Crie a variável fileName antes do switch e depois apenas atribua o valor.

. . . String fileName = null; switch(acao){ case JFileChooser.APPROVE_OPTION: fileName = chooser.getSelectedFile().getPath() + System.getProperty("file.separator") + "TBDIGI.004"; . . .

catia.alessandra

Ahhh…
Muito Obrigada!! :D:D:D:D
Agora ta funcionando certinho! :stuck_out_tongue:

catia.alessandra

Ah, mais uma dúvida:
Cada vez que eu gero o txt, ele adiciona as linhas abaixo das existentes; eu preciso que ele limpe o arquivo antes de gravar os novos dados.
Já percebi que não existe um clear ou algo do gênero. :?:

Eric_Yuzo

O segundo parâmetro do FileWriter indica se o conteúdo deve ser adicionado (append) ou sobrescrito. Para sobrescrever o arquivo, basta passar false neste parâmetro:

new FileWriter(fileName, false)
catia.alessandra

Muito obrigada, novamente! :oops:

Eric_Yuzo

Por nada. Estamos aqui pra isso mesmo.

Mas na verdade poderia até ignorar o segundo parâmetro, pois false já é o padrão.

catia.alessandra

A questão do false não deu certo, pois retornou apenas uma linha no txt :?: :?

Eric_Yuzo
while(rs.next())
            {
                . . .

                arquivo = new BufferedWriter(new FileWriter(fileName, false)); // A cada iteração no result set o BufferedWriter é criado novamente, apagando o que foi escrito anteriormente.
                arquivo.write(valores);  
                
                . . .
            }
O BufferedWriter deveria ser criado antes de entrar no laço.
catia.alessandra

Ta, eu coloquei a linha arquivo = new BufferedWriter(new FileWriter(fileName, false)); antes do While, mas acontece a mesma coisa: ele grava somente um registro, o primeiro! :?: :?

Eric_Yuzo

Apenas escreva o arquivo dentro do laço. Depois que terminar de escrever todas as linhas no arquivo, aí sim chame o flush e o close.

catia.alessandra

Ok, agora funcionou!
Obrigada :roll:

Criado 5 de fevereiro de 2011
Ultima resposta 7 de fev. de 2011
Respostas 26
Participantes 6