Como escrever números por extenso em java

Postado em por Wolmir Cezer Garbin em Java | 182 Visualizações
Última atualização em:

Precisando escrever valores ou números por extenso em java? Neste post vou te mostrar duas formas de fazer isso.

Escrever valores por extenso pode ser uma necessidade no desenvolvimento de aplicações, e isso seria bastante trabalhoso se tivesse que fazer manualmente.

Por isso, vou mostrar duas formas de fazer isso de maneira simples e prática, sem se utilizar de muito esforço.

Valor por extenso utilizando uma classe utilitária

O primeiro exemplo para escrever valores por extenço é utilizando uma classe, que inclusive também utilizo aqui nos projetos, onde basta cópiar e colocar a classe java em seu projeto e utilizar os métodos.

Veja a classe:

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
   
@SuppressWarnings("unchecked")  
public class Extenso {  
    
	private ArrayList nro;  
    private BigInteger num;  
   
    private String Qualificadores[][] = {  
          {"Centavo", "Centavos"},  
          {"", ""},  
          {"Mil", "Mil"},  
          {"Milhão", "Milhões"},  
          {"Bilhão", "Bilhões"},  
          {"Trilhão", "Trilhões"},  
          {"Quatrilhão", "Quatrilhões"},  
          {"Quintilhão", "Quintilhões"},  
          {"Sextilhão", "Sextilhões"},  
          {"Septilhão", "Septilhões"}  
          };  
    private String Numeros[][] = {  
          {"Zero", "Um", "Dois", "Três", "Quatro", "Cinco", "Seis", "Sete", "Oito", "Nove", "Dez",  
          "Onze", "Doze", "Treze", "Quatorze", "Quinze", "Desesseis", "Desessete", "Dezoito", "Desenove"},  
          {"Vinte", "Trinta", "Quarenta", "Cinquenta", "Sessenta", "Setenta", "Oitenta", "Noventa"},  
          {"Cem", "Cento", "Duzentos", "Trezentos", "Quatrocentos", "Quinhentos", "Seiscentos",  
          "Setecentos", "Oitocentos", "Novecentos"}  
          };  
   
   
    /** 
     *  Construtor 
     */  
    public Extenso() {  
       nro = new ArrayList();  
    }  
   
   
    /** 
     *  Construtor 
     * 
     *@param  dec  valor para colocar por extenso 
     */  
    public Extenso(BigDecimal dec) {  
       this();  
       setNumber(dec);  
    }  
   
   
    /** 
     *  Construtor para colocar o objeto por extenso 
     * 
     *@param  dec  valor para colocar por extenso 
     */  
    public Extenso(double dec) {  
       this();  
       setNumber(dec);  
    }  
   
   
    /** 
     *Setando o atributo do número para colocá-lo por extenso 
     *@param  dec  Novo valor para o Número 
     */  
    public void setNumber(BigDecimal dec) {  
       // Converte para inteiro arredondando os centavos  
       num = dec.setScale(2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)).toBigInteger(); 
       // Adiciona valores  
       nro.clear();  
       if (num.equals(BigInteger.ZERO)) {  
          // Centavos  
          nro.add(new Integer(0));  
          // Valor  
          nro.add(new Integer(0));  
       }  
       else {  
          // Adiciona centavos  
          addRemainder(100);  
          // Adiciona grupos de 1000  
          while (!num.equals(BigInteger.ZERO)) {  
             addRemainder(1000);  
          }  
       }  
    }  
   
    public void setNumber(double dec) {  
       setNumber(new BigDecimal(dec));  
   }  
   
    /** 
     *  Descrição do Método 
     */  
    public void show() {  
       Iterator valores = nro.iterator();  
       while (valores.hasNext()) {  
          System.out.println(((Integer) valores.next()).intValue());  
       }  
       System.out.println(toString());  
    }
   
    /** 
     *  Descrição do Método 
     * 
     *@return    Descrição do Valor Retornado 
     */  
    public String toString() {  
       StringBuffer buf = new StringBuffer();    
       //int numero = ((Integer) nro.get(0)).intValue();  
       int ct;  
  
       for (ct = nro.size() - 1; ct > 0; ct--) {  
          // Se ja existe texto e o atual não é zero  
          if (buf.length() > 0 && ! ehGrupoZero(ct)) {  
             buf.append(" e ");  
          }  
          buf.append(numToString(((Integer) nro.get(ct)).intValue(), ct));  
       }  
       if (buf.length() > 0) {  
          if (ehUnicoGrupo())  
             buf.append(" de ");  
          while (buf.toString().endsWith(" "))  
            buf.setLength(buf.length()-1);  
          if (ehPrimeiroGrupoUm())  
             //buf.insert(0, "h");  
          buf.insert(0, "");
          if (nro.size() == 2 && ((Integer)nro.get(1)).intValue() == 1) {  
             buf.append(" real");  
          } else {  
             buf.append(" reais");  
          }  
          if (((Integer) nro.get(0)).intValue() != 0) {  
             buf.append(" e ");  
          }  
       }  
       if (((Integer) nro.get(0)).intValue() != 0) {  
          buf.append(numToString(((Integer) nro.get(0)).intValue(), 0));  
       }  
       return buf.toString();  
    }  
   
    private boolean ehPrimeiroGrupoUm() {  
       if (((Integer)nro.get(nro.size()-1)).intValue() == 1)  
          return true;  
       return false;  
    }  
      
    /** 
     *  Adds a feature to the Remainder attribute of the Extenso object 
     * 
     *@param  divisor  The feature to be added to the Remainder attribute 
     */  
    private void addRemainder(int divisor) {  
       // Encontra newNum[0] = num modulo divisor, newNum[1] = num dividido divisor  
       BigInteger[] newNum = num.divideAndRemainder(BigInteger.valueOf(divisor));  
       // Adiciona modulo  
       nro.add(new Integer(newNum[1].intValue()));  
       // Altera numero  
       num = newNum[0];  
    }  
   
    /** 
     *  Descrição do Método 
     * 
     *@return     Descrição do Valor Retornado 
     */  
    private boolean ehUnicoGrupo() {  
       if (nro.size() <= 3)  
          return false;  
       if (!ehGrupoZero(1) && !ehGrupoZero(2))  
          return false;  
       boolean hasOne = false;  
       for(int i=3; i < nro.size(); i++) {  
          if (((Integer)nro.get(i)).intValue() != 0) {  
             if (hasOne)  
                return false;  
             hasOne = true;  
          }  
       }  
       return true;  
    }  
   
    boolean ehGrupoZero(int ps) {  
       if (ps == nro.size())  
          return true;  
       return ((Integer)nro.get(ps)).intValue() == 0;  
    }  
      
    /** 
     *  Descrição do Método 
     * 
     *@param  numero  Descrição do Parâmetro 
     *@param  escala  Descrição do Parâmetro 
     *@return         Descrição do Valor Retornado 
     */  
    private String numToString(int numero, int escala) {  
       int unidade = (numero % 10);  
       int dezena = (numero % 100); //* nao pode dividir por 10 pois verifica de 0..19  
       int centena = (numero / 100);  
       StringBuffer buf = new StringBuffer();  
   
       if (numero != 0) {  
          if (centena != 0) {  
             if (dezena == 0 && centena == 1) {  
                buf.append(Numeros[2][0]);  
             }  
             else {  
                buf.append(Numeros[2][centena]);  
             }  
          }  
          if ((buf.length() > 0) && (dezena != 0)) {  
             buf.append(" e ");  
          }  
          if (dezena > 19) {  
            dezena /= 10;  
             buf.append(Numeros[1][dezena - 2]);  
             if (unidade != 0) {  
                buf.append(" e ");  
                buf.append(Numeros[0][unidade]);  
             }  
          }  
          else if (centena == 0 || dezena != 0) {  
             buf.append(Numeros[0][dezena]);  
          }  
          buf.append(" ");  
          if (numero == 1) {  
             buf.append(Qualificadores[escala][0]);  
          }  
          else {  
             buf.append(Qualificadores[escala][1]);  
          }  
       }  
       return buf.toString();  
    }   
 }  

