RESOLVIDO - Completar string com Zeros

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

Meu código é os eguinte:

[code]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;
}[/code]

É 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! :?: :?

Bom dia Catia,

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

Exemplo de uso:

[code]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"));
}

}
[/code]

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

Espero ter ajudado

3 curtidas

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:

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(".", ""));

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:

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

BigDecimal valor = new BigDecimal(1.50000000000); System.out.print((valor+"").replace(".", ""))
O resultado sera: “15”.

Você pode fazer um método que faça isso, exemplo:

[code] 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;

}[/code]Assim você passa a variável e quantos 0 deve preencher.

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

Obrigado pela ajuda :slight_smile:

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

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:

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.

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 :?: :?

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;

Ok, adaptei meu código e ficou assim:

[code]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;
}

}[/code]

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 :? :?:

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";

Sim, ela está lá no Switch case!

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"; . . .

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

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. :?:

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)