实现 ActiveReports 的本地化报表(非Viewer本身)!

本文介绍了一种基于ActiveReports for .Net的报表本地化方法,包括报表预定义、CIMS本地化设置等,并通过示例代码详细展示了如何实现报表组件的多语言支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不是指ActiveReports Viewer 本身的本地化哦!指报表数据的本地化.

用过 ActiveReports for .Net (以下简称AR)的都知道它的优势(可代码化),这样就提供了很多报表功能开发的空间给程序员。

不多说了,下面将通过我的一个EPR软件来介绍一下实现 AR 2.0 的报表本地化功能(主要通过UI贴图+讲解方式):

开发环境:VS2005 .Net 2.0 + C# + SQL2005 + AR 2.0

=========================================================

讲解一下如何实现这几种本地化语言: 

1,报表预定义(快速!) [Default] 

   就是指实例化报表时不应用本地化设置;

2,CIMS本地化设置(推荐!)(System)

   随主系统的本地化设置一样;

3,简体中文(Chinese Simplified)

4,繁体中文(Chinese Traditional)

ReportLocal 类 定义一个属性:

public bool CanActive
{
  
getreturn m_canActive;}
  
set{ m_calActive = value;}
}

这个属性在ReportLocal类实例化代入,来自主系统用户权限控制,如果你的程序没有相关权限控制可忽略。

这个Active属性用来表示将要使用的本地化语言:

 /// <summary> 
 
/// 获取当前报表本地化设置('CIMS本地化设置' 除外) 
 
/// </summary> 
public ReportLocalizableEnum Active 

   
get 
   { 
        
if (CanActive == false)  return ReportLocalizableEnum.Default; 
        
if (m_active == ReportLocalizableEnum.System) m_active = GetReportLocalizableWithSystem;

        
return m_active;  //来自存储参数
  } 

 

这些属性,函数很关键,主要收集可以本地化的报表组件(未定义DataField属性的):

    /// <summary> 
    
/// 要本地化的报表控件集合,用于OnInitControlsCollection()函数。 
  
/// 参数:Key = Control.Name
    
/// 参数:Value = 控件(Label;TextBox,CheckBox...) 
    
/// </summary> 
public Hashtable Collection { get { return rptControls; } } 

public Hashtable CreateReportControls(DataDynamics.ActiveReports.ActiveReport rpt, string sectionNameOrType) 

    
if (rpt == null)  return null

    Hashtable ctrls 
= new Hashtable(); 
    Section rs 
= null
    
    
bool all = (sectionNameOrType == UnknownSection || string.IsNullOrEmpty(sectionNameOrType)); 
    
//所有报表区域 
    if (all == false) { 
       
        try 
        { 

            SectionType type 
= (SectionType)System.Enum.Parse(typeof(SectionType), sectionNameOrType, true); 

            foreach ( rs in rpt.Sections) 

            { 
                
if (rs.Name == sectionNameOrType)   break
     
            if (type == rs.Type)    break;
            }

        }
        catch { 
                all 
= true
                
break
            } 

    } 
    
    
if (all || (rs == null)) { 
        
foreach ( rs in rpt.Sections) 

        { 
            AddControlsInfo(rs, ctrls); 
        } 
    } 
    
else {AddControlsInfo(rs, ctrls); } 
    
    
return ctrls; 


private void AddControlsInfo(Section section, Hashtable collections) 

    SectionType type 
= section.Type; 
    ARControl ctrl; 
    
foreach ( ctrl in section.Controls) { 
        
if (string.IsNullOrEmpty(ctrl.DataField) == false)   continue
          
        
//只收集没有是定义DataField属性的组件! 
    ReportControlInfo ctrlInfo = null
        
if (ctrl is Label) 
        { 
            Label lab 
= (Label)ctrl; 
            ctrlInfo 
= new ReportControlInfo(lab.Text); 
        } 
        
        
else if (ctrl is TextBox) { 
            TextBox txt 
= (TextBox)ctrl; 
            
if (string.IsNullOrEmpty(txt.Text))  continue

            ctrlInfo 
= new ReportControlInfo(txt.Text); //TextBox类型必须是设置了Text的!
        } 
        
else if (ctrl is CheckBox) { 
            CheckBox chk 
= (CheckBox)ctrl; 
            
if (string.IsNullOrEmpty(chk.Text))    continue
           
           
 ctrlInfo = new ReportControlInfo(chk.Text); //CheckBox类型必须是设置了Text的! 
            
        } 
        
        
if ((ctrlInfo != null)) 
        { 
            ctrlInfo.DataField 
= this.GetDataField(ctrlInfo.Text, string.Empty); 
            ctrlInfo.Section 
= type; 
            ctrlInfo.Parent 
= ctrl.Parent; 
            collections.Add(ctrl.Name, ctrlInfo); 
        } 
        
    } 


