应用案例
企业要求实现通过ReportingService将报表的内容以手机短信的方式发送到订阅者的手机上进行浏览。
其中短信发送功能已经实现(提供了WebService,在这里不做讨论)
因为以短信的方式发送,暂时用ReportingServices的CSV格式采集数据。
一.需求分析
其中短信发送功能已经实现(提供了WebService,在这里不做讨论)
因为以短信的方式发送,暂时用ReportingServices的CSV格式采集数据。
订阅用的参数,在这里主要用到了一个手机号,为了说明简单,这里只让用户输入一个手机号
二.程序设计
namespace Lnnmc.ReportingServices.ShortMessageDeliveryProvider
1.记录用户订阅信息的SubscriptionData类
string Handset{get;} : 用户手机号 (不附合要求,该功能去掉)
string[] Groups{get;} : 当前报表订阅的组名
string[] Users{get;} : 当前订阅的用户名
void FromSettings(Setting[] settings) : 从settings中解释出用户订阅数据
Setting[] ToSettingArray() : 将用户订阅数据生成setting数组
2.实现IExtension, IDeliveryExtension的ShortMessageProvider类
string LocalizedName{get;} : 在RS的传递下拉框中显示的名称
void SetConfiguration(string configuration) : 从rsreportserver.config中得到当前Delivery的配置信息
Setting[] ExtensionSettings : 定义服务器端的默认Setting配置
IDeliveryReportServerInformation ReportServerInformation : 可以得到当前RS服务器上的一些可用的Render类型
bool Deliver(Notification notification) : 这个方法就是用来执行发送的
Setting[] ValidateUserData(Setting[] settings) : 验证用户输入的setting是否有效
3.实现UI接口WebControl, ISubscriptionBaseUIUserControl, IExtension的ShortMessageUIProvider类
string LocalizedName{get;} : 显示在报表传递属性中的传递者下拉框中
void SetConfiguration(string configuration) : 从RSWebApplication.config得到UI的配置信息
string Description{get;} : 订阅后,显示在订阅列表中的"描述"字段里
Setting[] UserData{get;set;} : 这个很关键,是得到UI上的用户配置数据(订阅时),得到原来的用户配置数据(编辑时)。
三.程序开发
SubscriptionData 源代码
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;

using System.Collections.Specialized;
using Microsoft.ReportingServices.Interfaces;

namespace Lnnmc.ReportingServices.ShortMessageDeliveryProvider


{
public class SubscriptionData

{

public string Handset = "";
public string[] Users = null;
public string[] UsersText = null;

public string[] Groups = null;

//public string Width = "5cm";
//public string High = "8cm";

internal const string HANDSET = "Handset";
internal const string USERS = "Users";
internal const string USERSTEXT = "UsersText";
internal const string GROUPS = "Groups";
//internal const string WIDTH = "Width";
//internal const string HIGH = "High";


public void FromSettings(Setting[] settings)

{
if (settings != null)

{
foreach (Setting s in settings)

{
switch (s.Name)

{
case HANDSET:
Handset = s.Value;
break;
case USERS:
if (s.Value != "")

{
Users = s.Value.Split('|');
}
break;
case GROUPS:
if (s.Value != "")

{
Groups = s.Value.Split('|');
}
break;
case USERSTEXT:
if (s.Value != null)

{
UsersText = s.Value.Split('|');
}
break;
//case WIDTH:
// this.Width = s.Value;
// break;
//case HIGH:
// this.High = s.Value;
// break;
default:
break;
}
}
}
}


public Setting[] ToSettingArray()

{
//Setting[] ss = new Setting[6];
Setting[] ss = new Setting[4];
ss[0] = CreateSetting(HANDSET, Handset);
if (Users != null)

{
ss[1] = CreateSetting(USERS, string.Join("|", Users));
}
else

{
ss[1] = CreateSetting(USERS, "");
}

if (Groups != null)

{
ss[2] = CreateSetting(GROUPS, string.Join("|", Groups));
}
else

{
ss[2] = CreateSetting(GROUPS, "");
}

if (UsersText != null)

{
ss[3] = CreateSetting(USERSTEXT, string.Join("|", UsersText));
}
else

{
ss[3] = CreateSetting(USERSTEXT, "");
}

//ss[4] = CreateSetting(WIDTH, this.Width);
//ss[5] = CreateSetting(HIGH, this.High);

return ss;
}



public override string ToString()

{
string info = "";
info += "total:";
info += "\r\n";
info += "users : " + (this.Users == null ? "0" : this.Users.Length.ToString());
info += "\r\n";
info += "groups: " + (this.Groups == null ? "0" : this.Groups.Length.ToString());
info += "\r\n";
info += "Data";
info += "\r\n";
info += "Users = " + (this.Users == null ? "" : string.Join("|", this.Users));
info += "\r\n";
info += "Groups = " + (this.Groups == null ? "" : string.Join("|", this.Groups));
//info += "\r\n";
//info += "Wigth=" + this.Width;
//info += "\r\n";
//info += "High=" + this.High;
return info;
}


public static Setting CreateSetting(string name, string value)

{
Setting s = new Setting();
s.Name = name;
s.Value = value;
return s;
}
}
}

ShortMessageProvider源代码
// #define CSV
#define IMAGE
#undef IMAGE
#define EXCEL

using System;
using System.Xml;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Microsoft.ReportingServices.Interfaces;
using System.Drawing;
using System.Drawing.Imaging;
using System.Data;
using System.Data.SqlClient;
using Microsoft.Office.Interop.Excel;
using System.Windows.Forms;

