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