缺血还是补血

mikel阅读(853)

企业要生存需要资金,要发展需要资金,雇佣员工需要资金,每日运营需要资金。。。。

所有都归拢到资金上,资金就成了命!

有些从融资中获得资金,作为血液流淌入企业中来维持企业的生存发展。

最 近股市同样是跌宕起伏,多少人三天大跌下像是被股市洗劫一空似的,卷走了一辈子的积蓄,还欠了外债。为什么会这样,因为企业需要钱,实体经济不景气,从银 行贷不出款,怎么办?想办法从股市套现吧!于是,各种企业纷纷涌向创业版,纷纷上市 增发股票,于是热钱涌入股市,股市一路牛市。

从P2P到各种理财产品,都是在钱上想办法再投资获利,拿别人的钱赚钱,然后维持自身发展。

[硬件项目] 1、汽车倒车雷达设计——基于API8108A芯片简易智能语音模块的设计与实现 - beautifulzzzz - 博客园

mikel阅读(948)

来源: [硬件项目] 1、汽车倒车雷达设计——基于API8108A芯片简易智能语音模块的设计与实现 – beautifulzzzz – 博客园

前言

汽车倒车防碰撞系统是一种辅助汽车泊车装置。低配的由超声波收发电路、回波放大电路、语音提示电路、数码显示、报警及温度补偿电路组成,高配的有时会带有后视视频系统。[1]

    

 

一、工作原理

如下图在汽车的尾部安装4个超声波探头,倒车时,采用往返时间测量法测量汽车尾部到障碍物的距离,通过数码管实时显示距离,当车尾部的超声波探头与障碍物的距离小于设定值的安全值时,通过蜂鸣器报警提示驾驶员。

这里测距一般采用4路超声波传感器分时隙工作,采用往返时间测量法测距,测距原理是当汽车进行倒车时,防碰撞系统开始工作,单片机产生一串 40KHz的矩形波,经4选1模拟开关按时序分别向4路超声波探头传给发射电路,通过超声波换能器发射超声波,同时开启计数器计数,超声波传至障碍物后反 射,反射回来部分超声波被超声波换能器接收并转换成电信号,再经过接收电路滤波、放大、整形后,触发单片机外部中断,产生中断,计数器停止计数,测出超声 波发射脉冲串到接收回波信号的时间差 t,并根据超声波在空气中传播的速度v,得出被测距离:

S=vt/2

由于声速会受到环境温度的影响,温度与声速的关系为:

v≈v0+0.607T

式中:v0=332m/s为0℃时的声波速度;T为当前的环境温度。因此只需要通过温度传感器测出T即可得到S的修正值。通过比较选取的4路信号中 的最短距离进行显示,当显示值小于设定警报值时,单片机控制蜂鸣器发出报警声音,随着距离越来越近,报警声音频率越大,同时显示部分两侧的条形数码管显示 条数量增加以表示危险级别。最大测量距离与超声波传感器性能、驱动电路、回波放大电路等因素相关。

 

二、主要模块介绍

系统主要模块包括:显示模块、语音报警和四探头测距模块(MCU负责整体逻辑协调、温度测量可采用数字式也可采用热敏电阻、蜂鸣器报警可以直接由 MCU控制)。此外显示模块设计没有难点,如果为了追求绚丽可以考虑采用TFT屏;语音模块这里引入一个API8108A语音芯片介绍、测距先简单介绍几 种方案(后面会细讲)。

 

三、具体模块详解

API8108A、API8108A(一次性编程语音系列)[2]

>_<: (介绍)10、 20秒多功能可编程语音电路是采用大规模CMOS芯片技术制造的最新ASIC专用语音电路。它们内部包含语音处理器、EPROM存储器、A/D、D/A数 模转换器、逻辑接口控制器、音频放大器、时钟振荡器等大量部件,能完成从语音数据写入固化到语音高保真重放的全过程工作,外围秩序几只元件即可。过去这种 电路常采用8031、2764、DA0832等IC组合完成,体积大、耗电大、成本高,现在API8108A、API8208A比常规语音处理电路设计要 结构简单、体积微小的多,而成本只是过去的五分之一。