namespace Lnnmc.ReportingServices.ShortMessageDeliveryProvider


{
public class ShortMessageProvider
: IExtension, IDeliveryExtension

{

string m_smsSenderToolWebServiceUrl = "http://www.nmc.ln.cmcc/NSPS/SMSSendService/SMSSender.asmx";
string m_smsLogFilePath = @"c:\csharp\log\short_msg_report_{0}.log";
string m_smsChannel = "02468100";
string m_connStr = "";
string m_reportMmsParse = "";
int m_maxRow = 500;
int m_maxColumn = 50;


// Represents an extension in SQL Server Reporting Services.

IExtension#region IExtension


public string LocalizedName
{ get
{ return "报表服务器手机彩信(Beta1)"; } }

public void SetConfiguration(string configuration)

{
//WriteLog("ShortMessageProvider.SetConfiguration() 加载报表服务器的配置数据");
//WriteLog("ShortMessageProvider.SetConfiguration() configuration=" + configuration);
XmlDocument doc = new XmlDocument();

try

{

doc.LoadXml(configuration);
XmlNode nodeUrl = doc.SelectSingleNode("//SmsSenderToolWebServiceUrl");
m_smsSenderToolWebServiceUrl = nodeUrl.InnerText;
XmlNode nodeLog = doc.SelectSingleNode("//SmsLogFilePath");
m_smsLogFilePath = nodeUrl.InnerText;
XmlNode nodeChannel = doc.SelectSingleNode("//SmsChannel");
m_smsChannel = nodeChannel.InnerText;
XmlNode node = doc.SelectSingleNode("//ConnectionString");
m_connStr = node.InnerText;
XmlNode reportParse = doc.SelectSingleNode("//ReportMmsParser");
m_reportMmsParse = reportParse.InnerText;
node = null;
XmlNode maxRowNode = doc.SelectSingleNode("//MaxRow");
m_maxRow = Int32.Parse(maxRowNode.InnerText);
XmlNode maxColumnNode = doc.SelectSingleNode("//MaxColumn");
m_maxColumn = Int32.Parse(maxColumnNode.InnerText);

WriteLog("m_smsSenderToolWebServiceUrl = " + m_smsSenderToolWebServiceUrl);
WriteLog("m_smsLogFilePath = " + m_smsLogFilePath);
WriteLog("m_smsChannel = " + m_smsChannel);
WriteLog("m_connStr = " + m_connStr);
WriteLog("m_reportMmsParse = " + m_reportMmsParse);
WriteLog("m_maxRow = " + m_maxRow.ToString());
WriteLog("m_maxColumn = " + m_maxColumn.ToString());
}
catch (Exception ex)

{
WriteLog("ShortMessageProvider.SetConfiguration() error=" + ex.ToString());
//throw new Exception("Failed to retrieve configuration data: " + ex.Message);
}
doc = null;
}


#endregion


// Represents a delivery extension in SQL Server Reporting Services

IDeliveryExtension#region IDeliveryExtension

Setting[] m_settings;
public Setting[] ExtensionSettings

{
get

{
WriteLog("ShortMessageProvider.ExtensionSettings.Get() 得当用户配置信息");
if (m_settings == null)

{
//WriteLog("m_settings == null");

/**//*
m_settings = new Setting[1];
Setting s = new Setting();
s.Name = SubscriptionData.HANDSET;
s.ReadOnly = false;
s.Required = true;
s.Value = "请在这里输入手机号吗";
m_settings[0] = s;
*/

}
//WriteLog("ShortMessageProvider.ExtensionSettings.Get() " + m_settings[0].Name + "=" + m_settings[0].Value);
return m_settings;
}
}

bool m_isPrivilegedUser = true;
public bool IsPrivilegedUser

{
set

{
WriteLog("ShortMessageProvider.IsPrivilegedUser.Set() 验证是否是合法用户");
m_isPrivilegedUser = value;
}
}


private IDeliveryReportServerInformation m_reportServerInfo;
public IDeliveryReportServerInformation ReportServerInformation

{
set

{
m_reportServerInfo = value; // 得到当前rs的配置信息
}
}


public bool Deliver(Notification notification)

{
WriteLog("ShortMessageProvider.Deliver() 验证用户数据");
// notification 就是要发送的报表订阅信息
// 发送

SubscriptionData userData = new SubscriptionData();
userData.FromSettings(notification.UserData);
int count = SendSMS(notification.Report, userData);
if (count > 0)

{
notification.Status = "已经发送给" + count.ToString() + "位订阅者";
}
else

{
notification.Status = "报表已经生成,但无人订阅";
}
notification.Save();
return true;
}


public Setting[] ValidateUserData(Setting[] settings)

{
WriteLog("ShortMessageProvider.ValidateUserData() 验证用户数据");
try

{
foreach (Setting setting in settings)

{
if (string.IsNullOrEmpty(setting.Field) == true)

{
WriteLog("ShortMessageProvider.ValidateUserData() " + setting.Name + "=" + setting.Value);
}
}
}
catch (Exception ep)

{
WriteLog("ShortMessageProvider.ValidateUserData() Error:" + ep.ToString());
}
return settings;
}


#endregion




public int SendSMS(Report report, SubscriptionData subscripton)

{
string msg = "";
string reportName = report.Name;
string reportTime = report.Date.ToString("HH:mm");

msg += "网事知多少之" + reportName;

string[] subscribers = GetAllMobile(subscripton);


if (subscribers != null && subscribers.Length > 0)

{

#if CSV
msg += "\r\n";
string deviceInfo = "<DeviceInfo><Encoding>Unicode</Encoding></DeviceInfo>";
RenderedOutputFile[] m_files = report.Render("CSV", deviceInfo);
if (m_files.Length > 0)

{
Stream stream = m_files[0].Data;
StreamReader reader = new StreamReader(stream);
reader.BaseStream.Position = 0;
string reportString = reader.ReadToEnd();
reader.Close();
stream.Close();

// 得到报表数据
if (!string.IsNullOrEmpty(reportString) && (reportString.Length < (100 * 1024)))

{
SmsSenderToolWS.SMSSender smsSender = new SmsSenderToolWS.SMSSender();
smsSender.Url = m_smsSenderToolWebServiceUrl;

string receiver = subscripton.Handset;
string logFile = string.Format(m_smsLogFilePath, DateTime.Now.ToString("yyyyMMdd"));
bool success = false;

msg += reportString;

// 发送短信
success = smsSender.SMSSenderTool(logFile,
m_smsChannel,
"",
receiver,
msg,
8);
}
}
else

{
// 无可用数据,不发送
}
#endif

#if IMAGE
string deviceInfo = "<DeviceInfo><OutputFormat>EMF</OutputFormat><PageHeight>" + subscripton.High + "</PageHeight><PageWidth>" + subscripton.Width + "</PageWidth><DpiX>0.1cm</DpiX><DpiY>0.0cm</DpiY><MarginLeft>0.0cm</MarginLeft><MarginRight>0.0cm</MarginRight><MarginTop>0.0cm</MarginTop><MarginBottom>0.0cm</MarginBottom></DeviceInfo>";
RenderedOutputFile[] m_files = report.Render("IMAGE", deviceInfo);
WriteLog("SendSMS() m_files.Length=" + m_files.Length.ToString());
int pageCount = m_files.Length;
if (pageCount > 0)

{
MMSWebService.MMSItem[] items = new MMSWebService.MMSItem[pageCount];

int index = 1;
foreach (RenderedOutputFile rf in m_files)

{
Stream stream = rf.Data;
WriteLog("SendSMS() stream.Length=" + stream.Length.ToString());


/**////////////////////////////////////////////////////////////////////
stream.Position = 0;
MemoryStream ms = new MemoryStream();
Image img = Image.FromStream(stream);
MemoryStream ms = new MemoryStream();
img.Save(ms, ImageFormat.Jpeg);
byte[] buffer = ms.ToArray();

items[index - 1] = new MMSWebService.MMSItem();
items[index - 1].Content = buffer;
items[index - 1].Discription = "";
items[index - 1].Type = "jpg";

/**////////////////////////////////////////////////////////////////////



///////////////////////////////////////////////////////////////////
stream.Position = 0;
Metafile mf = new Metafile(stream);

// mf.Save(@"c:\Work\ReportingServices\Out\" + DateTime.Now.ToString("MM_dd_HH_mm") + "_" + index.ToString() + ".jpg");

stream.Close();

/**////////////////////////////////////////////////////////////////////
index++;

/**//*
// 加上一个页数说明
string pageInfo = index.ToString() + "/" + pageCount.ToString();


items[index - 1] = new MMSWebService.MMSItem();
items[index - 1].Content = System.Text.Encoding.UTF8.GetBytes(pageInfo);
items[index - 1].Discription = "";
items[index - 1].Type = "txt";

index++;
*/

}

MMSWebService.MMSService mms = new MMSWebService.MMSService();
MMSWebService.Message mmsMsg = new MMSWebService.Message();
mmsMsg.AppendId = "00";
mmsMsg.From = m_smsChannel;
mmsMsg.Header = "";
mmsMsg.Panel = m_smsChannel;
mmsMsg.Subject = msg;

// 得到所有订阅者手机号
mmsMsg.To = string.Join(";", subscribers);

mmsMsg.Body = items;
mms.Send(mmsMsg);

}

#endif


#if EXCEL
WriteLog("开始生成Excel文件");

string deviceInfo = "<DeviceInfo></DeviceInfo>"; //<OmitDocumentMap>false</OmitDocumentMap><OmitFormulas>false</OmitFormulas><RemoveSpace>0.125in</RemoveSpace>
RenderedOutputFile[] m_files = report.Render("EXCEL", deviceInfo);

WriteLog("Excel文件个数=" + m_files.Length.ToString());

foreach (RenderedOutputFile rf in m_files)

{

// 创建文件名
string fileName = Environment.GetEnvironmentVariable("TMP").TrimEnd('\\') + "\\" + "Report_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls";
WriteLog(fileName);
FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate);
Stream stream = rf.Data;
stream.Position = 0;
BinaryReader br = new BinaryReader(stream);
br.BaseStream.Position = 0;
byte b;
//WriteLog("开始读文件流");
for (int rr = 0; rr < br.BaseStream.Length; rr++)

{
b = br.ReadByte();
fs.WriteByte(b);
}

//WriteLog("流数据读取完毕");

br.Close();
fs.Close();
fs.Dispose();
fs = null;
stream.Close();
stream.Dispose();
stream = null;
GC.Collect();

System.Threading.Thread.Sleep(2000);


try

{
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo
= new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = m_reportMmsParse;
startInfo.Arguments = "\"" + fileName
+ "\" \""
+ string.Join(";", subscribers)
+ "\" \""
+ m_smsLogFilePath
+ "\" \""
+ m_smsChannel
+ "\" \""
+ msg
+ "\" \""
+ m_maxRow.ToString()
+ "\" \""
+ m_maxColumn.ToString()
+ "\"";
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = true;
startInfo.RedirectStandardError = false;
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
startInfo = null;
process.Dispose();
process = null;
}
catch (Exception pppp)

{
WriteLog(pppp.ToString());
throw pppp;
}
finally

{
try

{
File.Delete(fileName);
}
catch

{ }
}
}
#endif

return subscribers.Length;
}
else

{
return 0;
}
}


private System.Security.SecureString ConvertToSecureString(string str)

{
System.Security.SecureString secureString = new System.Security.SecureString();
foreach (char c in str)

{
secureString.AppendChar(c);
}
return secureString;
}


public string[] GetAllMobile(SubscriptionData data)

{
string selectUser = "";
string selectGroup = "";

if (data.Users != null)

{
selectUser = @"select mobile from nsps_user_final where samaccountname in ('" + string.Join("','", data.Users) + "')";
}
else

{
selectUser = "select mobile from nsps_user_final where 1=0";
}

if (data.Groups != null)

{
selectGroup = @"select mobile from nsps_group_final g, nsps_user_final u, nsps_group_user_final f where f.userid=u.id and f.groupid=g.id and g.name in ('" + string.Join("','", data.Groups) + "')";
}
else

{
selectGroup = @"select '' mobile from nsps_group_final where 1=0";
}


SqlConnection conn = new SqlConnection(m_connStr);
conn.Open();

SqlCommand myCommand = conn.CreateCommand();
myCommand.CommandText = selectUser + " union " + selectGroup;

SqlDataReader userReader = myCommand.ExecuteReader();


int i = 0;
string temp = "";
while (userReader.Read())

{
i++;
temp += userReader[0].ToString();
temp += ",";
}

temp = temp.TrimEnd(',');
userReader.Close();
userReader = null;
conn.Close();
conn.Dispose();
conn = null;

return temp.Split(',');

}




public static void WriteLog(string sb)

{
return;
try

{
FileStream fs = new FileStream("c:\\ShortMessageDeliveryLog.txt", FileMode.Append,
FileAccess.Write);
StreamWriter writer = new StreamWriter(fs);
writer.WriteLine("[" + DateTime.Now.ToString("HH:mm:ss:ffff") + "]" + sb);
writer.Flush();
writer.Close();
}

catch (Exception ex)

{
throw new IOException("Error writing to log file: " + ex.Message);
}
}
}
}

