Skip to content

Instantly share code, notes, and snippets.

@alfchee
Last active May 3, 2025 16:31
Show Gist options
  • Save alfchee/e563340276f89b22042a to your computer and use it in GitHub Desktop.
Save alfchee/e563340276f89b22042a to your computer and use it in GitHub Desktop.
Código en JavaScript que convierte números a letras, bastante útil para formularios de documentos contables y similares
/*************************************************************/
// NumeroALetras
// The MIT License (MIT)
//
// Copyright (c) 2015 Luis Alfredo Chee
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// @author Rodolfo Carmona
// @contributor Jean ([email protected])
/*************************************************************/
function Unidades(num){
switch(num)
{
case 1: return “UN”;
case 2: return “DOS”;
case 3: return “TRES”;
case 4: return “CUATRO”;
case 5: return “CINCO”;
case 6: return “SEIS”;
case 7: return “SIETE”;
case 8: return “OCHO”;
case 9: return “NUEVE”;
}
return “”;
}//Unidades()
function Decenas(num){
decena = Math.floor(num/10);
unidad = num – (decena * 10);
switch(decena)
{
case 1:
switch(unidad)
{
case 0: return “DIEZ”;
case 1: return “ONCE”;
case 2: return “DOCE”;
case 3: return “TRECE”;
case 4: return “CATORCE”;
case 5: return “QUINCE”;
default: return “DIECI” + Unidades(unidad);
}
case 2:
switch(unidad)
{
case 0: return “VEINTE”;
default: return “VEINTI” + Unidades(unidad);
}
case 3: return DecenasY(“TREINTA”, unidad);
case 4: return DecenasY(“CUARENTA”, unidad);
case 5: return DecenasY(“CINCUENTA”, unidad);
case 6: return DecenasY(“SESENTA”, unidad);
case 7: return DecenasY(“SETENTA”, unidad);
case 8: return DecenasY(“OCHENTA”, unidad);
case 9: return DecenasY(“NOVENTA”, unidad);
case 0: return Unidades(unidad);
}
}//Unidades()
function DecenasY(strSin, numUnidades) {
if (numUnidades > 0)
return strSin + ” Y ” + Unidades(numUnidades)
return strSin;
}//DecenasY()
function Centenas(num) {
centenas = Math.floor(num / 100);
decenas = num – (centenas * 100);
switch(centenas)
{
case 1:
if (decenas > 0)
return “CIENTO ” + Decenas(decenas);
return “CIEN”;
case 2: return “DOSCIENTOS ” + Decenas(decenas);
case 3: return “TRESCIENTOS ” + Decenas(decenas);
case 4: return “CUATROCIENTOS ” + Decenas(decenas);
case 5: return “QUINIENTOS ” + Decenas(decenas);
case 6: return “SEISCIENTOS ” + Decenas(decenas);
case 7: return “SETECIENTOS ” + Decenas(decenas);
case 8: return “OCHOCIENTOS ” + Decenas(decenas);
case 9: return “NOVECIENTOS ” + Decenas(decenas);
}
return Decenas(decenas);
}//Centenas()
function Seccion(num, divisor, strSingular, strPlural) {
cientos = Math.floor(num / divisor)
resto = num – (cientos * divisor)
letras = “”;
if (cientos > 0)
if (cientos > 1)
letras = Centenas(cientos) + ” ” + strPlural;
else
letras = strSingular;
if (resto > 0)
letras += “”;
return letras;
}//Seccion()
function Miles(num) {
divisor = 1000;
cientos = Math.floor(num / divisor)
resto = num – (cientos * divisor)
strMiles = Seccion(num, divisor, “UN MIL”, “MIL”);
strCentenas = Centenas(resto);
if(strMiles == “”)
return strCentenas;
return strMiles + ” ” + strCentenas;
}//Miles()
function Millones(num) {
divisor = 1000000;
cientos = Math.floor(num / divisor)
resto = num – (cientos * divisor)
strMillones = Seccion(num, divisor, “UN MILLON DE”, “MILLONES DE”);
strMiles = Miles(resto);
if(strMillones == “”)
return strMiles;
return strMillones + ” ” + strMiles;
}//Millones()
function NumeroALetras(num) {
var data = {
numero: num,
enteros: Math.floor(num),
centavos: (((Math.round(num * 100)) – (Math.floor(num) * 100))),
letrasCentavos: “”,
letrasMonedaPlural: 'Córdobas',//“PESOS”, 'Dólares', 'Bolívares', 'etcs'
letrasMonedaSingular: 'Córdoba', //“PESO”, 'Dólar', 'Bolivar', 'etc'
letrasMonedaCentavoPlural: “CENTAVOS”,
letrasMonedaCentavoSingular: “CENTAVO”
};
if (data.centavos > 0) {
data.letrasCentavos = “CON ” + (function (){
if (data.centavos == 1)
return Millones(data.centavos) + ” ” + data.letrasMonedaCentavoSingular;
else
return Millones(data.centavos) + ” ” + data.letrasMonedaCentavoPlural;
})();
};
if(data.enteros == 0)
return “CERO ” + data.letrasMonedaPlural + ” ” + data.letrasCentavos;
if (data.enteros == 1)
return Millones(data.enteros) + ” ” + data.letrasMonedaSingular + ” ” + data.letrasCentavos;
else
return Millones(data.enteros) + ” ” + data.letrasMonedaPlural + ” ” + data.letrasCentavos;
}//NumeroALetras()
@LuisCruz3888
Copy link