API8108A、API8208A可根据需要分为一至八段录放,其语音可以最大不重复时间分别为10秒和20秒,重复部分可不计算时间。其语音录 入需要专门的计算机编程器上进行,一旦录入即成为固定数据,不能再更改或抹掉,永久保存。固化了语音之后的API8108A、API8208A在放音使用 上和普通的音乐集成片一样简单,只是发出的不是单调的音符曲调,而是极其逼真的话语模拟声响,其效果经计算机软件处理可与磁带、CD媲美。

>_<: (工作要求)其电源电压为:2.6~6V,静态耗电<5uA,工作温度:-10度~60度,储存温度:-55度~125度,发光管驱动电路:8mA。

>_<: (引脚说明)1、5、6编程 选择脚;2、3电压放大推挽输出,外接蜂鸣器或喇叭;4电源接地端;7电流放大输出,外接三极管放大推动喇叭;8外接振荡电阻,决定放音速度;9编程电源 端;12电源接正端;10、11、13、14发音触发器,高电平有效,组合控制8段;15单键触发端,高有效使所有的段顺序放音;16放音停止端,高电平 使放音中断停止。

编程引脚OUT1、OUT2、OUT3功能选择:

※STP指OUT输出15ms的停止脉冲,(也可推另一片语音IC,以增加语音长度)

※BUSY指OUT输出忙信号,推动马达或其它

语音分段控制选择:(L表示接正触发,N表示不接)

放音频率、振荡电阻(ROSC)与放音时间选择:

>_<: (基础应用)基础电路应用:

① COUT输出驱动喇叭 && VOUT输出驱动蜂鸣偏或喇叭

② 八段触发控制(见上表)

③ 两片串联加长语音长度

④ 带LED的电路

>_<: (时序波形)时序波形示意图:

1. Level, Unholdable, Non-retriggerable(电平的、非保持的、非触发的)

展示了两种情况:触发的时长小于一个Group的播放时长和触发时长超过一个Group的播放时长。可见小于的情况在一个Group的时间内多个触发只起单个作用,当大于Group时长的触发会导致Group再次启动。

2. Level Holdable(电平保持)