ShortMessageUIProvider源代码
using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.ReportingServices.Interfaces;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Data;
using System.Data.SqlClient;


namespace Lnnmc.ReportingServices.ShortMessageDeliveryProvider


{
public class ShortMessageUIProvider
: System.Web.UI.WebControls.WebControl, ISubscriptionBaseUIUserControl, IExtension

{
string m_connStr = "";
//string m_screenSize = "";

public ShortMessageUIProvider()

{
this.Init +=new EventHandler(MyDeliveryUIProvider_Init);
this.Load += new EventHandler(ShortMessageUIProvider_Load);
this.PreRender +=new EventHandler(ShortMessageUIProvider_PreRender);
}


IExtension#region IExtension

public string LocalizedName

{
get

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.LocalizedName.Get() 获得当前名称");
return "报表服务器手机短信";
}
}

public void SetConfiguration(string configuration)

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.SetConfiguration() 得到报表服务器上的配置数据");
// none
XmlDocument doc = new XmlDocument();
try

{
doc.LoadXml(configuration);
XmlNode node = doc.SelectSingleNode("//ConnectionString");
m_connStr = node.InnerText;
node = null;


/**//*
node = doc.SelectSingleNode("//ScreenSize");
m_screenSize = node.InnerText;
node = null;
*/

}
catch (Exception ep)

{
}
doc = null;
}