Hola, para los que manejan angular 17


`import { Component, Input } from '@angular/core';

@component({
selector: 'app-numeros-letras',
standalone: true,
imports: [],
templateUrl: './numeros-letras.component.html',
styleUrl: './numeros-letras.component.css'
})
export class NumerosLetrasComponent {

@input() num: number = 0;

Unidades(num: number): string {

switch (num) {
  case 1: return "UN";
  case 2: return "DOS";
  case 3: return "TRES";
  case 4: return "CUATRO";
  case 5: return "CINCO";
  case 6: return "SEIS";
  case 7: return "SIETE";
  case 8: return "OCHO";
  case 9: return "NUEVE";
}

return "";

}//Unidades()

Decenas(num: number): string | undefined {

let decena = Math.floor(num / 10);
let unidad = num - (decena * 10);

switch (decena) {
  case 1:
    switch (unidad) {
      case 0: return "DIEZ";
      case 1: return "ONCE";
      case 2: return "DOCE";
      case 3: return "TRECE";
      case 4: return "CATORCE";
      case 5: return "QUINCE";
      default: return "DIECI" + this.Unidades(unidad);
    }
  case 2:
    switch (unidad) {
      case 0: return "VEINTE";
      default: return "VEINTI" + this.Unidades(unidad);
    }
  case 3: return this.DecenasY("TREINTA", unidad);
  case 4: return this.DecenasY("CUARENTA", unidad);
  case 5: return this.DecenasY("CINCUENTA", unidad);
  case 6: return this.DecenasY("SESENTA", unidad);
  case 7: return this.DecenasY("SETENTA", unidad);
  case 8: return this.DecenasY("OCHENTA", unidad);
  case 9: return this.DecenasY("NOVENTA", unidad);
  case 0: return this.Unidades(unidad);
}

}//Unidades()

DecenasY(strSin: string, numUnidades: number): string {
if (numUnidades > 0)
return strSin + " Y " + this.Unidades(numUnidades)

return strSin;

}//DecenasY()

Centenas(num: number): string | undefined {
let centenas = Math.floor(num / 100);
let decenas = num - (centenas * 100);

switch (centenas) {
  case 1:
    if (decenas > 0)
      return "CIENTO " + this.Decenas(decenas);
    return "CIEN";
  case 2: return "DOSCIENTOS " + this.Decenas(decenas);
  case 3: return "TRESCIENTOS " + this.Decenas(decenas);
  case 4: return "CUATROCIENTOS " + this.Decenas(decenas);
  case 5: return "QUINIENTOS " + this.Decenas(decenas);
  case 6: return "SEISCIENTOS " + this.Decenas(decenas);
  case 7: return "SETECIENTOS " + this.Decenas(decenas);
  case 8: return "OCHOCIENTOS " + this.Decenas(decenas);
  case 9: return "NOVECIENTOS " + this.Decenas(decenas);
}

return this.Decenas(decenas);

}//Centenas()

Seccion(num: number, divisor: number, strSingular: string, strPlural: string): string {
let cientos = Math.floor(num / divisor)
let resto = num - (cientos * divisor)

let letras = "";

if (cientos > 0)
  if (cientos > 1)
    letras = this.Centenas(cientos) + " " + strPlural;
  else
    letras = strSingular;

if (resto > 0)
  letras += "";

return letras;

}//Seccion()

Miles(num: number): string | undefined {
let divisor = 1000;
let cientos = Math.floor(num / divisor)
let resto = num - (cientos * divisor)

let strMiles = this.Seccion(num, divisor, "UN MIL", "MIL");
let strCentenas = this.Centenas(resto);

if (strMiles == "")
  return strCentenas;

return strMiles + " " + strCentenas;

}//Miles()

Millones(num: number): string | undefined {
let divisor = 1000000;
let cientos = Math.floor(num / divisor)
let resto = num - (cientos * divisor)

let strMillones = this.Seccion(num, divisor, "UN MILLON", "MILLONES");
let strMiles = this.Miles(resto);

if (strMillones == "")
  return strMiles;

return strMillones + " " + strMiles;

}//Millones()

NumeroALetras(num: number): string {
var data = {
numero: num,
enteros: Math.floor(num),
centavos: (((Math.round(num * 100)) - (Math.floor(num) * 100))),
letrasCentavos: "",
letrasMonedaPlural: 'PESOS',//"PESOS", 'Dólares', 'Bolívares', 'etcs'
letrasMonedaSingular: 'PESO', //"PESO", 'Dólar', 'Bolivar', 'etc'

  letrasMonedaCentavoPlural: "CENTAVOS",
  letrasMonedaCentavoSingular: "CENTAVO"
}
if (data.centavos > 0) {
  let centavos = ''
  if (data.centavos == 1)
      centavos = this.Millones(data.centavos) + ' ' + data.letrasMonedaCentavoSingular;
  else
      centavos =  this.Millones(data.centavos) + ' ' + data.letrasMonedaCentavoPlural;
  data.letrasCentavos = 'CON ' + centavos
};

if (data.enteros == 0)
  return "CERO " + data.letrasMonedaPlural + " " + data.letrasCentavos;
if (data.enteros == 1)
  return this.Millones(data.enteros) + " " + data.letrasMonedaSingular + " " + data.letrasCentavos;
else
  return this.Millones(data.enteros) + " " + data.letrasMonedaPlural + " " + data.letrasCentavos;

}

}
`

