c#生成中文金额并用语音读取出来的完整类

C#把金额转成中文字符。金额最小的4位小数厘,最大没有限制。可以到亿、兆、吉、特。
数字字符:壹,贰,叁,肆,伍,陆,柒,捌,玖,拾
小数字符:厘,毫,分,角
千以下单位:拾,佰,仟
万以上单位:万,亿,兆,吉,特,长度没限制
调用方法:string s = new PayVoiceReader().chinaMoney(123456781234.5678);

代码很长,但是底下调用windows定义的部分几乎用不到,是另一种播放dll的方式。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//
using System.Threading;
using System.IO;
using System.Runtime.InteropServices;
using iPublic;
using Gs_Class;

namespace WindowsFormsApplication1
{
    /// <summary>
    /// 支付语音朗读,作者:海宏软件,http://www.iHaiHong.cn
    /// 修改记录:
    ///   20191107,周承昊,从delphi移过来
    /// </summary>
    public partial class PayVoiceReader
    {
        public Thread thread = null;
        List<string> readList = null;
        public iDefine.ChuLiJieGuo globalStatus = null;


        #region //readChinaMoney,读中文金额
        /// <summary>
        /// 读语音,比如金额。开启了一个线程thread。
        /// 用法:
        ///     PayVoiceReader p = new PayVoiceReader();
        ///     string s = p.chinaMoney(123.45), sPath="D:\\wave\\";
        ///     p.readChinaMoney(s, sPath);
        /// </summary>
        /// <param name="str">要读的中文字符串,是用chinaMoney(124.56)生成的</param>
        /// <param name="waveFilePath">wav文件的存储路径</param>
        /// <param name="您本次消费">是否前缀上“您本次消费”的语音</param>
        /// <returns></returns>
        public iDefine.ChuLiJieGuo readChinaMoney(string str, string waveFilePath = "", bool 您本次消费 = false)
        {
            iDefine.ChuLiJieGuo result = new iDefine.ChuLiJieGuo();
            if (string.IsNullOrEmpty(str)) { result.error = 0; return result; }
            //
            readList = getChinaMoneyWaveFiles(str, waveFilePath, 您本次消费);
            if (readList != null && readList.Count > 0)
            {
                thread = new Thread(new ThreadStart(threadRun));
                thread.Start();
            }
            //
            result.error = 0;
            return result;
        }
        #endregion


        #region //threadRun,线程的执行,被readChinaMoney调用
        /// <summary>
        /// thread的线程执行,被readChinaMoney调用
        /// </summary>
        private void threadRun()
        {
            if (globalStatus == null) globalStatus = new iDefine.ChuLiJieGuo();
            globalStatus.error = -1;
            if (readList == null) { globalStatus.error = 0; return; }
            //
            System.Media.SoundPlayer snd = null;
            try
            {
                //循环播放所有文件
                for (int i = 0; i < readList.Count; i++)
                {
                    if (Gs_Class.GsDefineTypes.GlobalTerminateWorking) break;   //全局终止标志
                    string sFile = readList[i];
                    if (!File.Exists(sFile)) continue;
                    //播放wav文件:
                    //iPublicX.PlaySound(sFile, (IntPtr)(iPublicX.PlaySoundFlags.SND_FILENAME | iPublicX.PlaySoundFlags.SND_SYNC), 0);
                    if (snd != null) try { snd.Dispose(); snd = null; } catch (Exception x) { }
                    snd = new System.Media.SoundPlayer(sFile);
                    snd.Load();
                    snd.PlaySync();
                }
                //完成
                globalStatus.error = 0;
            }
            catch (Exception x)
            {
                globalStatus.error = 100;
                globalStatus.message = x.Message;
            }
            finally
            {
                if (snd != null) try { snd.Dispose(); } catch (Exception y) { }
                snd = null;
            }
        }
        #endregion