#endregion



ISubscriptionBaseUIUserControl#region ISubscriptionBaseUIUserControl

public string Description

{
get

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.Description() 得到当前");
// return "发送手机彩信给 " + this.m_handsetTextBox.Text;
if (m_subscriptionList.Items.Count > 0)

{
string subscriber = "";
foreach(ListItem item in m_subscriptionList.Items)

{
subscriber += item.Value.Split(':')[1].ToString();
subscriber += ",";
}
subscriber = subscriber.TrimEnd(',');

// return "彩信大小 " + m_imgWidth.Text + " * " + m_imgHigh.Text +" 发给" + subscriber;
return "订阅者:" + subscriber;
}
else

{
return "未配置订阅用户";
}
}
}

bool m_isPrivilegedUser = false;
public bool IsPrivilegedUser

{
set

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.IsPrivilegedUser.Set() 验证用户是否合法");
m_isPrivilegedUser = value;
}
}

IDeliveryReportServerInformation m_reportServerInfo;
public IDeliveryReportServerInformation ReportServerInformation

{
set

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.ReportServerInformation.Set() 加载报表服务器配置信息");
m_reportServerInfo = value;
}
}

public Setting[] UserData

{
get

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.UserData.Get() 得到当前的用户配置信息");
SubscriptionData data = new SubscriptionData();
System.Collections.ArrayList arrUser = new System.Collections.ArrayList();
System.Collections.ArrayList arrUserText = new System.Collections.ArrayList();
System.Collections.ArrayList arrGroup = new System.Collections.ArrayList();
string[] v;
foreach (ListItem item in m_subscriptionList.Items)

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.UserData.Get() item[" + item.Text + "]=" + item.Value);
v = item.Value.Split(':');
ShortMessageProvider.WriteLog("ShortMessageUIProvider.UserData.Get() v[0]=" + v[0]);
ShortMessageProvider.WriteLog("ShortMessageUIProvider.UserData.Get() v[1]=" + v[1]);
if (v[0] == "user")

{
arrUser.Add(v[1]);
arrUserText.Add(item.Text);
}
else

{
arrGroup.Add(v[1]);
}
}
int uTotal = arrUser.Count;
int gTotal = arrGroup.Count;
if (uTotal > 0)

