zoukankan      html  css  js  c++  java
  • silverlight 导出Excel

    一、前因

          因为项目中需要在silverlight 中导出Excel文件,所以就在琢磨这个事情了,开始时候的想法是能不能通过js 导出excel,在网上查了资料,试了所有找到的方法,可惜没有一个成功的。想不出其他办法,只能绕着走了,可能有点蠢,呵呵。不知道大家是怎么解决的,我把自己的发出来,抛砖引玉,不恰当的地方欢迎指出。

     

    二、具体实现

          整个解决方案包括以下几个项目,如图:

     

    其中的BLL,Enity项目只是提供一个示例,没多大用处。ExcelExport项目中的SearchParam.cs文件中包含查询参数类,以及导航处理类。导航处理类主要是根据传入的参数集合、导出类型生成查询字符串,并传给Export.ashx处理。代码如下:

    代码
    /// <summary>
        
    /// 查询参数类
        
    /// </summary>
        public class SearchParam
        {
            
            
    public string Value { getset; }
            
            
    public object Name { getset; }

            
    public SearchParam(string value, string name)
            {
                Value 
    = value;
                Name 
    = name;
            }

            
    public override string ToString()
            {
                
    return Value + "_" + Name;
            }
        }

        
    /// <summary>
        
    /// 导出处理
        
    /// </summary>
        public class ExportHandle
        {
            
    /// <summary>
            
    /// 获取查询字符串
            
    /// </summary>
            
    /// <param name="searchParams">参数集合</param>
            
    /// <returns></returns>
            private static string GetQueryString(IEnumerable<SearchParam> searchParams)
            {
                StringBuilder builder 
    = new StringBuilder("condition=");
                
    foreach (var param in searchParams)
                {
                    builder.Append(param.ToString() 
    + " ");
                }
                
    return builder.ToString().TrimEnd();
            }

            
    /// <summary>
            
    /// 导出处理 
            
    /// </summary>
            
    /// <param name="paramCollection">参数集合</param>
            
    /// <param name="action">导出类型</param>
            public static void Action(SearchParam[] paramCollection, string action)
            {
                
    string paramString = GetQueryString(paramCollection);
                var uriInfo 
    = HtmlPage.Document.DocumentUri;
                var path 
    = uriInfo.AbsoluteUri.Replace(uriInfo.AbsolutePath, "");
                
    string uriString = string.Concat(path, "/Export.ashx?""action=", action, "&", paramString);
                HtmlPage.Window.Navigate(
    new System.Uri(uriString, UriKind.Absolute));
            }
        }

           在项目ExcelExport.Web中增加了一个导出处理,用来将传入的参数进行处理,并发送到WCF服务获取导出信息,然后以excel格式返回。其中存在一个正则表达式处理类,用来对查询字符串处理返回查询参数集合。代码如下:

    代码
    /// <summary>
        
    /// $codebehindclassname$ 的摘要说明
        
    /// </summary>
        [WebService(Namespace = "http://tempuri.org/")]
        [WebServiceBinding(ConformsTo 
    = WsiProfiles.BasicProfile1_1)]
        
    public class Export : IHttpHandler
        {

            
    #region IHttpHandler接口

            
    public void ProcessRequest(HttpContext context)
            {            
                var queryString 
    = context.Request.QueryString;
                
    string action = queryString["action"];
                
    string condition = queryString["condition"];
                var searchParams 
    = GetParams(condition);
                ExportClient client 
    = new ExportClient("WSHttpBinding_IExport");
                
    string content=client.GetExportString(searchParams, action);
                ExportToExcel(context.Response, content,action);
            }

            
    public bool IsReusable
            {
                
    get
                {
                    
    return true;
                }
            }

            
    #endregion


            
    #region 
            
    private SearchParam[] GetParams(string condition)
            {
                
    string pattern = @"\b(\S+)_(\S+)\b";
                IRegular regular 
    = new Regular();
                RegularInfo info 
    = new RegularInfo(condition, pattern, RegexOptions.IgnoreCase);
                var matchs 
    = regular.Filter(info);
                SearchParam[] searchParams
    =new SearchParam[matchs.Length];
                
    int i = 0; SearchParam param;
                
    foreach (Match match in matchs)
                {
                    param 
    = new SearchParam();
                    param.Name 
    = match.Groups[1].Value;
                    param.Value 
    = match.Groups[2].Value;
                    searchParams[i] 
    = param;
                    i
    ++;
                }
                
    return searchParams;
            }

            
    protected void ExportToExcel(HttpResponse response,string content,string action)
            {
                response.Clear();
                response.Buffer 
    = true;
                response.Charset 
    = "GB2312";
                
    //page.Response.Charset = "UTF-8";
                response.AppendHeader("Content-Disposition""attachment;filename=" + action + ".xls");
                response.ContentEncoding 
    = System.Text.Encoding.GetEncoding("GB2312");//设置输出流为简体中文
                response.ContentType = "application/ms-excel";//设置输出文件类型为excel文件。             
                response.Write(content);
                response.End();

            }
            
    #endregion
        }

    正则表达式处理代码:

    代码
    public interface IRegular
        {
            Match[] Filter(RegularInfo info);
        }

        
    /// <summary>
        
    /// 正则表达式处理
        
    /// </summary>
        public class Regular:IRegular
        {

            
    #region IRegular 成员

            
    public Match[] Filter(RegularInfo info)
            {
                var matchCollection 
    = Regex.Matches(info.Source, info.Pattern, info.Options);
                Match[] result 
    = new Match[matchCollection.Count];
                
    int i = 0;
                
    foreach (Match match in matchCollection)
                {
                    result[i] 
    = match;
                    i
    ++;
                }
                
    return result;
            }

            
    #endregion
        }

        
    /// <summary>
        
    /// 正则表达式信息
        
    /// </summary>
        public class RegularInfo
        {
            
    public string Source { getset; }

            
    public string Pattern { getset; }

            
    public RegexOptions Options { getset; }

            
    public RegularInfo(string source, string pattern, RegexOptions options)
            {
                Source 
    = source;
                Pattern 
    = pattern;
                Options 
    = options;
            }
        }

           项目ExportConfig中包括的内容是最重要的,主要分为接口、默认实现、导出处理、查询实体类四部分。接口分别为(1)IExportContent存在两个方法,Print()用来返回一行中各列的值,GetFormat() 返回单元格的样式,这里的样式必须为css样式;(2)IContentIterator内容迭代接口;(3)IExportFactory存在CreateHead,CreateContent两个方法,分别用来返回表头,表内容迭代。默认实现为:ExportContent,ContentAggregate,ContentIterator,ExportAbstractFactory。导出处理放在ExportHandle类。

    接口代码:

    代码
        /// <summary>
        
    /// 内容迭代接口
        
    /// </summary>
        public interface IContentIterator
        {
            
    bool HasNext();
            IExportContent Next();
        }


        
    /// <summary>
        
    /// 内容接口
        
    /// </summary>
        public interface IExportContent
        {
            
    string[] Print();
            
    string GetFormat();
        }


        
    /// <summary>
        
    /// 表信息工厂接口
        
    /// </summary>
        public interface IExportFactory
        {
            IExportContent  CreateHead();
            IContentIterator CreateContent(SearchCollection condition);
        }

    导出处理类:

    代码
     public class ExportHandle
        {
            
    private IExportFactory factory;
            
    public ExportHandle(IExportFactory factory)
            {
                
    this.factory = factory;
            }

            
    public string GetExportString(SearchCollection condition)
            {
                var head 
    = factory.CreateHead();
                StringBuilder build 
    = new StringBuilder("<table>");            
                AppandString(head, build);
                var iterator 
    = factory.CreateContent(condition);
                IExportContent item;
                
    while (iterator.HasNext())
                {
                    item 
    = iterator.Next();
                    AppandString(item, build);
                }
                build.Append(
    "</table>");
                
    return build.ToString();
            }

            
    private void AppandString(IExportContent item,StringBuilder build)
            {
                
                
    string format = item.GetFormat(), value;
                
    bool hasFormat = !string.IsNullOrEmpty(format);
                build.Append(
    "<tr>");
                var stringList 
    = item.Print();                        
                
    foreach (var str in stringList)
                {
                    
    if (hasFormat)
                    {
                        value 
    = string.Format("<td style=\"border-color:Gray; border-thin;border-style:ridge;{0}\">{1}</td>", format, str);
                    }
                    
    else
                    {
                        value 
    = string.Format("<td style=\"border-color:Gray; border-thin;border-style:ridge\">{0}</td>", str);
                    }
                    build.Append(value);
                }
                build.Append(
    "</tr>");            
            }
        }

             最后一个项目ExportService 是用来提供WCF服务的,这里还存在一个设置,可以在web.config中添加导出的类名,以及程序集名称 ,如图:

     

    获取配置信息后,通过反射创建实例。然后将查询参数、实例传给导出处理类进行操作。如下代码所示:

    代码

        [ServiceBehavior]
        [AspNetCompatibilityRequirements(RequirementsMode 
    = AspNetCompatibilityRequirementsMode.Allowed)]
        
    public class Export : IExport
        {

            
    #region IExport 成员        
            
    public string GetExportString(SearchParam[] paramCollection, string action)
            {
                
    string[] infos = ConfigurationSettings.AppSettings[action].Split('|');
                SearchCollection condition 
    = null;
                
    if (paramCollection != null)
                {
                    condition 
    = new SearchCollection();
                    
    foreach (var param in paramCollection)
                    {
                        condition.Add(param);
                    }
                }
                IExportFactory instance 
    = (IExportFactory)CommonHelp.CreateInstance(infos[1], infos[0], null);
                ExportHandle handle 
    = new ExportHandle(instance);
                
    return handle.GetExportString(condition);
            }
            
    #endregion
        }

        
    public class CommonHelp
        {
            
    public static object CreateInstance(string type, string assembly, object[] args)
            {
                
    return Assembly.Load(assembly).CreateInstance(type, true, BindingFlags.Default, null, args, nullnull);
            }  
        }

      

          另外,WCF调用可能存在跨域问题,在IIS网站根目录下放这个clientaccesspolicy.xml文件就OK了。第一次写可能有点乱,觉得还点用,就将就着看下吧,呵呵。完整的Demo下载:

    /Files/WGZ_Home/ExcelExport.rar 

    ——————————————————————————————————————————————————————————————————————————————————

         经(笨笨的猪)朋友的提醒,现在把handle去掉了,并进行了一些小的修改,silverlight直接引用WCF服务,并返回byte[],然后通过SaveDialog保存。修改后的关于silverlight

    处理代码如下:

    代码
            private void click_Click(object sender, RoutedEventArgs e)
            {
                
                ObservableCollection
    <SearchParam> paramCollection = new ObservableCollection<SearchParam>();
                var param
    =new SearchParam();
                param.Name
    ="2";
                param.Value
    ="2";
                paramCollection.Add(param);
                SaveFileDialog dialog
    =new SaveFileDialog();
                ExportHandle(
    "ATPExport", paramCollection, dialog);
               
            }

            
    public static void ExportHandle(string action,ObservableCollection<ExeclExport.Export.SearchParam> paramCollection,SaveFileDialog dialog)
            {            
                
    try  
                {                
                    dialog.DefaultExt 
    = ".txt";   
                    dialog.Filter 
    = "Excel Files|*.xls|Log Files|*.doc";   
                    dialog.FilterIndex 
    = 1;   
                }   
                
    catch ( Exception ex )   
                {   
                    HtmlPage.Window.Alert(ex.Message);
                    
    return;
                }
                
    bool? dialogResult = dialog.ShowDialog();   
                
    if ( dialogResult == true )   
                {  
                    Export.ExportClient client 
    = new ExeclExport.Export.ExportClient();
                    client.GetExportStringCompleted 
    += delegate(object sender, ExeclExport.Export.GetExportStringCompletedEventArgs e)
                    {
                         
    if(e.Error==null)
                         {
                             
    using ( Stream fs =dialog.OpenFile() )   
                             {
                                 var resultBytes 
    = e.Result;
                                 fs.Write(resultBytes, 
    0, resultBytes.Length);
                                 fs.Close();   
                                 HtmlPage.Window.Alert(
    "保存成功");                            
                             }                                          
                             
    return;
                         }
                         client.CloseAsync();
                         HtmlPage.Window.Alert(e.Error.Message);
                    };


                    client.GetExportStringAsync(paramCollection, action);
                }
            }



    完整Demo如下:/Files/WGZ_Home/ExcelExport.rar

  • 相关阅读:
    【C++札记】友元
    【C++札记】const关键字
    【C++札记】实现C++的string类
    【C++札记】拷贝构造函数,浅拷贝和深拷贝
    【C++札记】内联函数
    【C++札记】函数重载
    文章博客导航
    【C++札记】标准输入与输出
    毕业季,学子们又把翟天临推上了热搜!
    【底层原理】高级开发必须懂的"字节对齐"
  • 原文地址:https://www.cnblogs.com/WGZ_Home/p/1709279.html
Copyright © 2011-2022 走看看