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

原文地址:https://www.cnblogs.com/WGZ_Home/p/1709279.html