{
data.Users = new string[uTotal];
data.UsersText = new string[uTotal];
for (int i = 0; i < uTotal; i++)

{
data.Users[i] = arrUser[i].ToString();
data.UsersText[i] = arrUserText[i].ToString();
}
}
if (gTotal > 0)

{
data.Groups = new string[gTotal];
for (int i = 0; i < gTotal; i++)

{
data.Groups[i] = arrGroup[i].ToString();
}
}
//data.High = m_imgHigh.Text;
//data.Width = m_imgWidth.Text;
ShortMessageProvider.WriteLog("ShortMessageUIProvider.UserData.Get() UserData=" + data.ToString());
return data.ToSettingArray();
}
set

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.UserData.Set() 加载setting信息");
SubscriptionData data = new SubscriptionData();
data.FromSettings(value);
ShortMessageProvider.WriteLog("ShortMessageUIProvider.UserData.Set() UserData=" + data.ToString());
if (data.Users != null)

{
int uuTotal = data.Users.Length;
for (int ii = 0; ii < uuTotal; ii++)

{
m_subscriptionList.Items.Add(
new ListItem(data.UsersText[ii], "user:" + data.Users[ii]));
}
}


if (null!=data.Groups)

{
foreach (string g in data.Groups)

{
m_subscriptionList.Items.Add(new ListItem(g, "group:" + g));
}
}
//m_imgWidth.Text = data.Width;
//m_imgHigh.Text = data.High;
}
}

public bool Validate()

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.Validate() 验证");
return true;
}

#endregion


Controls#region Controls

TextBox m_handsetTextBox = new TextBox();
Label m_handsetLabel = new Label();
RegularExpressionValidator m_handsetValidator = new RegularExpressionValidator();

// 定义Table
HtmlTable m_table = new HtmlTable();

// 定义Row
HtmlTableRow m_userRow = new HtmlTableRow();
HtmlTableRow m_groupRow = new HtmlTableRow();
HtmlTableRow m_subInfoRow = new HtmlTableRow();
//HtmlTableRow m_imgSizeRow = new HtmlTableRow();
//HtmlTableRow m_imgDetailRow = new HtmlTableRow();

// 定义Cell
HtmlTableCell m_userLabelCell = new HtmlTableCell();
HtmlTableCell m_userListCell = new HtmlTableCell();
HtmlTableCell m_groupLableCell = new HtmlTableCell();
HtmlTableCell m_groupListCell = new HtmlTableCell();
HtmlTableCell m_subLabelCell = new HtmlTableCell();
HtmlTableCell m_subInfoCell = new HtmlTableCell();
//HtmlTableCell m_imgSizeCell = new HtmlTableCell();
//HtmlTableCell m_imgSizeLabelCell = new HtmlTableCell();
//HtmlTableCell m_imgDetailLabelCell = new HtmlTableCell();
//HtmlTableCell m_imgDetailCell = new HtmlTableCell();


// 其它
DropDownList m_userDropDownList = new DropDownList(); // 用户下拉框
DropDownList m_groupDropDownList = new DropDownList(); // 组下拉框
ListBox m_subscriptionList = new ListBox(); // 订阅情况下拉框
ListBox m_memberList = new ListBox(); // 成员列表
//TextBox m_imgWidth = new TextBox();
//TextBox m_imgHigh = new TextBox();
//Label m_imgWidthLabel = new Label();
//Label m_imgHighLabel = new Label();
//Label m_imgSizeDetail = new Label();

// Button
Button m_addUserButton = new Button(); // 填加用户按键
Button m_addGroupButton = new Button(); // 添加组按键
Button m_listMemberButton = new Button(); // 查看组中成员
Button m_cannelSubButon = new Button(); // 取消订阅

#endregion



Event#region Event


void MyDeliveryUIProvider_Init(object sender, EventArgs args)

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.MyDeliveryUIProvider_Init() 初始化UI");