        #region //getChinaMoneyWaveFiles,获取金额的语音文件清单
        /// <summary>
        /// 获取金额的语音文件清单
        /// </summary>
        /// <param name="sMoney">字符串,比如一个金额:壹佰贰拾叁元肆角伍分,可以用chinaMoney生成</param>
        /// <param name="waveFilePath">wav文件路径</param>
        /// <param name="您本次消费">是否前缀“您本次消费”的提示语音</param>
        /// <returns></returns>
        public List<string> getChinaMoneyWaveFiles(string sMoney, string waveFilePath = "", bool 您本次消费 = false)
        {
            List<string> result = new List<string>();
            if (string.IsNullOrEmpty(sMoney)) return null;
            //
            string s = "", s2 = "", sPath = waveFilePath;
            if (string.IsNullOrEmpty(sPath)) sPath = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath);
            if (!sPath.EndsWith("\\")) sPath += "\\";
            while (sMoney.Length > 0)
            {
                s = sMoney.Substring(0, 1);         //取第一个
                sMoney = sMoney.Substring(1);       //字符截取
                //
                s2 = getFileName(s, sPath);
                if (File.Exists(s2)) result.Add(s2);
            }
            if (result.Count > 0 && 您本次消费)
            {
                s = getFileName("您本次消费", sPath);
                if (File.Exists(s)) result.Insert(0, s);
            }
            //
            return result;
        }
        private string getFileName(string sKey, string sPath = "")
        {
            string s = sPath + sKey + ".wav";
            if (!File.Exists(s)) s = sPath + sKey + ".mp3";
            if (File.Exists(s)) return s;
            return "";
        }
        #endregion