展示了两种情况:(和上面一样。当小于时,播放会直接停止;当大于时,播放会重新开始同样也会戛然而止。

3. Single Button Trigger (SBT), Sequential(这是一个按钮的控制情况)

这是Level Unholdable情况的长短两种情况,可见:SBT每次触发会进行一次Group的切换,直到第8个又重新从第1个开始,如果某一个SBT信号持续时间超过当前播放一组的时长,会导致该组重复播放,直至SBT切换。

这是Level Holdable情况的长短两种情况,可见:类似与上面的Level Unholdable情况,只是会出现截止情况。

4. Edge,Unholdable,Non-retritggerable(边缘触发的、非保持的、非触发的)

和上面1的电平触发的比较可以看出当触发时长保持超过Group的时长时,仍然播放一次。

5. Edge Holdable

和上面2的电平保持比较可以发现当触发时长保持超过Group的时长时,仍然播放一次。

6. Single Button Trigger (SBT), Sequential(这是一个按钮控制的情况)

这是Edge Unholdable应和3的Level Unholdable比较发现这仍然是Edge触发的特点:当时长超过时,仍然只播放一次。

同样的Edge Holdable不再说明。

>_<: (使用注意事项)

编程烧写语音芯片时注意:语音芯片型号要与软件相对应,不可互相混淆。
烧写时注意:首先检测是否空片,是空片再开始烧写;OPT芯片不可多次烧写不用的内容。
API8108A、840N语音芯片烧写采用6V供电,API8208A语音芯片采用5V供电(可以采用ADAPTOR转换烧写电压)。

>_<: (具体应用)[3] 

AT89C205除了在外部引脚上少了两个并口外,其他资源与AT89C52完全相同,且内部的2KFLASHROM能够很方便的进行擦写。该单片 机的P1口是一个8位双向I/O口,其中P1.2~P1.7口内部提供上拉电阻,P1.0和P1.1需要外接上拉电阻。P1.0和P1.1同时也是片内精 确模拟比较器的正输入端(AIN0)和负输入端(AIN1)。P3口是7个带有内部上拉电阻的双向口(P3.6除外)。

为了提高音量,在该设计中加入了音频放大芯片LM386。LM386是美国国家半导体公司生产的音频放大器,主要应用于低电压消费类产品。为使外围 元件最少,电压增益内置为20,如果在1脚和8脚之间增加一只外接电阻和电容,便可将电压增益调为任意值,直至200。输入端以地为参考,同时输出端被自 动偏置到电源电压的一半,在6V电源电压下,它的静态功耗仅仅为24mW,所以它是一种低电压小功率的音频功放集成电路,采用8脚双列直插式封装,第6脚 为电源正极,第4脚接地,第2、3脚为选择输入端,第5脚为输出端,第1、8脚为增益控制端,第7脚为旁路端。它具有共组电压宽(4~12V)、静态耗电 少、电压增益可调(20~200)、外接元件少、频带宽(300KHz)、低失真度。

整个电路图如上图:单片机的P3口控制API8108A的TG1~TG4,用来控制语音的分段输出。R4为语音模块的振荡电阻,其余放音时间的关系 见上面的表格。在本设计中选用200千欧,放音时间为9s左右。由于U3的1脚和8脚之间只连接10微法的电容,此音频放大倍数为200倍。通过R2还可 以调节音量大小,如果想降低音量,只需在U3的3脚连接一个电位器和R2进行分压即可。

播放语音已经预先录制好,存放在API8108A语音芯片的各单元中,语音播放程序首先完成语音地址计算,将语音地址存放在缓冲区中,待全部算完, 建立结束标志,然后启动定时器,每隔0.3s输出一个地址信号,完成语音输出,如要播放“欢迎光临”,根据该数据,调用语音地址计算子程序,将“欢” “迎”语音地址存入缓冲区30H和31H中。依次类推,直至结束,再在缓冲区依次间隔0.3s时间取出语音地址,直至遇到结束标志。

 

四、小结

最近一直没有写东西了,三四月份忙着导师的项目、五月份忙着找工作、六月份忙着复习考试(其实明天还有考试,复习烦了遂来写点东西,嘻嘻)。翻来覆 去发现还是把这个有趣的汽车倒车雷达的设计同大家分享吧,本部分将倒车雷达电路系统中的语音模块大致讲述了一下,接下来还要对其测距电路进行分析设计(其 实以前我已经对超声波测距进行了比较细致的研究啦4个哦:点这看看)。

 

 

链接

[1] 一种倒车防碰撞系统的设计与实现(张安然):http://pan.baidu.com/s/1dDGrGbR

[2] API8108A的datasheet:http://pan.baidu.com/s/1bn2i7UJ

[3] 简易智能语音模块的设计与实现(李世红)(蒋海潮):http://pan.baidu.com/s/1o6GFrK2

其他资料(私用):http://pan.baidu.com/s/1o6HvpJO

不能释怀 看淡事事

mikel阅读(1157)

今天,女儿幼儿园最后一天,女儿很感性,临走和老师告别的时候,眼里含泪舍不得老师。

自己也被感动了。

看来自己还是不能看淡事事,不能释怀感情。

 

少想多做 多点儿执行少点儿疑问

mikel阅读(1019)

很多时候我喜欢犯一个毛病,就是总是想得太多,做得太少。想法层出不穷,真正做了的很少,或者做了也是半途而废,做着做着又有新的想法,于是打断或者不做这个了,觉得这个没什么价值,又去做别的,或者想别的。还有或多或少这里面都会有别人的影响在里面,结果手里面的项目大多是半吊子,没有结果也没有价值。

很多时候,真正认真做一件事儿,并把它做完的,真的是一件难能可贵的事儿!

少想多做,少问那么多为什么或者怎么做,做就是了!遇到问题,解决问题,一门心思的把它做出来,扔到市场上去接受考验吧!只有这样才能不荒废时间还没有结果。

时间对于互联网创业的人来说很宝贵,宝贵到什么程度,比如你全职互联网创业,你以往打工积累的积蓄只够提供你全职在家干一个月的生活保障,怎么在这一个月里赚到下个月的生活费,就要有时间管理观念还有执行力,否则短短的一个月过去了,你不得不面对断粮的窘迫问题。

互联网人缺乏的不是执行,反倒是想法太多,执行被迷惑在众多想法中失去了它应有的效率和能力。

ASP.NET MVC 自定义错误页面心得 - kavensu - 博客园

mikel阅读(1088)

来源: ASP.NET MVC 自定义错误页面心得 – kavensu – 博客园

自定义错误页面的目的,就是为了能让程序在出现错误/异常的时候,能够有较好的显示体验。

所以,首先要先了解,我们可以在哪里捕获异常。

当程序发生错误的时候,我们可以在两个地方捕获:

  1. Global里面的Application_Error 。
  2. HandleErrorAttribute 中的OnException。(需要新建一个类,继承HandleErrorAttribute)

那我们到底应该在哪里处理错误好呢?下面我来给大家说说他们的区别。

Application_Error

程序中发生的所有异常,都可以在这里捕获。但是有一个不足的地方,那就是,如果我们在这里捕 获异常之后,需要显示错误页面,那么浏览器上的地址是会改变的,已经被重定向了。也就是说,浏览器上显示的地址,并不是真正发生错误的地址,而是仅仅是显 示错误信息的页面地址。这个不足,跟在Web.config的customError中配置错误页面是一样的。

很多时候,我们是希望在访问某个URL后发生了错误,显示错误页面之后,URL还是不变。因此,在这里处理异常并不能满足这种需求。

OnException。(继承HandleErrorAttribute)

MVC的特点就是,每一个请求都对应一个Controller,当在某个Controller中发生异常时,我们都可以在OnException中捕获。但是,如果根本就找不到这个Controller,那么这种错误OnException就无能为力了。举个例子:

假设有个Controller叫About,当访问http://host/About/Index发生错误时,是可以在OnException中捕获的。但如果我访问http://host/Aboute/Index的时候,因为根本不存在Aboute控制器,所以这种错误是无法在OnException捕获的,如果要捕获这种错误,只能在Application_Error中处理。虽然OnException不能捕获所有的错误,但是,它可以解决Application_Error错误页面重定向的问题,在显示错误页面的时候,URL保持不变。

 

执行顺序

如果发生了错误,会先执行OnException,如果设置 filterContext.ExceptionHandled = true; 则说明该错误已被错误,不会再执行Application_Error,否则会继续执行Application_Error。

 

参考代码

复制代码
 protected void Application_Error(Object sender, EventArgs e)
        {
            //当路径出错,无法找到控制器时,不会执行FilterConfig中的OnException,而会在这里捕获。
            //当发生404错误时,执行完OnException后,还会执行到这里。
            //当发生其他错误,会执行OnException,但在base.OnException中已经处理完错误,不会再到这里执行。
            var lastError = Server.GetLastError();
            if (lastError != null)
            {
                var httpError = lastError as HttpException;

                if (httpError != null)
                {
                    //Server.ClearError();
                    switch (httpError.GetHttpCode())
                    {
                        case 404:
                            Response.Redirect("/Views/Static/404.html");
                            break;
                    }
                }
            }
}
复制代码

 

复制代码
    [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
    public class LogExceptionAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            string controllerName = (string)filterContext.RouteData.Values["controller"];
            string actionName = (string)filterContext.RouteData.Values["action"];
            HandleErrorInfo info = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);

            HttpRequestBase request = filterContext.RequestContext.HttpContext.Request;
            string broser = request.Browser.Browser;
            string broserVersion = request.Browser.Version;
            string system = request.Browser.Platform;
            string errBaseInfo = string.Format("UserId={0},Broser={1},BroserVersion={2},System={3},Controller={4},Action={5}", AuthAttribute.GetUserId(), broser, broserVersion, system, controllerName, actionName);
            LogUtil.Error(errBaseInfo, filterContext.Exception, Website.LOG_ID);

            if (!filterContext.ExceptionHandled)
            {
                if (filterContext.HttpContext.IsCustomErrorEnabled)
                {
                    filterContext.HttpContext.Response.Clear();
                    HttpException httpex = filterContext.Exception as HttpException;
                    if (httpex != null)
                    {
                        filterContext.HttpContext.Response.StatusCode = httpex.GetHttpCode();
                        // info = new HandleErrorInfo(ex, controllerName, actionName);
                        //switch (httpex.GetHttpCode())
                        //{
                        //    case 403:
                        //        break;
                        //    case 404:
                        //        break;
                        //    default:
                        //        base.OnException(filterContext);
                        //        break;
                        //}
                    }
                    else
                    {
                        filterContext.HttpContext.Response.StatusCode = 500;
                    }

                    filterContext.Result = new ViewResult() { ViewName = "/Views/Shared/Error.cshtml", ViewData = new ViewDataDictionary<HandleErrorInfo>(info) };
                    filterContext.ExceptionHandled = true;
                    filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
                }
                else
                {
                    //base.OnException(filterContext);
                   // return;
                    //当customErrors=Off时
                    //当customErrors = RemoteOnly,且在本地调试时
                    filterContext.Result = new ViewResult() { ViewName = "/Views/Shared/ErrorDetails.cshtml", ViewData = new ViewDataDictionary<HandleErrorInfo>(info) };
                    filterContext.ExceptionHandled = true;
                    filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
                }
            }

        }
    }