m_addUserButton.Text = "添加";
m_addUserButton.Click+=new EventHandler(m_addUserButton_Click);
m_listMemberButton.Text = "成员";
m_addGroupButton.Text = "添加";
m_cannelSubButon.Text = "取消订阅";
m_addGroupButton.Click +=new EventHandler(m_addGroupButton_Click);
m_listMemberButton.Click +=new EventHandler(m_listMemberButton_Click);
m_cannelSubButon.Click+=new EventHandler(m_cannelSubButon_Click);
m_subscriptionList.Rows = 10;
m_subscriptionList.Width = new Unit(500);
m_memberList.Rows = 1;
m_memberList.Font.Name = "宋体";
m_groupDropDownList.Font.Name = "宋体";
m_userDropDownList.Font.Name = "宋体";
m_subscriptionList.Font.Name = "宋体";
// 第一行
m_userLabelCell.InnerText = "选择用户:";
m_userListCell.Controls.Add(m_userDropDownList);
m_userListCell.Controls.Add(m_addUserButton);
m_userRow.Cells.Add(m_userLabelCell);
m_userRow.Cells.Add(m_userListCell);
m_table.Rows.Add(m_userRow);
// 第二行
m_groupLableCell.InnerText = "选择组名:";
m_groupListCell.Controls.Add(m_groupDropDownList);
m_groupListCell.Controls.Add(m_listMemberButton);
m_groupListCell.Controls.Add(m_addGroupButton);
m_groupListCell.Controls.Add(m_memberList);
m_groupRow.Cells.Add(m_groupLableCell);
m_groupRow.Cells.Add(m_groupListCell);
m_table.Rows.Add(m_groupRow);
// 第三行
m_subLabelCell.InnerText = "订阅列表:";
m_subInfoCell.Controls.Add(m_subscriptionList);
m_subInfoCell.Controls.Add(m_cannelSubButon);
m_subInfoRow.Cells.Add(m_subLabelCell);
m_subInfoRow.Cells.Add(m_subInfoCell);
m_table.Rows.Add(m_subInfoRow);
// 第四行
//m_imgSizeLabelCell.InnerText = "图像大小:";
//m_imgWidth.Width = Unit.Parse("40");
//m_imgHigh.Width = Unit.Parse("40");
//m_imgWidthLabel.Text = "宽度";
//m_imgHighLabel.Text = "高度";
//m_imgWidth.Text = "6cm";
//m_imgHigh.Text = "8cm";
//m_imgWidth.Visible = false;
//m_imgHigh.Visible = false;
//m_imgSizeCell.Controls.Add(m_imgWidthLabel);
//m_imgSizeCell.Controls.Add(m_imgWidth);
//m_imgSizeCell.Controls.Add(m_imgHighLabel);
//m_imgSizeCell.Controls.Add(m_imgHigh);
//m_imgSizeRow.Cells.Add(m_imgSizeLabelCell);
//m_imgSizeRow.Cells.Add(m_imgSizeCell);
//m_table.Rows.Add(m_imgSizeRow);
// 第五行
//m_imgDetailLabelCell.InnerText = "图像说明:";
//m_imgDetailCell.InnerText = m_screenSize;
//m_imgDetailRow.Cells.Add(m_imgDetailLabelCell);
//m_imgDetailRow.Cells.Add(m_imgDetailCell);
//m_table.Rows.Add(m_imgDetailRow);
this.Controls.Add(m_table);
// 初始化所有控件
SqlConnection conn = new SqlConnection(m_connStr);
conn.Open();
SqlCommand userCommand = conn.CreateCommand();
userCommand.CommandText =
@"SELECT samaccountname,displayname,mobile
FROM nsps_user_final
WHERE mobile is not null and mobile <> ''
and substring(mobile,1,3) in ('134','135','136','137','138','139')
order by samaccountname ";
SqlDataReader userReader = userCommand.ExecuteReader();
while (userReader.Read())

{
m_userDropDownList.Items.Add(
new ListItem(
string.Format("{0,-16}{1,11}____{2}",
userReader[0].ToString(),
userReader[2].ToString(),
userReader[1].ToString()).Replace(" ", "_"),
"user:" + userReader[0].ToString())
);
}
userReader.Close();
userReader = null;


SqlCommand groupCommand = conn.CreateCommand();
groupCommand.CommandText = "SELECT distinct Name FROM [om].[lnnmc].[nsps_group_final] where usercount >0 order by name ";
SqlDataReader groupReader = groupCommand.ExecuteReader();
while (groupReader.Read())

{
m_groupDropDownList.Items.Add(new ListItem(groupReader[0].ToString(), "group:" + groupReader[0].ToString()));
}

conn.Close();
conn.Dispose();
conn = null;
}



void ShortMessageUIProvider_PreRender(object sender, EventArgs args)

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.ShortMessageUIProvider_PreRender()");
}

void ShortMessageUIProvider_Load(object sender, EventArgs args)

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.ShortMessageUIProvider_Load()");
this.m_memberList.Items.Clear();
if (!this.Page.IsPostBack)

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.ShortMessageUIProvider_Load() !IsPostBack");
}
else

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.ShortMessageUIProvider_Load() IsPostBack");
}
}


// 添加用户按键点击
void m_addUserButton_Click(Object sender, EventArgs args)

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.m_addUserButton_Click()");
int i = m_userDropDownList.SelectedIndex;
if (i != -1)

{
string displayName = m_userDropDownList.SelectedItem.Text;
string accountName = m_userDropDownList.SelectedItem.Value;
bool isExit = false;
foreach(ListItem item in m_subscriptionList.Items)

{
if (item.Value == accountName)

{
isExit = true;
break;
}
}

if (!isExit)

{
// 从前面开始加
m_subscriptionList.Items.Insert(0,
new ListItem(displayName, accountName));
}
}
}


// 添加组
void m_addGroupButton_Click(Object sender, EventArgs args)

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.m_addGroupButton_Click()");
int i = m_groupDropDownList.SelectedIndex;
if (i != -1)

{
string displayName = m_groupDropDownList.SelectedItem.Text;
string groupName = m_groupDropDownList.SelectedItem.Value;
bool isExit = false;
int listTotal = m_subscriptionList.Items.Count;
for (int index = listTotal - 1; index >= 0; index--)

{

if (m_subscriptionList.Items[index].Value == groupName)

{
isExit = true;
break;
}
}

if (!isExit)

{
m_subscriptionList.Items.Add(
new ListItem(displayName, groupName));
}
}
}