        #region //chinaMoney,中文金额
        /// <summary>
        /// 数字转成中文金额。金额最小的4位小数厘,最大没有限制。可以到兆、吉、特。
        ///   数字字符:壹,贰,叁,肆,伍,陆,柒,捌,玖,拾
        ///   小数字符:厘,毫,分,角
        ///   千以下单位:拾,佰,仟
        ///   万以上单位:万,亿,兆,吉,特
        /// 调用方法:string s = new PayVoiceReader().chinaMoney(123456781234.5678);
        /// </summary>
        /// <param name="num">数字</param>
        /// <returns>中文金额</returns>
        public string chinaMoney(double num)
        {
            if (num == 0) return "零";
            string result = "";
            string s = "", s2 = "";
            //定义数字
            string[] sNum = new string[] { "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖", "拾" };
            //定义小数部分
            string[] sDecimal = new string[] { "厘", "毫", "分", "角" };
            //定义每4位一组的标题
            string[] sMulti = new string[] { "", "拾", "佰", "仟" };
            //定义每4位一组的汉语标志
            string[] sTitle = new string[] { "", "万", "亿", "兆", "吉", "特" };
            //初始化
            string Str = Math.Abs(num).ToString();      //FloatToStr(ABS(Num));
            int nPoint = Str.IndexOf('.');              //Pos('.', Str);
            if (nPoint == 0) nPoint = Str.Length + 1;
            //----------------------------------取小数部分,保留4位----------------------------------//
            string sDec = "";
            Int64 n = Convert.ToInt64((Math.Round(num, 4) * 10000)) % 10000;
            if (n > 0)
            {
                s = n.ToString().PadRight(4, '0');
                for (int i = 0; i < s.Length; i++)
                {
                    s2 = s.Substring(i, 1);
                    if (s2 == "0") continue;
                    sDec += sNum[Convert.ToInt16(s2) - 1] + sDecimal[4 - 1 - i];
                }
            }
            //-------------------------------------整数部分------------------------------------------//
            //4位一组。编程注意:Length(Str)取出的长度总是少1位
            string sInt = "";
            Str = Math.Abs(num).ToString().Split('.')[0].Trim();    //Copy(Str, 1, nPoint - 1);
            int nLen = Str.Length;                      // Length(Str) + 1;
            int nM = nLen / 4;                          //nM:= nLen Div 4;  //4位数一组
            if ((nLen % 4) != 0) nM++;                  //if (nLen Mod 4)<> 0 then Inc(nM); //如果不足4位,则+1防止遗漏
            for (int j = 1; j <= nM; j++)               //For J:= 1 to nM do Begin               //外围,万、亿、兆、吉
            {
                int n2 = Str.Length;
                if (n2 >= 4) n2 = 4;
                s = Str.Substring(Str.Length - n2, n2); //s:= Copy(Str, Length(Str) + 1 - 4, 4);   //从后边取4位数
                Str = Str.Substring(0, Str.Length - n2);//Str:= Copy(Str, 1, Length(Str) + 0 - 4); //缩短主要部分
                //处理取到的4位数
                int nZTime = 0;
                string s4 = "";
                for (int i = 1; i <= s.Length; i++)      //For i:= 1 to Length(s) + 1 do Begin
                {
                    s2 = s.Substring(i - 1, 1);         //s2:= Copy(s, i, 1);//取某位数
                    n = Convert.ToInt16(s2);            //n:= StrToIntDef(s2, 0);
                    if (n == 0) nZTime++;               //if n = 0 then Inc(nZTime)//如果数字是零,则将0数递增
                    else
                    {   //Else Begin                    //非零
                        if (nZTime > 0) s4 += "零";     //if nZTime > 0 then s4:= s4 + '零';
                        s4 += sNum[n - 1];              //s4:= s4 + sNum[n];//数字转字符
                        n = s.Length - i;               //n:= Length(s) + 1 - i + 0;       //‘’、拾、百、千
                        s4 += sMulti[n];                //s4:= s4 + sMulti[n];
                        nZTime = 0;                     //nZTime:= 0;//重置0记数
                    }   //End;
                }   //End;
                加上汉语万、亿、兆、吉标头
                if (!string.IsNullOrEmpty(s4)) s4 += sTitle[j - 1]; //if s4 <> '' then s4:= s4 + sTitle[J];
                sInt = s4 + sInt;                       //sInt:= s4 + sInt;
            }//End;
            if (sInt != "") sInt += "元";               //if sInt <> '' then sInt:= sInt + '元';
            完成,组合整数和小数
            if (num < 0) result = "负";                 //if Num < 0 then Result:= '负';
            result += (sInt + sDec).Trim();             //Result:= Result + Trim(sInt + sDec);
            if (sInt != "" && sDec == "") result += "整";//if Result <> '' then Result:= Result + '整';

            //完成
            return result;
        }
        #region //chinaMoney原来delphi下的版本,稳定运行了多年
        /*
         //中国金额1
Function ChinaMoney(const Num:Real;sSpaceChar:String=''):String;       //将数字金额转为中文金额大写
Var s,s2,s4, Str, sDec, sInt:String; 
    sTitle:Array[1..6] of string;     //万、亿、兆、特、吉
    sDecimal:Array[1..4] of String;   //角、分、毫、厘
    sMulti:Array[1..4] of string;     //千百拾
    sNum  :Array[1..10] of String;    //壹、贰、叁。。。
    i,j,k,n, nPoint, nLen, nM, nzTime:integer;
Begin
    if num=0 then begin
        result:='零';
        exit;
    end;
    //定义数字
		sNum[1]:='壹';
		sNum[2]:='贰';
		sNum[3]:='叁';
		sNum[4]:='肆';
		sNum[5]:='伍';
		sNum[6]:='陆';
		sNum[7]:='柒';
		sNum[8]:='捌';
		sNum[9]:='玖';
		sNum[10]:='拾';
    //定义小数部分
		sDecimal[1]:='厘';
		sDecimal[2]:='毫';
		sDecimal[3]:='分';
		sDecimal[4]:='角';
    //定义每4位一组的标题
		sMulti[1]:='';
		sMulti[2]:='拾';
		sMulti[3]:='佰';
		sMulti[4]:='仟';
    //定义每4位一组的汉语标志
		sTitle[1]:='';
		sTitle[2]:='万';
		sTitle[3]:='亿';
		sTitle[4]:='兆';
		sTitle[5]:='吉';
		sTitle[6]:='特';
    //初始化
    Str:=FloatToStr(ABS(Num));
    nPoint:=Pos('.',Str);
    if nPoint=0 then nPoint:=Length(Str)+1;
    //取小数部分    
    sDec:='';
    s:=Trim( Copy(Str,nPoint+1,4) );
    If s<>'' then Begin
        if Length(s)<4 then While Length(s)<4 do s:=s+'0';
        FOR i:=4 downto 4-Length(s)+1 do Begin
	          s2:=Copy(s,Length(s)-i+1,1);
            n:=StrToIntDef(s2,0);
            If n=0 then s2:='' else s2:=sNum[n]+sDecimal[i];
            sDec:=sDec+s2;
        End;
    End;
    //整数部分,4位一组。编程注意:Length(Str)取出的长度总是少1位
    sInt:='';
    Str:=Copy(Str,1,nPoint-1);
    nLen:=Length(Str)+1;
    nM:=nLen Div 4;                       //4位数一组
    if (nLen Mod 4)<>0 then Inc(nM);      //如果不足4位,则+1防止遗漏
    For J:=1 to nM do Begin               //外围,万、亿、兆、吉
        s:=Copy(Str,Length(Str)+1-4,4);   //从后边取4位数
        Str:=Copy(Str,1,Length(Str)+0-4); //缩短主要部分
        //处理取到的4位数
        nZTime:=0;
        s4:='';
        For i:=1 to Length(s)+1 do Begin
            s2:=Copy(s,i,1);              //取某位数
            n:=StrToIntDef(s2,0);
            if n=0 then                   //如果数字是零,则将0数递增
                Inc(nZTime)
            Else Begin                    //非零
                if nZTime>0 then s4:=s4+'零';
                s4:=s4+sNum[n];           //数字转字符
                n:=Length(s)+1-i+0;       //‘’、拾、百、千
                s4:=s4+sMulti[n];
                nZTime:=0;                //重置0记数
            End;
        End;
        //加上汉语万、亿、兆、吉标头
        if s4<>'' then s4:=s4+sTitle[J];
        sInt:=s4+sInt;
    End;
    if sInt<>'' then sInt:=sInt+'元'; 
    //完成,组合整数和小数
    if Num<0 then Result:='负';
    Result:=Result+Trim(sInt+sDec);
    if Result<>'' then Result:=Result+'整';
End;
*/
        #endregion
        #endregion


    }

}

