spellmoney
v2.0.0
Published
Convierte montos a letras en español, inglés, portugués y francés para cheques, facturas, recibos y contratos, con las divisas del estándar ISO 4217 y sus subunidades.
Maintainers
Readme
spellmoney
Convierte montos numéricos a letras, con el formato exacto que exigen los documentos legales y financieros — cheques, facturas, recibos y contratos: CIENTO VEINTICINCO DÓLARES CON 50/100.
▶ Probalo en el navegador · Read this in English
Existe también el puerto a Python — misma lógica, mismos datos de moneda, mismo resultado exacto.
Instalación
npm install spellmoneyO directamente en el navegador, sin instalar nada:
<script src="https://cdn.jsdelivr.net/npm/spellmoney/dist/spellmoney.min.js"></script>
<script>
document.title = spellmoney.aLetras("125.50");
</script>Uso
import { aLetras } from "spellmoney";
aLetras(125.50);
// 'CIENTO VEINTICINCO DÓLARES CON 50/100'
aLetras("125.50");
// 'CIENTO VEINTICINCO DÓLARES CON 50/100' (lectura decimal exacta)
aLetras(1, { moneda: "GTQ" });
// 'UN QUETZAL CON 00/100'
aLetras(21000000, { moneda: "EUR" });
// 'VEINTIÚN MILLONES DE EUROS CON 00/100'
aLetras(2, { moneda: "GBP", mayusculas: false });
// 'dos libras esterlinas con 00/100'
aLetras(10.50, { centavos: "palabras" });
// 'DIEZ DÓLARES CON CINCUENTA CENTAVOS'También funciona con require():
const { aLetras } = require("spellmoney");Otros idiomas
aLetras(125.50, { idioma: "en" });
// 'ONE HUNDRED TWENTY-FIVE DOLLARS AND 50/100'
aLetras(125.50, { idioma: "pt", moneda: "BRL" });
// 'CENTO E VINTE E CINCO REAIS E 50/100'
aLetras(125.50, { idioma: "fr", moneda: "EUR" });
// 'CENT VINGT-CINQ EUROS ET 50/100'Desde la terminal
npx spellmoney 125.50
npx spellmoney 125.50 --moneda GTQ
npx spellmoney 1000000 --moneda EUR --idioma fr
npx spellmoney --monedas quetzalSolo el número, sin moneda
import { numeroALetras, numeroALetrasEn, numeroALetrasPt, numeroALetrasFr } from "spellmoney";
numeroALetras(1000000); // 'un millón'
numeroALetras(1000000000); // 'mil millones' (¡no "un billón"!)
numeroALetras(1000000000000); // 'un billón'
numeroALetras(200, "f"); // 'doscientas' (concordancia de género)
numeroALetrasEn(1000000000); // 'one billion' (escala corta del inglés)
numeroALetrasPt(21, "f"); // 'vinte e uma' (concordancia de género)
numeroALetrasFr(71); // 'soixante et onze' (base vigesimal del francés)Divisas y subunidades
El catálogo sigue el estándar ISO 4217, incluido el número de decimales de cada divisa. Eso cambia la salida:
aLetras(125.50, { moneda: "JPY" });
// 'CIENTO VEINTISÉIS YENES JAPONESES' el yen no tiene subunidad
aLetras("125.500", { moneda: "KWD" });
// 'CIENTO VEINTICINCO DINARES KUWAITÍES CON 500/1000' el dinar se divide en 1000
aLetras(1.25, { moneda: "GBP", centavos: "palabras" });
// 'UNA LIBRA ESTERLINA CON VEINTICINCO PENIQUES' no "centavos"
aLetras(1.25, { moneda: "EUR", centavos: "palabras" });
// 'UN EURO CON VEINTICINCO CÉNTIMOS'El género de la divisa arrastra al número, como exige la gramática — y no solo en el último dígito: las centenas concuerdan aunque se interponga "mil".
aLetras(200, { moneda: "GBP" });
// 'DOSCIENTAS LIBRAS ESTERLINAS CON 00/100'
aLetras(200000, { moneda: "GBP" });
// 'DOSCIENTAS MIL LIBRAS ESTERLINAS CON 00/100'
aLetras(200, { moneda: "USD" });
// 'DOSCIENTOS DÓLARES CON 00/100'
aLetras(200000000, { moneda: "GBP" });
// 'DOSCIENTOS MILLONES DE LIBRAS ESTERLINAS CON 00/100' "millones" es masculinoLos cuatro idiomas cubren las 156 divisas del catálogo, cada una con su nombre, su género gramatical y, cuando la tiene, el nombre de su subunidad:
| Idioma | Divisas | Ejemplo |
|---|---|---|
| es (español) | 156 | UNA CORONA CHECA CON 00/100 |
| en (inglés) | 156 | ONE CZECH KORUNA AND 00/100 |
| pt (portugués) | 156 | UMA COROA TCHECA E 00/100 |
| fr (francés) | 156 | UNE COURONNE TCHÈQUE ET 00/100 |
Divisas retiradas. Las que el estándar retiró se conservan, marcadas con la fecha en MONEDAS[codigo].retirada — el florín antillano (ANG, 2025-03), el dólar zimbabuense (ZWL, 2024-09) y el lev búlgaro (BGN, 2026-01). Una factura de 2023 se tiene que poder escribir igual.
Montos negativos
Por defecto se rechazan, porque en un cheque casi siempre son un error. Para notas de crédito y devoluciones:
aLetras(-125.50, { negativos: "prefijo" });
// 'MENOS CIENTO VEINTICINCO DÓLARES CON 50/100'Plantilla de salida
Cada país tiene su fórmula legal. La plantilla permite calcarla:
aLetras(125.50, { plantilla: "SON: {monto} {moneda} {conector} {centavos}" });
// 'SON: CIENTO VEINTICINCO DÓLARES CON 50/100'
aLetras(125.50, { plantilla: "{monto} {moneda} ({codigo})" });
// 'CIENTO VEINTICINCO DÓLARES (USD)'Marcadores disponibles: {signo}, {monto}, {moneda}, {conector}, {centavos} y {codigo}. Los espacios sobrantes se colapsan.
Ojo con mayusculas: pasa todo el resultado a mayúsculas o a minúsculas, la plantilla incluida. No conserva el texto tal como se escribió.
API
| Función | Descripción |
|---|---|
| aLetras(monto, opciones?) | Convierte un monto con nombre de moneda. monto puede ser number o cadena decimal. |
| numeroALetras(n, genero?) | Solo el número, en español. |
| numeroALetrasEn(n) | Solo el número, en inglés. |
| numeroALetrasPt(n, genero?) | Solo el número, en portugués. |
| numeroALetrasFr(n) | Solo el número, en francés. |
| MONEDAS | Catálogo de divisas ISO 4217, con decimales y subunidades. |
| IDIOMAS | ["es", "en", "pt", "fr"]. |
| SpellMoneyError | Error lanzado ante un monto, moneda o idioma inválidos. |
ALetrasOptions:
| Opción | Valores | Por defecto |
|---|---|---|
| moneda | código ISO 4217 | "USD" |
| idioma | "es" | "en" | "pt" | "fr" | "es" |
| centavos | "fraccion" | "palabras" | "fraccion" |
| mayusculas | boolean | true |
| negativos | "error" | "prefijo" | "error" |
| plantilla | string | según la divisa |
Redondeo y precisión
Un monto se puede pasar como number o como cadena decimal, y la diferencia importa:
- Cadena —
aLetras("125.50"): los dígitos se leen tal como fueron escritos, sin pasar por punto flotante. El redondeo del primer decimal sobrante es half-up exacto, así que"2.675"da68/100. Es la vía recomendada cuando el monto viene de una base de datos, un formulario o un archivo, donde ya es texto. - Número —
aLetras(125.50): los montos de dos decimales se convierten de forma exacta. Verificado sobre el millón de montos de0.00a9999.99: ninguna diferencia frente a aritmética decimal exacta. Con tres o más decimales, el empate exacto se resuelve según el valor binario que JavaScript almacena realmente, que puede quedar apenas por debajo del decimal escrito:2.675da67/100, igual que(2.675).toFixed(2). Es una propiedad del tiponumber, no de esta librería.
Rango soportado
Enteros de 0 a 999,999,999,999,999. Un monto fuera de ese rango lanza SpellMoneyError, igual que una moneda no reconocida o un idioma no soportado.
Desarrollo
git clone https://github.com/brandriver-bit/spellmoney-js.git
cd spellmoney-js
npm install
npm test
npm run buildLicencia
MIT — ver LICENSE.
spellmoney (English)
Turns numeric amounts into words, in the exact format legal and financial documents require — cheques, invoices, receipts and contracts: ONE HUNDRED TWENTY-FIVE DOLLARS AND 50/100.
▶ Try it in your browser · Leer esto en español
Four languages — Spanish, English, Brazilian Portuguese and French — and the ISO 4217 currency catalog, including each currency's minor units. Zero dependencies. There is also a Python port with identical output.
Install
npm install spellmoneyOr straight in the browser:
<script src="https://cdn.jsdelivr.net/npm/spellmoney/dist/spellmoney.min.js"></script>Usage
import { aLetras } from "spellmoney";
aLetras(125.50, { idioma: "en" });
// 'ONE HUNDRED TWENTY-FIVE DOLLARS AND 50/100'
aLetras("125.50", { idioma: "en", moneda: "GBP", centavos: "palabras" });
// 'ONE HUNDRED TWENTY-FIVE POUNDS STERLING AND FIFTY PENCE'
aLetras(125.50, { idioma: "en", moneda: "JPY" });
// 'ONE HUNDRED TWENTY-SIX JAPANESE YEN' the yen has no minor unit
aLetras("125.500", { idioma: "en", moneda: "KWD" });
// 'ONE HUNDRED TWENTY-FIVE KUWAITI DINARS AND 500/1000'CommonJS (require) and a browser global are both supported, and there's a CLI:
npx spellmoney 125.50 --idioma en --moneda GBPThe API is in Spanish because that's the audience it was written for. aLetras(amount, options) is the entry point; moneda is the ISO 4217 code, idioma the language, centavos whether the minor unit is written as a fraction (50/100) or in words, mayusculas the casing, negativos how to treat negative amounts, and plantilla an output template for matching a specific legal wording.
Pass the amount as a string to have its digits read exactly, without floating point: "2.675" rounds half-up to 68/100, while the number 2.675 gives 67/100 because the nearest double sits just below it — the same result (2.675).toFixed(2) returns.
All four languages cover every currency in the catalog, each with its name, grammatical gender and, where it has one, the name of its minor unit. Withdrawn currencies are kept and flagged with the date they left the standard, so older documents can still be spelled.
MIT licensed.