void m_listMemberButton_Click(Object sender, EventArgs args)

{
ShortMessageProvider.WriteLog("ShortMessageUIProvider.m_listMemberButton_Click()");
int i = m_groupDropDownList.SelectedIndex;
if (i != -1)

{
string groupName = m_groupDropDownList.Items[i].Text;

SqlConnection conn = new SqlConnection(m_connStr);
conn.Open();

SqlCommand userCommand = conn.CreateCommand();

userCommand.CommandText =
@"select c.samaccountname,c.displayname,c.mobile from
nsps_group_final a,
NSPS_GROUP_USER_final b,
nsps_user_final c
where a.id = b.groupid
and c.id = b.userid
and a.name = '" + groupName + @"'
order by c.displayname";

SqlDataReader userReader = userCommand.ExecuteReader();
while (userReader.Read())

{
m_memberList.Items.Add(
new ListItem(
string.Format("{0,-16}{1,11}____{2}",
userReader[0].ToString(),
userReader[2].ToString(),
userReader[1].ToString()).Replace(" ","_"),
"user:" + userReader[0].ToString())
);
}
userReader.Close();
userReader = null;

conn.Close();
conn.Dispose();
}
}


void m_cannelSubButon_Click(object sender, EventArgs args)

{
int selectedIndex = m_subscriptionList.SelectedIndex;
if (selectedIndex >= 0)

{
m_subscriptionList.Items.RemoveAt(selectedIndex);
}
}

#endregion





public string[] GetAllMobile(SubscriptionData data)

{
string selectUser = "";
string selectGroup = "";

if (data.Users != null)

{
selectUser = @"select mobile from nsps_user_final where samaccountname in ('" + string.Join("','", data.Users) + "')";
}
else

{
selectUser = "select mobile from nsps_user_final where 1=0";
}

if (data.Groups != null)

{
selectGroup = @"select mobile from nsps_group_final g, nsps_user_final u, nsps_group_user_final f where f.userid=u.id and f.groupid=g.id and g.name in ('" + string.Join("','", data.Groups) + "')";
}
else

{
selectGroup = @"select mobile from nsps_group_final where 1=0";
}


SqlConnection conn = new SqlConnection(m_connStr);
conn.Open();

SqlCommand myCommand = conn.CreateCommand();
myCommand.CommandText = selectUser + " union " + selectGroup;

SqlDataReader userReader = myCommand.ExecuteReader();


int i = 0;
string temp = "";
while (userReader.Read())

{
i++;
temp += userReader[0].ToString();
temp += ",";
}

temp = temp.TrimEnd(',');
userReader.Close();
userReader = null;
conn.Close();
conn.Dispose();
conn = null;

return temp.Split(',');

}



}
}

实际开发过程中发现,Excel的一些处理只能在WinForm程序中进行(具体为啥没搞清楚)所以,在处理生成的Excel时,只能单独做了一个WinApp
ReportMmsParser.exe 的源代码
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace ReportMmsParser


{
static class Program

{

/**//// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)

{

if (args.Length != 7)

{
Usage();
}
else

{

try

{
// Application.EnableVisualStyles();
// Application.SetCompatibleTextRenderingDefault(false);

string fileName = args[0];
string receivers = args[1];
string m_smsLogFilePath = args[2];
string m_smsChannel = args[3];
string m_subject = args[4];
string m_maxRow = args[5];
string m_maxColumn = args[6];

Form1 frm = new Form1();
frm.txtChannel.Text = m_smsChannel;
frm.txtFilePath.Text = fileName;
frm.txtReceivers.Text = receivers;
frm.txtSmsLog.Text = m_smsLogFilePath;
frm.txtSubject.Text = m_subject;
frm.txtMaxRow.Text = m_maxRow;
frm.txtMaxColumn.Text = m_maxColumn;

Application.Run(frm);


}
catch(Exception eee)

{

}

}


}

public static void Usage()

{
Console.WriteLine("报表解析发送程序");
Console.WriteLine("输入4个参数");
Console.WriteLine("参数1:ReportService产生的Excel文件");
Console.WriteLine("参数2:接收者的手机号(逗号分隔)");
Console.WriteLine("参数3:短信日志文件路径");
Console.WriteLine("参数4:发短信时使用的通道号");
}

}
}

using System;
using System.IO;
using System.Drawing.Imaging;
using System.Diagnostics;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Office.Interop;
using Microsoft.Office.Interop.Excel;

namespace ReportMmsParser