复制代码

 

[emerg]: bind() to 0.0.0.0:80 failed (98: Address already in use)

mikel阅读(894)

[emerg]: bind() to 0.0.0.0:80 failed (98: Address already in use)   这个是nginx重启是 经常遇到的。   网上找了很多信息 都是没有啥用。说的乱七八糟的。   发现原来是nginx重复重启。自己占用了端口。 解决
方法  killall -9 nginx 杀掉nginx 进程  然后重启就行了。  service nginx restart
这样就解决了。

我不用你 与你无关

mikel阅读(1075)

其实这个问题挺悲壮的,为什么这么说?因为针对的是那些站长们,特别是草根站长们,建网站不容易运营更难,还要做内容,做流量,做SEO,然后最重要的就是盈利活着。

盈利无外乎几种收广告费、做会员收费、卖产品。可偏偏这些都是有流量有排名的基础上才能达成的。

用户体验只不过是一句空话,所以说用户来了发现满站的广告和推广,直接关闭网页,我不用你与你无关。苦的还是站长,一边是盈利一边是流量损失,如何权衡真的不是一时半会儿能道清的。

互联网就是这样,站长如此痛苦,做app开发的个人开发者同样如此,辛苦做的应用,好不容易审核通过上架了没有排名就谈不上盈利,好不容易做上排名了,用户觉得你插广告赚钱了,不好用直接卸载了。现在人的耐心就那么3秒,看到广告比看到蟑螂还反应强烈,直接卸载,同样是我不用你与你无关。