//为兼容设计的
namespace iPublic
{
    public partial class iDefine
    {
        public class ChuLiJieGuo
        {
            public int error = -1;
            public string message = "";
        }
    }
    public partial class iPublicX
    {
        #region //PlaySound,播放声音,传入声音文件播放,用法:PlaySound("ding.wav", IntPtr.Zero, (int)(PlaySoundFlags.SND_ASYNC | PlaySoundFlags.SND_FILENAME));
        /// <summary>
        /// PlaySound,播放声音,传入声音文件播放,用法:
        ///     PlaySound("提示时奏幻想空间.WAV", 0, SND_ASYNC|SND_FILENAME);
        ///     PlaySound("ding.wav", IntPtr.Zero, (int)(PlaySoundFlags.SND_ASYNC | PlaySoundFlags.SND_FILENAME));
        /// windowsPC下引用[DllImport("Wimm.dll")],在移动设备上引用:[DllImport("Coredll.dll")]
        /// </summary>
        /// <param name="pszSound">声音文件,例如:"ding.wav", "\\Program Files\\music.wav"</param>
        /// <param name="hmod">IntPtr.Zero</param>
        /// <param name="fdwSound">PlaySoundFlags参数</param>
        /// <returns></returns>
        [DllImport("winmm.dll")]
        public static extern bool PlaySound(string pszSound, IntPtr hmod, UInt32 fdwSound);
        #endregion


        #region //PlaySoundFlags,播放声音的参数
        public enum PlaySoundFlags
        {
            /// <summary>
            /// 同步播放声音,play synchronously (default)
            /// </summary>
            SND_SYNC = 0x0000,          /* play synchronously (default) */
            /// <summary>
            /// 异步播放声音,plaSmartHomey asynchronously
            /// </summary>
            SND_ASYNC = 0x0001,         /* plaSmartHomey asynchronously */
            /// <summary>
            /// 沉默,silence (!default) if sound not found
            /// </summary>
            SND_NODEFAULT = 0x0002,     /* silence (!default) if sound not found */
            /// <summary>
            /// 播放声音指向内存文件,pszSound points to a memory file
            /// </summary>
            SND_MEMORY = 0x0004,        /* pszSound points to a memory file */
            /// <summary>
            /// 循环播放声音直到下一个指令,loop the sound until next sndPlaySound
            /// </summary>
            SND_LOOP = 0x0008,          /* loop the sound until next sndPlaySound */
            /// <summary>
            /// 任何时候都不停止播放,don't stop any currently playing sound
            /// </summary>
            SND_NOSTOP = 0x0010,        /* don't stop any currently playing sound */
            /// <summary>
            /// 如果声卡驱动忙也不等待,don't wait if the driver is busy
            /// </summary>
            SND_NOWAIT = 0x00002000,    /* don't wait if the driver is busy */
            /// <summary>
            /// 名称是注册别名,name is a registry alias
            /// </summary>
            SND_ALIAS = 0x00010000,     /* name is a registry alias */
            /// <summary>
            /// 别名是预定义ID,alias is a predefined ID
            /// </summary>
            SND_ALIAS_ID = 0x00110000,  /* alias is a predefined ID */
            /// <summary>
            /// 名字是文件名,name is file name
            /// </summary>
            SND_FILENAME = 0x00020000,  /* name is file name */
            /// <summary>
            /// 名字是资源或者原子,name is resource name or atom
            /// </summary>
            SND_RESOURCE = 0x00040004   /* name is resource name or atom */
        }
        #endregion
    }
}

namespace Gs_Class
{
    public class GsDefineTypes
    {
        public static bool GlobalTerminateWorking = false; //全局终止标志
    }
}

 

代码及语音文件下载地址:https://download.csdn.net/download/gssystems/11964879

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值