@jcmendez26
Copy link

El código original me pareció muy bien.

Lo he modificado con las siguientes características:

  • Acepta hasta Centenas de Millones.
  • Muestra una línea por default si la cifra es demasiado grande.
  • Le añadí un filtro para que elimine signos o símbolos en el número recibido.
  • Añadí un parámetro para mostrar la moneda (opcional)
  • Y finalmente arreglé algunos errores de formato (espacios de más o de menos).

Lo he estado actualizando constantemente. Pueden revisar la efectividad de esta versión implementada en este generador de Pagarés.

const centavosFormatter = new Intl.NumberFormat('en-US', {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
});

/**
 * Función para convertir un número a letras, con centavos (ideal para representar dinero). Fuente: https://gist.github.com/alfchee/e563340276f89b22042a
 * 
 * @param {float} cantidad - La cantidad a convertir en letras.
 * @param {string} moneda - Moneda opcional para desplegarse en el texto si es que se especifica una. Ej: "PESOS", "DÓLARES" 
 * 
 * NumeroALetras
 * The MIT License (MIT)
 * 
 * Copyright (c) 2015 Luis Alfredo Chee 
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * 
 * @author Rodolfo Carmona
 * @contributor Jean ([email protected])
 * 
 */
function numeroALetras(cantidad, moneda) {

    var numero = 0;
    cantidad = filterNum(cantidad);
    cantidad = parseFloat(cantidad);

    if (cantidad == "0.00" || cantidad == "0") {
        return "CERO 00/100 ";
    } else {
        var cantidadConCentavosExplicitos = centavosFormatter.format(parseFloat(cantidad)).toString().split(".");
        var ent = cantidad.toString().split(".");
        var arreglo = separar_split(ent[0]);
        var longitud = arreglo.length;

        switch (longitud) {
            case 1:
                numero = unidades(arreglo[0]);
                break;
            case 2:
                numero = decenas(arreglo[0], arreglo[1]);
                break;
            case 3:
                numero = centenas(arreglo[0], arreglo[1], arreglo[2]);
                break;
            case 4:
                numero = unidadesdemillar(arreglo[0], arreglo[1], arreglo[2], arreglo[3]);
                break;
            case 5:
                numero = decenasdemillar(arreglo[0], arreglo[1], arreglo[2], arreglo[3], arreglo[4]);
                break;
            case 6:
                numero = centenasdemillar(arreglo[0], arreglo[1], arreglo[2], arreglo[3], arreglo[4], arreglo[5]);
                break;
            case 7:
                numero = unidadesdemillon(arreglo[0], arreglo[1], arreglo[2], arreglo[3], arreglo[4], arreglo[5], arreglo[6]);
                break;
            case 8:
                numero = decenasdemillon(arreglo[0], arreglo[1], arreglo[2], arreglo[3], arreglo[4], arreglo[5], arreglo[6], arreglo[7]);
                break;
            case 9:
                numero = centenasdemillon(arreglo[0], arreglo[1], arreglo[2], arreglo[3], arreglo[4], arreglo[5], arreglo[6], arreglo[7], arreglo[8]);
                break;
            default:
                numero = "______________________________________________________________________";
                break;
        }

        cantidadConCentavosExplicitos[1] = isNaN(cantidadConCentavosExplicitos[1]) ? '00' : cantidadConCentavosExplicitos[1];

        if (cantidad == "1000000" && numero == "UN MILLÓN MIL ") {
            numero = "UN MILLÓN ";
        }

        var divisibleEntreUnMillon = parseInt(cantidad) % 1000000;

        if (divisibleEntreUnMillon == 0) {
            numero = numero.replace("MILLONES MIL", "MILLONES");
        }

        if (moneda) {
            if (cantidad == "1000000" && numero == "UN MILLÓN ") {
                numero = "UN MILLÓN DE";
            }
            if (divisibleEntreUnMillon == 0 && parseInt(cantidad) > 1000000) {
                numero = numero.replace("MILLONES", "MILLONES DE");
            }
            return numero + " " + moneda + " " + cantidadConCentavosExplicitos[1] + "/100";
        } else {
            return numero + cantidadConCentavosExplicitos[1] + "/100";
        }
    }
}