BAT的战略更加是我消灭你 与你无关的套路,你做起来了,直接山寨一个比你强的,烧钱把你消灭了,问都不问你的感受。好点儿的,先跟你谈招安。

要想真的做到老乔的苹果地步每个偏执狂的精神和舍我其谁的架势和资源,真不行。

抱团儿还不见得干得过BAT和更加恶略的类似神州专车的流氓营销策略呢,更别说草根儿个人站长和开发者了。风投更加是见风使舵,无利不起早的,台风挺大,人家也要看你能赚几个钱才会投你。

小问题大成本

mikel阅读(1052)

今天很多事儿需要做,很多事儿又着急做,结果堆在一起,像个气球一样被挣得满满的一天,至今还有很多待办的事情堆着,每个头绪。

为什么这么多事解决不了,就是因为一个小小的技术问题,很多时候不是因为大事儿,反而是一个小问题就会浪费一大半的时间,还必须得解决,绕不过去,时间和效率都被迫降下来了。

为什么造成这种结果?就是因为没有积累过去的经验,其实也没什么就是导出excel乱码的问题,过去做过类似的功能,结果怎么解决的忘了,又得从头再来,要是有现成的解决代码,直接拿来用就可以秒杀了这个问题。于是解决后,迫不及待的写到博客中,以免日后查看。