/// <summary> 
/// 根据组件的Name返回关联本地化设置的‘字段名’,仅判断一些常用的。 
/// </summary> 
/// <param name="controlText">组件.Text</param> 
/// <param name="defaultField">默认使用的‘字段名’,一般为空,需要后续修正</param> 
protected string GetDataField(string controlText, string defaultField) 

    
if (controlText.IndexOf("ted By"> -1) { 
        
return DBColumns.CreatedBy; 
    } 
    
else if (controlText.IndexOf("red By"> -1) { 
        
return DBColumns.PreparedBy; 
    .......
//根据你的报表来添加判断,主要是用于后面的BatchCreate功能,避免手功添加


这是ReportControlInfo类(用于收录组件的相关参数):

public class ReportControlInfo 

    
protected string m_text; 
    
protected string m_dataField; 
    
protected object m_section; 
    
protected object m_parent; 
    
public ReportControlInfo(string text) 
    

        m_text 
= text; 
    }
 
    
public ReportControlInfo(string text, object section) 
    

        m_text 
= text; 
        m_section 
= section; 
    }
 
    
public ReportControlInfo(string text, string dataField) 
    

        m_text 
= text; 
        m_dataField 
= dataField; 
    }
 
    
    
/// <summary> 
    
/// 获取或设置 组件预定义了的文本 
  
/// </summary> 

    public string Text 
        
get return m_text; } 
        
set { m_text = value; } 
    }
 
    
    
/// <summary> 
    
/// 获取或设置 用于关联本地化设置的‘字段名’ 
  
/// </summary> 

    public string DataField 
        
get return m_dataField; } 
        
set { m_dataField = value; } 
    }
 
    
    
/// <summary> 
    
/// 获取或设置 组件的父容器(PageHeader,GroupHeader...),一般可不设置 
  
/// </summary> 

    public object Parent 
        
get return m_parent; } 
        
set { m_parent = value; } 
    }
 
    
/// <summary> 
    
/// 获取或设置 组件所在的节(Report.Section),可以是SectionName OR SectionType 
    
/// </summary> 

    public object Section 
        
get return m_section; } 
        
set { m_section = value; } 
    }
 
    
}
 

=================================

下面将是实现“报表本地化关联”功能的核心:

为于实现报表同主系统使用一致的本地化定义,下面部分是必须的!

系统的本地化资源编辑器(由于此ERP的应用关系,编辑器中增加了对应用人的权限控制),源代码不提供:

这是 关联系统本地化设置 的报表本地化配置器:

解释一下各字段作用:

所属区域:指要本地化的组件所在的Section,如果为空,则为公共设置,任何报表都会搜索这些关联设置;

字段名:一般为数据表的ColumnName,要同“本地化编辑器”里的DataField定义一致;

组件名:将本地化的AR.Control,应于实际报表设计时一致,如果报表做了更改,可使用“批量修复”功能来自动修复refContrlName;

默认文本:AR.Control 预定义的Text,如果用户想始终使用这个DefaultText,只需要定义后钩选“仅使用默认标题”;

备注:不用解释了。

“报表效果预览”只是应用了最上面的参数设置。

下面,录制了一个“批量创建”报表组件的本地化关联设置的动画(文件太大!只能用GIF格式上传了,UI有失真):

索引关联设置类:

using System;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace CIMS.Report
{
    
public class ReportsLocalization : IDisposable
    
{
        
Const

        
Variables

        
Init

        
Properties

        
Localizable

        
IDisposable
    }

}

通过上面一些定义,就可以在实例化报表时实现本地化报表了!

先收集本地化组件到Collection,然后遍历集合并:

//GetLocalText函数很重要!

rptTest rpt 
= new rptTest(...);

ReportLocal reportLocal 
= new ReportLocal(true);

reportLocal.OnInitControlsCollection();

IDictionaryEnumerator ie 
= collection.GetEnumerator();
while (ie.MoveNext())
{
    
string controlName = ie.Key.ToString();
    
string localText =  reportLocal.GetLocalText(controlName);//得到本地化资源
  if(string.IsNullOrEmpty(localText)) continue;

    ARControl ctrl
= (ARControl)((ReportControl)ie.Value).Control;
    
if( ctrl is Label)
     
    ((Label)ctrl).Text
= localText ;//设置Text属性完成本地化
  else if ......

}

最终报表本地化预览:

 繁体报表结果预览:

英文报表本地化结果(BUG: SubReport 还不能本地化):

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值