const filterNum = (str) => {
    const numericalChar = new Set([".", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
    str = str.split("").filter(char => numericalChar.has(char)).join("");
    return str;
}

function unidades(unidad) {
    var unidades = Array('UN ', 'DOS ', 'TRES ', 'CUATRO ', 'CINCO ', 'SEIS ', 'SIETE ', 'OCHO ', 'NUEVE ');


    return unidades[unidad - 1];
}

function decenas(decena, unidad) {
    var diez = Array('ONCE ', 'DOCE ', 'TRECE ', 'CATORCE ', 'QUINCE', 'DIECISEIS ', 'DIECISIETE ', 'DIECIOCHO ', 'DIECINUEVE ');
    var decenas = Array('DIEZ ', 'VEINTE', 'TREINTA', 'CUARENTA', 'CINCUENTA', 'SESENTA', 'SETENTA', 'OCHENTA', 'NOVENTA');

    if (decena == 0 && unidad == 0) {
        return "";
    }

    if (decena == 0 && unidad > 0) {
        return unidades(unidad);
    }

    if (decena == 1) {
        if (unidad == 0) {
            return decenas[decena - 1];
        } else {
            return diez[unidad - 1];
        }
    } else if (decena == 2) {
        if (unidad == 0) {
            return decenas[decena - 1];
        }
        else if (unidad == 1) {
            return veinte = "VEINTI" + "UNO ";
        }
        else {
            return veinte = "VEINTI" + unidades(unidad);
        }
    } else {

        if (unidad == 0) {
            return decenas[decena - 1] + " ";
        }
        if (unidad == 1) {
            return decenas[decena - 1] + " Y " + "UNO ";
        }

        return decenas[decena - 1] + " Y " + unidades(unidad);
    }
}

function centenas(centena, decena, unidad) {
    var centenas = Array("CIENTO ", "DOSCIENTOS ", "TRESCIENTOS ", "CUATROCIENTOS ", "QUINIENTOS ", "SEISCIENTOS ", "SETECIENTOS ", "OCHOCIENTOS ", "NOVECIENTOS ");

    if (centena == 0 && decena == 0 && unidad == 0) {
        return "";
    }
    if (centena == 1 && decena == 0 && unidad == 0) {
        return "CIEN ";
    }

    if (centena == 0 && decena == 0 && unidad > 0) {
        return unidades(unidad);
    }

    if (decena == 0 && unidad == 0) {
        return centenas[centena - 1] + "";
    }

    if (decena == 0) {
        var numero = centenas[centena - 1] + "" + decenas(decena, unidad);
        return numero.replace(" Y ", " ");
    }
    if (centena == 0) {

        return decenas(decena, unidad);
    }

    return centenas[centena - 1] + "" + decenas(decena, unidad);

}

function unidadesdemillar(unimill, centena, decena, unidad) {
    var numero = unidades(unimill) + "MIL " + centenas(centena, decena, unidad);
    numero = numero.replace("UN MIL ", "MIL ");
    if (unidad == 0) {
        return numero.replace(" Y ", " ");
    } else {
        return numero;
    }
}

function decenasdemillar(decemill, unimill, centena, decena, unidad) {
    var numero = decenas(decemill, unimill) + "MIL " + centenas(centena, decena, unidad);
    return numero;
}

function centenasdemillar(centenamill, decemill, unimill, centena, decena, unidad) {

    var numero = 0;
    numero = centenas(centenamill, decemill, unimill) + "MIL " + centenas(centena, decena, unidad);

    return numero;
}

function unidadesdemillon(unimillon, centenamill, decemill, unimill, centena, decena, unidad) {
    var numero = unidades(unimillon) + "MILLONES " + centenas(centenamill, decemill, unimill) + "MIL " + centenas(centena, decena, unidad);
    numero = numero.replace("UN MILLONES ", "UN MILLÓN ");
    if (unidad == 0) {
        return numero.replace(" Y ", " ");
    } else {
        return numero;
    }
}

function decenasdemillon(decemillon, unimillon, centenamill, decemill, unimill, centena, decena, unidad) {
    var numero = decenas(decemillon, unimillon) + "MILLONES " + centenas(centenamill, decemill, unimill) + "MIL " + centenas(centena, decena, unidad);
    return numero;
}

function centenasdemillon(centenamillon, decemillon, unimillon, centenamill, decemill, unimill, centena, decena, unidad) {

    var numero = 0;
    numero = centenas(centenamillon, decemillon, unimillon) + "MILLONES " + centenas(centenamill, decemill, unimill) + "MIL " + centenas(centena, decena, unidad);

    return numero;
}

function separar_split(texto) {
    var contenido = new Array();
    for (var i = 0; i < texto.length; i++) {
        contenido[i] = texto.substr(i, 1);
    }
    return contenido;
}

NO ME FUNCIONA EN SHEET, ARROJA EL SIGUIENTE ERROR:
Error
TypeError: str.split is not a function (línea 114)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment