Desde hace tiempo quería compartir con ustedes esta pequeña clase en PHP que nos permite obtener la cantidad con letras de un número dado. Esta clase la escribi en PHP a partir de una macro que encontré hace tiempo escrita para Excel y que solíamos utilizar hace tiempo en ese programa para elaborar nuestras facturas sin tener que estar escribiendo la cantidad con letras.
El código lo pueden encontrar a continuación o bien descargar Numero2Text.zip.
<?php /******************************************************** * Numero2Texto convierte un numero a una cadena * de texto que indica con palabras la cantidad que * representa el numero. * * El script se baso en el trabajo realizado por: * César Castro * Enero-97 * http://chamarrasdepiel.com/SrExcel.html * para un libro de excel. * * La funcionalidad para PHP fue realizada por * Gerardo Gonzalez Flores, 2007 * gerardo@clic.com.mx * * * 'Optional Fraccion_Letras = False, _ * 'Optional Fraccion = "", _ * 'Optional Texto_Inicial = "", _ * 'Optional Texto_Final = "", _ * 'Optional Estilo = 1) * **********************************************************/ class Numero2Texto extends Object{ /***************************************************************************** '-- Funcion principal para convertir el numero en texto -- '-- Argumentos: -- '-- $numero = Valor que deseamos convertir en texto -- '-- $moneda = es el nombre de la moneda a mostrar -- '-- $fraccionLetras = Verdadero para que la fraccion de la moneda -- '-- tambien la convierta a letras -- '-- $fraccion = Es el nombre de la fraccion de la moneda -- '-- $textoInicial = Cualquier texto que quieras al principio del resultado -- '-- $texto_Final = Cualquier texto que quieras al final del resultado -- '-- $estilo = Formato de salida -- '-- 1 = MAYUSCULAS -- '-- 2 = minusculas -- '-- 3 = Tipo Titulo (no habilitada por el momento) -- '-- Los valores negativos los convierte a positivos -- '-- El valor minimo en 0, el valor maximo es 9,999,999,999,999.99 -- ******************************************************************************/ function numeroTexto($numero, $moneda = 'peso' , $fraccionLetras = true, $fraccion = ' centavo', $textoInicial = "", $textoFinal="", $estilo = 2){ $strLetras = ""; $numTmp = ""; $intFraccion = ""; $strLetras = $textoInicial; //'Convertimos a positivo si es negativo $numero = abs($numero); $numTmp = $this->format($numero, "000000000000000.00"); if($numero < 1 ){ $strLetras = $strLetras . "cero " . $this->plural($moneda) . " "; }else{ $strLetras = $strLetras . $this->numLet($this->val(substr($numTmp, 0, 15))); if($this->val($numTmp) == 1 || $this->val($numTmp) <= 2) { $strLetras = $strLetras . $moneda . " "; }elseif($this->val(substr($numTmp, 3, 12)) == 0 || $this->val(substr($numTmp, 9, 6)) == 0){ $strLetras = $strLetras . "de " . $this->plural($moneda) . " "; }else{ $strLetras = $strLetras . $this->plural($moneda) . " "; } } if($fraccionLetras){ $intFraccion = $this->val(substr($numTmp, strlen($numTmp)-2, 2)); switch($intFraccion){ case 0: $strLetras = $strLetras . "con cero " . $this->plural($fraccion); break; case 1: $strLetras = $strLetras . "con un " . $fraccion; break; default: // se podra usar intFraccion? //-->strLetras = strLetras + "con " + numLet($intFraccion) + $this->plural($fraccion); $strLetras = $strLetras . "con " . $this->numLet(substr($numTmp, strlen($numTmp)-2, 2)) . $this->plural($fraccion); } }else{ // se podra usar intFraccion? //-->$strLetras = $strLetras + $intFraccion; $strLetras = $strLetras . substr($numTmp, strlen($numTmp)-2, 2) . '/100'; } $strLetras = $strLetras . $textoFinal; switch($estilo){ case 1: $strLetras = strtoupper($strLetras); break; case 2: $strLetras = strtolower($strLetras); break; case 3: $strLetras = strtolower(strLetras); //'StrConv(strLetras, vbPropercase); break; } return $strLetras; } function numLet($numero ) { $numTmp = ""; $co1 = ""; $co2 = ""; $pos = ""; $dig = ""; $cen = ""; $dec = ""; $uni = ""; $letra1 = ""; $letra2 = ""; $letra3 = ""; $leyenda = ""; $tFNumero = ""; $numTmp = $this->format($numero, "000000000000000"); // 'Le da un formato fijo $co1 = 1; $pos = 0; //'Para extraer tres digitos cada vez while($co1 <= 5){ $co2 = 1; while($co2 <= 3){ //'Extrae un digito cada vez de izquierda a derecha $dig = $this->val(substr($numTmp, $pos, 1)); switch($co2){ case 1: $cen = $dig+0; break; case 2: $dec = $dig+0; break; case 3: $uni = $dig+0; break; } $co2++; $pos++; } $letra3 = $this->centena($uni, $dec, $cen); $letra2 = $this->decena($uni, $dec); $letra1 = $this->unidad($uni, $dec); switch($co1){ case 1: if(($cen + $dec + $uni) == 1 ){ $leyenda = "billon "; }elseif(($cen + $dec + $uni) > 1){ $leyenda = "billones "; } break; case 2: if(($cen + $dec + $uni >= 1) && $this->val(substr($numTmp, 6, 3)) == 0){ $leyenda = "mil millones "; }elseif($cen + $dec + $uni >= 1){ $leyenda = "mil "; } break; case 3: if(($cen + $dec == 0) && ($uni == 1)){ $leyenda = "millon "; }elseif(($cen > 0) || ($dec > 0) || ($uni > 1)){ $leyenda = "millones "; } break; case 4: if(($cen + $dec + $uni) >= 1){ $leyenda = "mil "; } break; case 5: if($cen + $dec + $uni >= 1){ $leyenda = ""; } break; } $co1++; $tFNumero = $tFNumero . $letra3 . $letra2 . $letra1 . $leyenda; $leyenda = ""; $letra1 = ""; $letra2 = ""; $letra3 = ""; }//fin while return $tFNumero; } function centena($uni , $dec , $cen) { $cTexto = ""; switch($cen){ case 1: if(($dec + $uni) == 0){ $cTexto = "cien "; }else{ $cTexto = "ciento "; } break; case 2: $cTexto = "doscientos "; break; case 3: $cTexto = "trescientos "; break; case 4: $cTexto = "cuatrocientos "; break; case 5: $cTexto = "quinientos "; break; case 6: $cTexto = "seiscientos "; break; case 7: $cTexto = "setecientos "; break; case 8: $cTexto = "ochocientos "; break; case 9: $cTexto = "novecientos "; break; default: $cTexto = ""; } return $cTexto; } function decena($uni , $dec ){ $cTexto = ""; switch($dec){ case 1: switch($uni){ case 0: $cTexto = "diez "; break; case 1: $cTexto = "once "; break; case 2: $cTexto = "doce "; break; case 3: $cTexto = "trece "; break; case 4: $cTexto = "catorce "; break; case 5: $cTexto = "quince "; break; case 6: $cTexto = "dieci"; break; case 7: $cTexto = "dieci"; break; case 8: $cTexto = "dieci"; break; case 9: $cTexto = "dieci"; break; } break; case 2: if($uni == 0){ $cTexto = "veinte "; }elseif($uni > 0){ $cTexto = "veinti"; } break; case 3: $cTexto = "treinta "; break; case 4: $cTexto = "cuarenta "; break; case 5: $cTexto = "cincuenta "; break; case 6: $cTexto = "sesenta "; break; case 7: $cTexto = "setenta "; break; case 8: $cTexto = "ochenta "; break; case 9: $cTexto = "noventa "; break; default: $cTexto = ""; } $cTexto = $uni > 0 && $dec > 2 ? $cTexto . "y " : $cTexto; return $cTexto; } function unidad($uni, $dec){ $cTexto = ""; if($dec != 1){ switch($uni){ case 1: $cTexto = "un "; break; case 2: $cTexto = "dos "; break; case 3: $cTexto = "tres "; break; case 4: $cTexto = "cuatro "; break; case 5: $cTexto = "cinco "; break; } } switch($uni){ case 6: $cTexto = "seis "; break; case 7: $cTexto = "siete "; break; case 8: $cTexto = "ocho "; break; case 9: $cTexto = "nueve "; break; } return $cTexto; } //'Funcion que convierte al plural el argumento pasado function plural($palabra) { $pos = ""; $strPal = ""; if(strlen(trim($palabra)) > 0){ $pos = strpos("aeiou", substr($palabra, -1, 1)); if($pos > 0){ $strPal = $palabra . "s"; }else{ $strPal = $palabra . "es"; } } return $strPal; } //'--- Pequeños Hacks para funciones que no tenemos disponibles en VbScript --- function format($cadena, $formato){ $arr = ""; $entero = ""; $decimal = ""; if(!is_numeric($cadena)){ $cadena = 0; } $cadena = number_format($cadena, 2); if(substr_count($formato, ".") == 1){ // Indispensables [] para detectat los siguientes caracteres / . - $arr = split("[.]", $formato); $entero = trim($arr[0]); $decimal = trim($arr[1]); }else{ $entero = $formato; } //--Eliminamos la coma $cadena = str_replace(",","",$cadena); // Crea una cadena standar con ceros a la izquierda (podria usarse sprintf?) $cadena = substr($entero, 0, (strlen($entero)-(strlen($cadena)-3))) . $cadena; return $cadena; } function val($parametro){ $parametro = trim($parametro); if((!empty($parametro) && $parametro!="" && !is_null($parametro)) && is_numeric($parametro)){ $parametro = $parametro * 1; }else{ $parametro = 0; } return $parametro; } } ?>
El uso es bastante sencillo como lo demuestro a continuación:
$num2Texto = new Numero2Texto(); $num2Texto->numeroTexto($numero, $moneda, $fraccionLetras, $fraccion, $textoInicial, $textoFinal, $estilo)