Para utilizar a classe para gerar valores por extenso em java, basta fazer o seguinte:

public static void main(String args[]) {
	 Double valor = 120.35;
	System.out.println( new Extenso(valor).toString() );
}

O resultado será o seguinte:

Cento e Vinte reais e Trinta e Cinco Centavos

A vantagem de utilizar esta classe é que você pode alterar os nomes para outras linguagens e utilizar em qualquer idioma, mas se quiser outra opção para gerar valores por extenso em java, vou deixar mais uma dica.

Utilizando um biblioteca java para gerar valores por extenso

Este projeto está no github é um projeto simples mas funcional. O nome da biblioteca é PorExtenso.

Segundo o próprio autor da biblioteca, "PorExtenso foi desenvolvida para escrever valores monetários por extenso automaticamente e pode escrever valores da ordem de setilhões."

A url do projeto no github é: https://github.com/mcrisc/porextenso

O objetivo da biblioteca é gerar expressões em português gramaticalmente correto, para que possam ser usadas em documentos formais, como contratos.

Para utilizar a biblioteca, veja o código:

CurrencyWriter cw = CurrencyWriter.getInstance();

String extenso = cw.write(new BigDecimal("234.89"));
System.out.println(extenso);

extenso = cw.write(new BigDecimal("130000000000"));
System.out.println(extenso);

O resultado será:

duzentos e trinta e quatro reais e oitenta e nove centavos
cento e trinta bilhões de reais

Qualquer dúvida deixe nós comentários.

Wolmir Cezer Garbin

Wolmir Cezer Garbin


Sou formado em Desenvolvimento de Sistemas para Internet pela faculdade Mater Dei e Pós graduado em Desenvolvimento de sistemas em Java pela UTFPR. Trabalho a mais de 9 anos com desenvolvimento em Java, Android e Web utilizando as principais tecnologias do mercado. Atuo como professor na faculdade Mater Dei, programador na Garbo Software e criador do Receitas de Código.

Ver mais

Posts relacionados


Code Conference

Esta é uma conferência de código realizada na cidade de Pato Branco para dissiminar tendências e informações sobre programação e novas tecnológias

Veja mais sobre o Code Conference

Publique seu post no Receitas de Código

Agora você pode publicar seu post no Receitas de Código e compartilhar seu conhecimento com muitas pessoas!

Quero publicar