{
public partial class Form1 : Form

{
public Form1()

{
InitializeComponent();
}

private void cmdParse_Click(object sender, EventArgs e)

{
string fileName = txtFilePath.Text;
string receivers = txtReceivers.Text;
string m_smsLogFilePath = txtSmsLog.Text;
string m_smsChannel = txtChannel.Text;
string m_subject = txtSubject.Text;
Int32 m_maxRow = Int32.Parse(txtMaxRow.Text);
Int32 m_maxColumn = Int32.Parse(txtMaxColumn.Text);

// 定义采集内容
System.Collections.ArrayList arrItems
= new System.Collections.ArrayList();

// 解析文件
string strOutputText = "";
ApplicationClass excel
= new ApplicationClass();
Workbook workBook = excel.Workbooks.Open(
fileName,
0,
true,
5,
"",
"",
true,
XlPlatform.xlWindows,
"\t",
false,
false,
0,
true,
1,
0);
Worksheet sheet = workBook.ActiveSheet as Worksheet;
bool finished = false;
int currentRow, currentColumn;
for (int rowIndex = 1; rowIndex <= m_maxRow; rowIndex++)

{
for (int colIndex = 1; colIndex <= m_maxColumn; colIndex++)

{

// 图片位置?
currentRow = rowIndex;
currentColumn = colIndex;

// 当前的单元格
Range range = sheet.Cells[rowIndex, colIndex] as Range;
if (range != null && range.Value2 != null)

{
string v = range.Value2.ToString();

if (v.IndexOf("------", 0) == 0) // 这个表示Item的分隔

{
if (strOutputText != "")

{
MMSWebService.MMSItem item = new MMSWebService.MMSItem();
item.Content = System.Text.Encoding.UTF8.GetBytes(strOutputText.Replace("\\r", "\r").Replace("\\n", "\n"));
item.Type = "txt";
arrItems.Add(item);
strOutputText = "";
}
}
else if (string.Compare(v, "end", true) == 0)

{
if (strOutputText != "")

{
MMSWebService.MMSItem item = new MMSWebService.MMSItem();
item.Content = System.Text.Encoding.UTF8.GetBytes(strOutputText.Replace("\\r", "\r").Replace("\\n", "\n"));
item.Type = "txt";
arrItems.Add(item);
strOutputText = "";
}

finished = true;
break;
}
else

{
strOutputText += v;
}

}
else // 如果当前单元格数据为空,那么看看这个格子是不是图片

{
foreach (Shape shape in sheet.Shapes)

{
if (shape.TopLeftCell.Row == currentRow
&& shape.TopLeftCell.Column == currentColumn)

{

// 找到图片了

// 先把前面的文字信息输出
if (strOutputText != "")

{
MMSWebService.MMSItem item = new MMSWebService.MMSItem();
item.Content = System.Text.Encoding.UTF8.GetBytes(strOutputText.Replace("\\r", "\r").Replace("\\n", "\n"));
item.Type = "txt";
arrItems.Add(item);
strOutputText = "";
}


shape.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap);

if (Clipboard.ContainsImage())

{
Image imgBmp = Clipboard.GetData(System.Windows.Forms.DataFormats.Bitmap) as Image;
if (imgBmp != null)

{
// 转成jpg的
System.Drawing.Image imgJpeg = imgBmp.GetThumbnailImage(imgBmp.Width, imgBmp.Height, null, new IntPtr());
Graphics g = Graphics.FromImage(imgJpeg);
g.DrawImage(imgJpeg, 0, 0, imgJpeg.Width, imgJpeg.Height); //將原圖畫到指定的圖上
g.Dispose();
// Stream jpgStream = null ;
// imgJpeg.Save(jpgStream, ImageFormat.Jpeg);
MemoryStream ms = new MemoryStream();
imgJpeg.Save(ms, ImageFormat.Jpeg);
byte[] bf = ms.ToArray();

MMSWebService.MMSItem item = new MMSWebService.MMSItem();
item.Content = bf;
item.Discription = "";
item.Type = "jpg";

arrItems.Add(item);
}
}
else

{
}
}
}


}

if (finished)

{
break;
}
} // Exist for


}

// 有可能用户忘记写"end"了。所以要判断一下。
if (strOutputText != "")

{
MMSWebService.MMSItem item = new MMSWebService.MMSItem();
item.Content = System.Text.Encoding.UTF8.GetBytes(strOutputText.Replace("\\r", "\r").Replace("\\n", "\n"));
item.Type = "txt";
arrItems.Add(item);
strOutputText = "";
}


workBook.Close(false, "", 0);
workBook = null;
excel.Quit();
excel = null;

GC.Collect();


// 准备发
if (arrItems.Count > 0)

{
// 只发短信
if (arrItems.Count == 1)

{
MMSWebService.MMSItem item = arrItems[0] as MMSWebService.MMSItem;
if (item.Type == "txt")

{
string msgmsg = System.Text.Encoding.UTF8.GetString(item.Content);
SmsSenderToolWS.SMSSender smsSender = new SmsSenderToolWS.SMSSender();


string logFile = string.Format(m_smsLogFilePath, DateTime.Now.ToString("yyyyMMdd"));
bool success = false;

foreach (string receiver in receivers.Split(';'))

{
// 发送短信
success = smsSender.SMSSenderTool(logFile,
m_smsChannel,
"",
receiver,
msgmsg,
8);

}

}
}
else

{
MMSWebService.MMSService mms = new MMSWebService.MMSService();
MMSWebService.Message mmsMsg = new MMSWebService.Message();
mmsMsg.AppendId = "";
mmsMsg.From = m_smsChannel;
mmsMsg.Header = "";
mmsMsg.Panel = m_smsChannel;
mmsMsg.Subject = m_subject;

// 得到所有订阅者手机号
mmsMsg.To = receivers;

mmsMsg.Body = new MMSWebService.MMSItem[arrItems.Count];
for (int pp = 0; pp < arrItems.Count; pp++)

{
mmsMsg.Body[pp] = arrItems[pp] as MMSWebService.MMSItem;
}
mms.Send(mmsMsg);

}
}
}

private void Form1_Load(object sender, EventArgs e)

{
this.cmdParse_Click(null, null);
this.Close();
}
}
}

四.程序部署
五.程序测试
本次开发,参考了RS自带的PrinterDelivery例程