silverlight 导出Excel

一、前因

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

 

二、具体实现

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

 

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

 

ExpandedBlockStart.gif 代码
///   <summary>
    
///  查询参数类
    
///   </summary>
     public   class  SearchParam
    {
        
        
public   string  Value {  get set ; }
        
        
public   object  Name {  get set ; }

        
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格式返回。其中存在一个正则表达式处理类,用来对查询字符串处理返回查询参数集合。代码如下:

 

ExpandedBlockStart.gif 代码
///   <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
    }

 

正则表达式处理代码:

ExpandedBlockStart.gif 代码
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 {  get set ; }

        
public   string  Pattern {  get set ; }

        
public  RegexOptions Options {  get set ; }

        
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类。

接口代码:

ExpandedBlockStart.gif 代码
     ///   <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);
    }

 

导出处理类:

 

ExpandedBlockStart.gif 代码
  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 - width:thin;border - style:ridge;{ 0 }\ " >{1}</td> " , format, str);
                }
                
else
                {
                    value 
=   string .Format( " <td style=\ " border - color:Gray; border - width:thin;border - style:ridge\ " >{0}</td> " , str);
                }
                build.Append(value);
            }
            build.Append(
" </tr> " );            
        }
    }

 

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

 

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

 

ExpandedBlockStart.gif 代码

    [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,  null null );
        }  
    }

 

  

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

/Files/WGZ_Home/ExcelExport.rar 

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

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

处理代码如下:

 

ExpandedBlockStart.gif 代码
         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/archive/2010/04/10/1709279.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值