所以说不论好脑筋不如烂笔头,很多时候动动手记录下来总比没记录强,日后谁知道哪天用上呢?!

再说说成本问题,大半天的时间成本再加上耽误的事儿没做的成本,那就大了去了。

不单单是技术问题,折射到网络上的推广等等行业都是一样,做SEO的要做笔记,有新的体验就要记录下来,日后再查找很容易,就可以按经验来做就行了。

做网赚项目也要有笔记,怎么做的一步步记录下来,遇到类似的项目可以轻车熟路降低成本,少走弯路,毕竟大家都很忙,没时间走老路。

这次事件引以为戒,养成记录的好习惯。

[原创]ASP.NET MVC导出Excel 避免身份证号码格式乱码

mikel阅读(1316)

ASP.NET MVC导出Excel 避免身份证号码格式乱码问题,

利用导出的Excel的脚本增加“vnd.ms-excel.numberformat:@”的style来解决

导出省份证号码的科学计数法的问题


 /// <summary>
 /// 导出Excel文件
 /// </summary>
 /// <param name="ls">数据集</param>
 /// <returns></returns>
 public FileResult ExportExcel(List<EmployeeExcel> ls)
 {
 var sbHtml = new StringBuilder();
 sbHtml.Append("<table border='1' cellspacing='0' cellpadding='0'>");
 sbHtml.Append("<tr>");
 var lstTitle = new List<string> ();
 PropertyInfo[] properties = typeof(EmployeeExcel).GetProperties();
 for (int i = 0; i < properties.Length; i++)
 {
 string headName = properties[i].Name;
 Attribute attribute = Attribute.GetCustomAttribute(properties[i], typeof(DisplayNameAttribute));
 if (attribute != null)
 {
 DisplayNameAttribute displayNameAttribute = attribute as DisplayNameAttribute;
 if (displayNameAttribute != null && !string.IsNullOrWhiteSpace(displayNameAttribute.DisplayName))
 {
 headName = displayNameAttribute.DisplayName;
 }
 }

 lstTitle.Add(headName);
 }
 foreach (var item in lstTitle)
 {
 sbHtml.AppendFormat("<td style='font-size: 14px;text-align:center;background-color: #DCE0E2; font-weight:bold;' height='25'>{0}</td>", item);
 }
 sbHtml.Append("</tr>");
 for (int i = 0; i < ls.Count; i++)
 {
 sbHtml.Append("<tr>");
 for (int j = 0; j < properties.Length; j++)
 {
 string sign = j == properties.Length - 1 ? "\n" : "\t";
 object obj = properties[j].GetValue(ls[i], null);
 sbHtml.AppendFormat("<td style='font-size: 12px;height:20px;vnd.ms-excel.numberformat:@'>{0}</td>", obj);
 }
 sbHtml.Append("</tr>");
 }
 sbHtml.Append("</table>");

 //第一种:使用FileContentResult
 byte[] fileContents = Encoding.Default.GetBytes(sbHtml.ToString());
 DateTime time = DateTime.Now;
 String fileName = string.Format("{0}_{1}_{2}_{3}",
 time.Month, time.Day, time.Hour, time.Minute);
 return File(fileContents, "application/ms-excel", fileName+".xls");

 }

Asp.Net MVC 使用FileResult导出Excel数据文件 - mr3 - 博客园

mikel阅读(1399)

来源: Asp.Net MVC 使用FileResult导出Excel数据文件 – mr3 – 博客园

前几天一个MVC3.0项目做了一个Excel导出功能,今天来记录一下. 采取了最简单的方法.
用的是Html拼接成Table表格的方式,返回 FileResult 输出一个二进制的文件.

第一种:使用FileContentResult


//
// 摘要:
//     通过使用文件内容,内容类型,文件名称创建一个FileContentResult对象//
// 参数:
//   fileContents:
//     响应的二进制文件内容
//
//   contentType:
//     内容类型(MIME类型)
//
//   fileDownloadName:
//     显示在浏览器下载窗口的文件名称//
// 返回结果:
//     文件内容对象.
protected internal virtual FileContentResult File(byte[] fileContents, string contentType, string fileDownloadName);

需要将文件内容转化成字节数组byte[]

<pre>byte[] fileContents = Encoding.Default.GetBytes(sbHtml.ToString());

第二种:使用FileStreamResult

// 其他参数描述同FileContentResult
        // 参数:
        //   fileStream:
        //     响应的流
        // 
        // 返回结果:
        //     文件流对象.
        protected internal virtual FileStreamResult File(Stream fileStream, string contentType, string fileDownloadName);

需要将文件内容转化成流

</pre>
<pre>      var fileStream = new MemoryStream(fileContents);

第三种:使用FilePathResult

// 其他参数描述同FileContentResult
        // 参数:
        //   fileName:
        //     响应的文件路径
        //
        // 返回结果:
        //     文件流对象.
     protected internal virtual FilePathResult File(string fileName, string contentType, string fileDownloadName);

服务器上首先必须要有这个Excel文件,然会通过Server.MapPath获取路径返回.

具体详情请看代码.


ExportExcel Code
public FileResult ExportExcel()
{
var sbHtml = new StringBuilder();
sbHtml.Append("&lt;table border='1' cellspacing='0' cellpadding='0'&gt;");
sbHtml.Append("&lt;tr&gt;");
var lstTitle = new List&lt;string&gt; { "编号", "姓名", "年龄", "创建时间" };
foreach (var item in lstTitle)
{
sbHtml.AppendFormat("&lt;td style='font-size: 14px;text-align:center;background-color: #DCE0E2; font-weight:bold;' height='25'&gt;{0}&lt;/td&gt;", item);
}
sbHtml.Append("&lt;/tr&gt;");

for (int i = 0; i &lt; 1000; i++)
{
sbHtml.Append("&lt;tr&gt;");
sbHtml.AppendFormat("&lt;td style='font-size: 12px;height:20px;'&gt;{0}&lt;/td&gt;", i);
sbHtml.AppendFormat("&lt;td style='font-size: 12px;height:20px;'&gt;屌丝{0}号&lt;/td&gt;", i);
sbHtml.AppendFormat("&lt;td style='font-size: 12px;height:20px;'&gt;{0}&lt;/td&gt;", new Random().Next(20, 30) + i);
sbHtml.AppendFormat("&lt;td style='font-size: 12px;height:20px;'&gt;{0}&lt;/td&gt;", DateTime.Now);
sbHtml.Append("&lt;/tr&gt;");
}
sbHtml.Append("&lt;/table&gt;");

//第一种:使用FileContentResult
byte[] fileContents = Encoding.Default.GetBytes(sbHtml.ToString());
return File(fileContents, "application/ms-excel", "fileContents.xls");

//第二种:使用FileStreamResult
var fileStream = new MemoryStream(fileContents);
return File(fileStream, "application/ms-excel", "fileStream.xls");

//第三种:使用FilePathResult
//服务器上首先必须要有这个Excel文件,然会通过Server.MapPath获取路径返回.
var fileName = Server.MapPath("~/Files/fileName.xls");
return File(fileName, "application/ms-excel", "fileName.xls");
}