引言
项目到目前告一段落,目前进入测试阶段,下周就要去部署了。虽然项目不大,但是从头到尾都是自己一个人负责,在完成编码之后,对代码进行走查,命名规范,业务逻辑,代码优化等,能负责一个项目的整个编码,非常的兴奋啊。
技术
用到的技术:
技术 | 项目中使用该技术目的 |
ASP.NET | 使用asp.net进行web端用户信息管理,对用户的增删改查,对签名样本的上传,下载Excel模版,导入用户信息。 |
webService | 为签名客户端提供修改用户密码接口服务,下载签名样本接口服务, |
windows服务 | 轮询数据库,对满足条件的dwg文件,从ftp服务器下载dwg文件至c盘缓存,获取签名样本文件,调用c++签名接口,对dwg文件进行签名。 |
ftp | 使用serv-u进行ftp服务器搭建,对dwg文件进行上传下载。serv-u配置教程。[工具]Serv-U配置教程 |
jquery | 使用ajax对用户信息的无刷新校验,主要用在登录页面,添加用户页面对信息的校验。 |
js | 回车键触发登录事件。 |
jqueryui | 上传前面样本,excel人员信息excel文件的弹出框。 |
uploadify上传组件 | 上传.sign文件和.xlsx文件。 |
NHibernate |
对象/关系数据库映射工具 |
多层 |
IData:数据库操作接口 Data:数据库操作类 Business:业务逻辑层 Domain:简单领域层,包括Entities(数据库映射实体类)和Mapping(NHibernate映射xml文件) Ui:人员信息管理web端 |
NHibernate |
对象/关系数据库映射工具 |
NPOI |
项目中用到com组件进行读取excel的,但是测试的时候,在x64系统上读取不了,没办法采用了NPOI组件。 |
AspNetPager |
对人员列表进行分页。 |
工具
工具 | 目的 |
VS2012 | 代码编写 |
动软代码生成器 | 根据NHibernate模版生成IData,Data,Business,Entities,Mapping代码生成 |
Serv-U | ftp服务器搭建 |
SqlServer2012 |
数据库 |
windows server2008 | 服务器环境虚拟机,测试用 |
Dependency Walker |
查看dll依赖,
[工具]推荐一款查看dll依赖工具 |
web端界面
该项目,为管理员使用,类似一个简单的管理工具。对样式要求不高就从网上找了一个样式,扒取的样式。
登录界面:
页面主要代码:
1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="PYC.SignatureNX.Login" %> 2 3 <!DOCTYPE html> 4 5 <html xmlns="http://www.w3.org/1999/xhtml"> 6 <head runat="server"> 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 8 <title>登录</title> 9 <link href="CSS/admin_login.css" rel="stylesheet" /> 10 <script type="text/javascript" src="Scripts/jquery-1.10.2.js"></script> 11 <script type="text/javascript"> 12 $(function () { 13 //页面加载,用户名文本框获得焦点 14 $("#txtCode").focus(); 15 //密码框获得焦点,断用户是否存在 16 $("#txtPwd").focus(function () { 17 var strCode = $("#txtCode").val(); 18 if (strCode == "") { 19 alert("请输入用户名"); 20 $("#txtCode").focus(); 21 return; 22 } else { 23 AjaxRequest(strCode, "", "Exist"); 24 } 25 26 }); 27 //单击登录按钮,验证密码是否存在,存在则登录,不存在重新输入用户密码 28 $("#btnLogin").click(function () { 29 var strCode = $("#txtCode").val(); 30 var strPwd = $("#txtPwd").val(); 31 if (strCode == "") { 32 alert("请输入用户名"); 33 return; 34 } else if (strPwd == "") { 35 alert("请输入密码"); 36 return; 37 } else { 38 AjaxRequest(strCode, strPwd, "SignIn"); 39 } 40 41 }); 42 43 }); 44 //ajax请求,验证用户名,密码 45 function AjaxRequest(code, pwd, method) { 46 //拼接参数 47 var strData = "strCode=" + code 48 if (pwd != "") { 49 strData += "&strPwd=" + pwd; 50 } 51 $.ajax({ 52 type: "POST", 53 url: "Ashx/Login.ashx?action=" + method, 54 data: strData, 55 contentType: "application/x-www-form-urlencoded", 56 dataType: "text", 57 success: function (data) { 58 if (data == "-1") { 59 alert("该用户不存在,请重新输入"); 60 $("#txtCode").val(""); 61 $("#txtCode").focus(); 62 return false; 63 } else if (data == "0") { 64 alert("密码不正确,请重新输入"); 65 $("#txtPwd").val(""); 66 $("#txtPwd").focus(); 67 return false; 68 } else if (data == "1") { 69 window.location.href = "Main.aspx"; 70 } 71 }, 72 //参数:XMLHttpRequest 对象、错误信息、(可选)捕获的异常对象。 73 error: function (XMLHttpRequest, textStatus, errorThrown) { 74 //请求失败,弹出错误状态码 75 alert(textStatus); 76 } 77 }); 78 } 79 </script> 80 <script type="text/javascript"> 81 //回车触发登录事件 82 function keyLogin() { 83 //获得用户名和密码 84 var strCode = $("#txtCode").val(); 85 var strPwd = $("#txtPwd").val(); 86 //如果按下回车键,此时用户名为空,则提示,用户名文本框获得焦点,并阻止提交 87 if (event.keyCode == 13 && strCode == "") { 88 alert("请输入用户名"); 89 $("#txtCode").val(""); 90 $("#txtCode").focus(); 91 return; 92 } else if (event.keyCode == 13 && strPwd == "") { 93 //如果按下回车键,此时密码为空,则提示,密码文本框获得焦点,并阻止提交 94 alert("请输入密码"); 95 $("#txtPwd").val(""); 96 $("#txtPwd").focus(); 97 return; 98 } 99 //如果按下回车键,并且用户名和密码都不为空,触发登录按钮的单击事件,进行提交验证 100 if (event.keyCode == 13 && strCode != "" && strPwd != "") //回车键的键值为13 101 document.getElementById("btnLogin").click(); //调用登录按钮的登录事件 102 } 103 </script> 104 </head> 105 <body onkeyup="keyLogin();"> 106 <form id="form1" runat="server"> 107 <div class="admin_login_wrap"> 108 <h1>系统登录窗口</h1> 109 <div class="adming_login_border"> 110 <div class="admin_input"> 111 112 <ul class="admin_items"> 113 <li> 114 <label for="user">用户名:</label> 115 <input type="text" name="txtCode" value="" id="txtCode" size="40" class="admin_input_style" /> 116 </li> 117 <li> 118 <label for="pwd">密码:</label> 119 <input type="password" name="txtPwd" value="" id="txtPwd" size="40" class="admin_input_style" /> 120 </li> 121 <li> 122 <input type="button" tabindex="3" id="btnLogin" value="登录" class="btn btn-primary" /> 123 </li> 124 </ul> 125 126 </div> 127 </div> 128 </div> 129 130 </form> 131 </body> 132 </html>
业务逻辑:用户名失去焦点时,进行用户名是否存在。使用ajax进行无刷新登录。
人员信息模版:
人员信息列表页面:
导入过程:
结果:
上传签名人样本:
单击人员列表中的上传,弹出上传签名样本的窗口。
页面主要代码:
1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Main.aspx.cs" Inherits="PYC.SignatureNX.Main" %> 2 3 <!DOCTYPE html> 4 <%@ Register Assembly="AspNetPager" Namespace="Wuqi.Webdiyer" TagPrefix="webdiyer" %> 5 <html xmlns="http://www.w3.org/1999/xhtml"> 6 <head runat="server"> 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 8 <title>用户信息</title> 9 <link href="CSS/common.css" rel="stylesheet" /> 10 <link href="CSS/main.css" rel="stylesheet" /> 11 <style type="text/css"> 12 /*隐藏上传的进度条*/ 13 .uploadify-queue 14 { 15 display: none; 16 } 17 /*查询框中灰色字体样式*/ 18 .search 19 { 20 color: gray; 21 } 22 </style> 23 <script type="text/javascript" src="Scripts/jquery-1.10.2.js"></script> 24 <link href="Scripts/uploadify/css/uploadify.css" rel="stylesheet" /> 25 <script type="text/javascript" src="Scripts/uploadify/js/uploadify3.2.1/jquery.uploadify.js"></script> 26 <link href="Scripts/JqueryUI/css/redmond/jquery-ui-1.10.4.custom.css" rel="stylesheet" /> 27 <script type="text/javascript" src="Scripts/JqueryUI/js/jquery-ui-1.10.4.custom.js"></script> 28 <script type="text/javascript"> 29 $(function () { 30 //初始化批量导入弹出框 31 OpenDialog("dialogxls", "上传批导人员信息", false); 32 33 //初始化dialog 34 OpenDialog("dialog", "上传签名样本", true); 35 }); 36 function OpenDialog(id, title, isContainsUpload) { 37 //弹出框的初始化方法 38 $("#" + id).dialog({ 39 40 // 初始化之后,是否立即显示对话框,默认为 true 41 autoOpen: false, 42 43 //设置弹出框的高度 400px 44 width: 400, 45 46 //是否模式对话框,默认为 false 47 modal: true, 48 49 //是否允许拖动,默认为 true 50 draggable: true, 51 52 //是否可以调整对话框的大小,默认为 true 53 resizable: true, 54 55 //弹出框的标题 56 title: title, 57 position: "center", 58 close: function () { 59 if (isContainsUpload == true) { 60 //注意jquery下检查一个元素是否存在必须使用 .length >0 来判断 61 if ($(‘#btnUpload‘).length > 0) { 62 //如果存在,则将其销毁 63 $(‘#btnUpload‘).uploadify(‘destroy‘); 64 } 65 } else { 66 //注意jquery下检查一个元素是否存在必须使用 .length >0 来判断 67 if ($(‘#btnUploadXLS‘).length > 0) { 68 //如果存在,则将其销毁 69 $(‘#btnUploadXLS‘).uploadify(‘destroy‘); 70 } 71 72 } 73 } 74 }); 75 } 76 </script> 77 </head> 78 <body> 79 <div class="result-wrap"> 80 81 <form id="form1" runat="server"> 82 <div> 83 <table style="width: 100%;"> 84 <tr> 85 <td> 86 <asp:Button ID="btnAdd" runat="server" Text="添加" CssClass="btn btn6" OnClick="btnAdd_Click" /> <asp:Button CssClass="btn btn6" ID="btnDeleteMore" runat="server" Text="批量删除" OnClientClick="SelectUsers();" OnClick="btnDeleteMore_Click" /> <input class="btn btn6" type="button" name="name" id="btnMoreImport" value="批量导入" /> <asp:Button CssClass="btn btn6" ID="btnTemlpalteLoad" runat="server" Text="批导模版下载" OnClick="btnTemlpalteLoad_Click" /> <%--<a href="SignTest.aspx">签名信息列表</a>--%><asp:Button Text="批量启用" runat="server" ID="btnStartMore" CommandName="Start" CssClass="btn btn6" OnClientClick="SelectUsers();" OnClick="btnStartMore_Click" /> <asp:Button Text="批量停用" runat="server" OnClick="btnStartMore_Click" CssClass="btn btn6" OnClientClick="SelectUsers();" CommandName="Stop" ID="btnStopMore" /></td> 87 <td align="right"> 88 <asp:TextBox runat="server" Text="请输入查询关键字" ID="txtSearch" CssClass="search" /> <asp:Button Text="查询" runat="server" CssClass="btn btn6" ID="btnSearch" OnClick="btnSearch_Click" /></td> 89 </tr> 90 </table> 91 <asp:HiddenField runat="server" ID="hdFieldIds" Value="" /> 92 <br /> 93 94 <div class="result-content"> 95 <asp:Repeater ID="RptUserList" runat="server" OnItemDataBound="RptUserList_ItemDataBound"> 96 <HeaderTemplate> 97 <table class="result-tab" style="width: 100%; text-align: center;" id="tbUsers"> 98 <tr> 99 <th width="5%"> 100 <a href="javascript:void(0)" id="lnkSelectAll">全选</a> </th> 101 <th width="5%">序号</th> 102 <th>用户名</th> 103 <th>签名人姓名</th> 104 <th>签名人样本</th> 105 <th>状态</th> 106 <th>操作</th> 107 </tr> 108 </HeaderTemplate> 109 <ItemTemplate> 110 <tr> 111 <td> 112 <input type="checkbox" name="name" value=‘<%#Eval("Sign_Code") %>‘ /> 113 </td> 114 <td> 115 <asp:Literal ID="ltlItemNo" runat="server" /> 116 </td> 117 <td><%#Eval("Sign_Code") %></td> 118 <td><%#Eval("Sign_Name") %></td> 119 <td id="td<%#Eval("Sign_Code") %>"> 120 <asp:Literal Text="" ID="ltlSignSample" runat="server" /> 121 </td> 122 <td> 123 <asp:LinkButton OnClick="lnkState_Click" ID="lnkState" Text="" runat="server" /></td> 124 <td> 125 <asp:LinkButton CommandArgument=‘<%#Eval("Sign_Code") %>‘ CommandName="Edit" Text="编辑" ID="lnkBtn" OnClick="lnkBtn_Click" runat="server" /> 126 <asp:LinkButton Text="删除" CommandArgument=‘<%#Eval("Sign_Code") %>‘ CommandName="Delete" OnClick="lnkBtn_Click" runat="server" /> 127 </td> 128 129 </tr> 130 </ItemTemplate> 131 <FooterTemplate> 132 </table> 133 </FooterTemplate> 134 </asp:Repeater> 135 </div> 136 <div id="dialogxls" title="上传Excel文件" style="text-align: center; display: none;"> 137 <input type="button" name="name" id="btnUploadXLS" value="上传" /> 138 <span id="spanMsg">(只能上传.xlsx格式文件)</span> 139 </div> 140 <div id="dialog" title="上传签名样本" style="text-align: center; display: none;"> 141 <input type="button" name="name" id="btnUpload" value="上传样本" /> 142 <span>(只能上传.sign格式文件)</span> 143 </div> 144 145 </div> 146 147 148 <div class="list-page"> 149 <%-- 分页样式一 首页 上一页 下一页 尾页--%> 150 <webdiyer:AspNetPager ID="AspNetPager1" runat="server" 151 CustomInfoHTML="共%PageCount%页,当前为第%CurrentPageIndex%页,每页%PageSize%条,共%RecordCount%条" 152 FirstPageText="首页" 153 LastPageText="尾页" 154 NextPageText="下一页" 155 PageIndexBoxType="TextBox" 156 PrevPageText="上一页" 157 ShowCustomInfoSection="Left" 158 ShowPageIndex="true" 159 ShowPageIndexBox="Always" 160 SubmitButtonText="Go" 161 SubmitButtonClass="right_d_btn" 162 TextAfterPageIndexBox="页" 163 TextBeforePageIndexBox="转到" 164 OnPageChanging="AspNetPager1_PageChanging" 165 AlwaysShow="True" 166 PageSize="10" 167 ShowMoreButtons="false" 168 HorizontalAlign="Center"> 169 </webdiyer:AspNetPager> 170 171 </div> 172 </form> 173 </div> 174 </body> 175 </html> 176 <script type="text/javascript"> 177 178 //全选,全不选 179 $("#lnkSelectAll").click(function () { 180 var txt = $(this).text(); 181 var flag = false; 182 var strIds = ""; 183 if (txt == "全选") { 184 $(this).text("全不选"); 185 flag = true; 186 } else { 187 $(this).text("全选"); 188 flag = false; 189 } 190 $("#tbUsers td :checkbox").each(function () { 191 this.checked = flag; 192 }); 193 if (flag) { 194 $("#tbUsers td :checkbox").each(function (index) { 195 strIds += $(this).val() + ","; 196 }); 197 } else { 198 strIds = ""; 199 } 200 $("#hdFieldIds").val(strIds) 201 202 }); 203 //选中的用户 204 function SelectUsers() { 205 var strIds = ""; 206 $("#tbUsers td :checked").each(function (index) { 207 strIds += $(this).val() + ","; 208 }); 209 $("#hdFieldIds").val(strIds) 210 211 } 212 //批量导入 213 $("#btnMoreImport").click(function () { 214 $("#dialogxls").dialog("open"); 215 //上传 216 //上传插件初始化方法 217 $(‘#btnUploadXLS‘).uploadify({ 218 219 //选择文件后是否自动上传,默认为true 220 ‘auto‘: true, 221 //选择文件按钮 222 ‘buttonClass‘: ‘some-class‘, 223 //是否开启调试模式 224 // ‘debug‘: true, 225 //设置按钮文本 226 ‘buttonText‘: ‘上传人员信息文件‘, 227 //以get方式提交,默认post 228 ‘method‘: ‘post‘, 229 //单个文件大小,0为无限制,可接受KB,MB,GB等单位的字符串值 上传大文件 230 ‘fileSizeLimit‘: ‘0‘, 231 ‘queueSizeLimit‘: 1, 232 //文件描述 233 ‘fileTypeDesc‘: ‘Files‘, 234 ‘multi‘: false, 235 //允许上传的文件类型 以分号分割 236 ‘fileTypeExts‘: ‘*.xlsx‘, 237 //当浏览文件对话框关闭触发 238 ‘onDialogClose‘: function (queueData) { 239 if (queueData.filesSelected>0) { 240 $("#spanMsg").html("正在处理上传的文件,请稍等...."); 241 } 242 }, 243 //FLash文件路径 244 ‘swf‘: ‘/Scripts/uploadify/js/uploadify3.2.1/uploadify.swf‘, 245 //上传文件处理后台页面 246 ‘uploader‘: ‘/Ashx/SampleUp.ashx?action=xlsUpload‘, 247 //上传成功后触发,每个文件都触发 248 ‘onUploadSuccess‘: function (file, data, response) { 249 if (data == "0") { 250 alert("人员信息有不合法数据,请检查后再次上传"); 251 return false; 252 } else { 253 window.location = window.location; 254 } 255 } 256 }); 257 }); 258 var strSignCode = ""; 259 function Upload(strCode) { 260 strSignCode = strCode; 261 //打开弹出框的按钮 262 //单击按钮 调用弹出框的open方法 263 $("#dialog").dialog("open"); 264 //上传 265 //上传插件初始化方法 266 $(‘#btnUpload‘).uploadify({ 267 268 //选择文件后是否自动上传,默认为true 269 ‘auto‘: true, 270 //选择文件按钮 271 ‘buttonClass‘: ‘some-class‘, 272 273 //设置按钮文本 274 ‘buttonText‘: ‘上传样本‘, 275 ‘method‘: ‘post‘, 276 //单个文件大小,0为无限制,可接受KB,MB,GB等单位的字符串值 上传大文件 可参考使用手册说明 277 ‘fileSizeLimit‘: ‘0‘, 278 ‘queueSizeLimit‘: 1, 279 //文件描述 280 ‘fileTypeDesc‘: ‘Files‘, 281 ‘multi‘: false, 282 //允许上传的文件类型 以分号分割 283 ‘fileTypeExts‘: ‘*.sign‘, 284 ‘onUploadStart‘: function (file) { 285 $("#btnUpload").uploadify("settings", "formData", { ‘code‘: strSignCode }); 286 }, 287 //FLash文件路径 288 ‘swf‘: ‘/Scripts/uploadify/js/uploadify3.2.1/uploadify.swf‘, 289 //上传文件处理后台页面 290 ‘uploader‘: ‘/Ashx/SampleUp.ashx?action=mainUpload‘, 291 //上传成功后触发,每个文件都触发 292 ‘onUploadSuccess‘: function (file, data, response) { 293 // window.location = window.location; 294 //上传成功,改变单元格内容,并停留在当前页面,可以避免刷新回到首页的情况。 295 $("#td" + strSignCode).html("<span>" + data + "</span>"); 296 $("#dialog").dialog("close"); 297 } 298 }); 299 } 300 301 //查询相关方法 302 //获得焦点时,将文本框清空,并移除样式。 303 //失去焦点时,判断是否为空,为空则将提示信息重新填回,并添加样式。 304 $("#txtSearch").focus(function () { 305 if ($(this).val() == "请输入查询关键字") { 306 $(this).val(""); 307 $(this).removeClass("search"); 308 } 309 }).blur(function () { 310 if ($(this).val() == "") { 311 $(this).val("请输入查询关键字"); 312 $(this).addClass("search"); 313 } 314 }); 315 316 </script>
添加人员信息页面:
业务逻辑:签名样本应跟签名人编号相同。只有输入了编号,才允许上传,并且保证上传后的签名样本名称为只读的。
关于只读框和密码框应注意的地方:[Asp.net]说说密码框和只读框
输入用户名后:
用户编辑页面:
由于添加和编辑页面代码较简单,就不再贴代码,需注意的就是只读框的取值。
辅助类
1 public class ExcelHelper 2 { 3 /// <summary> 4 /// 将Excel文件中的数据读出到DataTable中 5 /// </summary> 6 /// <param name="strFile">文件路径</param> 7 /// <returns>datatable</returns> 8 public static DataTable Excel2DataTable(string strFile, string strSheetName, string strTableName) 9 { 10 DataTable dt = new DataTable(); 11 IWorkbook workbook = null; 12 using (FileStream fs = new FileStream(strFile, FileMode.Open, FileAccess.Read)) 13 { 14 //office2003 HSSFWorkbook 15 //office2007 XSSFWorkbook初始化 16 workbook = new XSSFWorkbook(fs); 17 } 18 ISheet sheet = workbook.GetSheet(strSheetName); 19 // 20 dt = Export2DataTable(sheet, 0, false); 21 return dt; 22 23 } 24 /// <summary> 25 /// 将指定sheet中的数据导入到datatable中 26 /// </summary> 27 /// <param name="sheet">指定需要导出的sheet</param> 28 /// <param name="HeaderRowIndex">列头所在的行号,-1没有列头</param> 29 /// <param name="needHeader">是否需要列头</param> 30 /// <returns>DataTable</returns> 31 private static DataTable Export2DataTable(ISheet sheet, int HeaderRowIndex, bool needHeader) 32 { 33 DataTable dt = new DataTable(); 34 XSSFRow headerRow = null; 35 int cellCount; 36 try 37 { 38 if (HeaderRowIndex < 0 || !needHeader) 39 { 40 headerRow = sheet.GetRow(0) as XSSFRow; 41 cellCount = headerRow.LastCellNum; 42 for (int i = headerRow.FirstCellNum; i <= cellCount; i++) 43 { 44 DataColumn column = new DataColumn(Convert.ToString(i)); 45 dt.Columns.Add(column); 46 } 47 } 48 else 49 { 50 headerRow = sheet.GetRow(HeaderRowIndex) as XSSFRow; 51 cellCount = headerRow.LastCellNum; 52 for (int i = headerRow.FirstCellNum; i <= cellCount; i++) 53 { 54 ICell cell = headerRow.GetCell(i); 55 if (cell == null) 56 { 57 break;//到最后 跳出循环 58 } 59 else 60 { 61 //创建列 62 DataColumn column = new DataColumn(headerRow.GetCell(i).ToString()); 63 //将列添加到datatable中 64 dt.Columns.Add(column); 65 } 66 67 } 68 } 69 //保存最后一行的索引 70 int intRowCount = sheet.LastRowNum; 71 for (int i = HeaderRowIndex + 1; i <= sheet.LastRowNum; i++) 72 { 73 XSSFRow xSSFRow = null; 74 if (sheet.GetRow(i) == null) 75 { 76 xSSFRow = sheet.CreateRow(i) as XSSFRow; 77 } 78 else 79 { 80 xSSFRow = sheet.GetRow(i) as XSSFRow; 81 } 82 DataRow dtRow = dt.NewRow(); 83 for (int j = xSSFRow.FirstCellNum; j <= cellCount; j++) 84 { 85 //j=-1表示没有数据了 86 if (j != -1 && xSSFRow.GetCell(j) != null) 87 { 88 switch (xSSFRow.GetCell(j).CellType) 89 { 90 case CellType.Boolean: 91 dtRow[j] = Convert.ToString(xSSFRow.GetCell(j).BooleanCellValue); 92 break; 93 case CellType.Error: 94 dtRow[j] = ErrorEval.GetText(xSSFRow.GetCell(j).ErrorCellValue); 95 break; 96 case CellType.Formula: 97 switch (xSSFRow.GetCell(j).CachedFormulaResultType) 98 { 99 100 case CellType.Boolean: 101 dtRow[j] = Convert.ToString(xSSFRow.GetCell(j).BooleanCellValue); 102 103 break; 104 case CellType.Error: 105 dtRow[j] = ErrorEval.GetText(xSSFRow.GetCell(j).ErrorCellValue); 106 107 break; 108 case CellType.Numeric: 109 dtRow[j] = Convert.ToString(xSSFRow.GetCell(j).NumericCellValue); 110 111 break; 112 case CellType.String: 113 string strFORMULA = xSSFRow.GetCell(j).StringCellValue; 114 if (strFORMULA != null && strFORMULA.Length > 0) 115 { 116 dtRow[j] = strFORMULA.ToString(); 117 } 118 else 119 { 120 dtRow[j] = null; 121 } 122 break; 123 default: 124 dtRow[j] = ""; 125 break; 126 } 127 break; 128 case CellType.Numeric: 129 if (DateUtil.IsCellDateFormatted(xSSFRow.GetCell(j))) 130 { 131 dtRow[j] = DateTime.FromOADate(xSSFRow.GetCell(j).NumericCellValue); 132 } 133 else 134 { 135 dtRow[j] = Convert.ToDouble(xSSFRow.GetCell(j).NumericCellValue); 136 } 137 break; 138 case CellType.String: 139 string str = xSSFRow.GetCell(j).StringCellValue; 140 if (!string.IsNullOrEmpty(str)) 141 { 142 143 dtRow[j] = Convert.ToString(str); 144 } 145 else 146 { 147 dtRow[j] = null; 148 } 149 break; 150 default: 151 dtRow[j] = ""; 152 break; 153 } 154 } 155 else 156 { 157 break; 158 } 159 } 160 //将行加入datatable中 161 dt.Rows.Add(dtRow); 162 } 163 } 164 catch (Exception ex) 165 { 166 throw ex; 167 } 168 return dt; 169 } 170 /// <summary> 171 /// 将DataTable中的数据导入Excel文件中 172 /// </summary> 173 /// <param name="dt"></param> 174 /// <param name="strFile"></param> 175 public static void DataTable2Excel(DataTable dt, string strFile, string strSheetName) 176 { 177 IWorkbook workbook = new XSSFWorkbook(); 178 ISheet sheet = workbook.CreateSheet(strSheetName); 179 IRow header = sheet.CreateRow(0); 180 for (int i = 0; i < dt.Columns.Count; i++) 181 { 182 ICell cell = header.CreateCell(i); 183 cell.SetCellValue(dt.Columns[i].ColumnName); 184 } 185 //数据 186 for (int i = 0; i < dt.Rows.Count; i++) 187 { 188 IRow row = sheet.CreateRow(i + 1); 189 for (int j = 0; j < dt.Columns.Count; j++) 190 { 191 ICell cell = row.CreateCell(j); 192 cell.SetCellValue(dt.Rows[i][j].ToString()); 193 } 194 } 195 MemoryStream stream = new MemoryStream(); 196 workbook.Write(stream); 197 byte[] buffer = stream.ToArray(); 198 using (FileStream fs = new FileStream(strFile, FileMode.Create, FileAccess.Write)) 199 { 200 fs.Write(buffer, 0, buffer.Length); 201 fs.Flush(); 202 } 203 } 204 /// <summary> 205 /// 获取单元格类型 206 /// </summary> 207 /// <param name="xSSFCell">单元格</param> 208 /// <returns>object</returns> 209 private static object GetValueType(XSSFCell xSSFCell) 210 { 211 if (xSSFCell == null) 212 { 213 return null; 214 } 215 switch (xSSFCell.CellType) 216 { 217 case CellType.Blank: 218 return null; 219 case CellType.Boolean: 220 return xSSFCell.BooleanCellValue; 221 case CellType.Error: 222 return xSSFCell.ErrorCellValue; 223 224 case CellType.Numeric: 225 return xSSFCell.NumericCellValue; 226 case CellType.String: 227 return xSSFCell.StringCellValue; 228 case CellType.Formula: 229 default: 230 return "=" + xSSFCell.StringCellValue; 231 } 232 } 233 234 }
1 public class FTPHelper 2 { 3 #region 字段 4 /// <summary> 5 /// ftp地址,带ftp协议 6 /// </summary> 7 private string strFtpURI; 8 /// <summary> 9 /// ftp用户名 10 /// </summary> 11 private string strFtpUserID; 12 /// <summary> 13 /// ftp的ip地址 14 /// </summary> 15 private string strFtpServerIP; 16 /// <summary> 17 /// ftp用户登录密码 18 /// </summary> 19 private string strFtpPassword; 20 /// <summary> 21 /// ftp目录路径 22 /// </summary> 23 private string strFtpRemotePath; 24 #endregion 25 26 /// <summary> 27 /// 连接FTP服务器 28 /// </summary> 29 /// <param name="strFtpServerIP">FTP连接地址</param> 30 /// <param name="strFtpRemotePath">指定FTP连接成功后的当前目录, 如果不指定即默认为根目录</param> 31 /// <param name="strFtpUserID">用户名</param> 32 /// <param name="strFtpPassword">密码</param> 33 public FTPHelper(string strFtpServerIP, string strFtpRemotePath, string strFtpUserID, string strFtpPassword) 34 { 35 this.strFtpServerIP = strFtpServerIP; 36 this.strFtpRemotePath = strFtpRemotePath; 37 this.strFtpUserID = strFtpUserID; 38 this.strFtpPassword = strFtpPassword; 39 this.strFtpURI = "ftp://" + strFtpServerIP + strFtpRemotePath; 40 } 41 42 /// <summary> 43 /// 上载 44 /// </summary> 45 /// <param name="strFilename">本地文件路径</param> 46 /// <param name="strSavePath">ftp服务器文件保存路径</param> 47 public void Upload(string strFilename, string strSavePath) 48 { 49 FileInfo fileInf = new FileInfo(strFilename); 50 FtpWebRequest reqFTP; 51 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strSavePath + fileInf.Name)); 52 reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword); 53 reqFTP.Method = WebRequestMethods.Ftp.UploadFile; 54 reqFTP.KeepAlive = false; 55 reqFTP.UseBinary = true; 56 reqFTP.Proxy = null; 57 reqFTP.ContentLength = fileInf.Length; 58 int buffLength = 2048; 59 byte[] buff = new byte[buffLength]; 60 int contentLen; 61 FileStream fs = fileInf.OpenRead(); 62 try 63 { 64 Stream strm = reqFTP.GetRequestStream(); 65 contentLen = fs.Read(buff, 0, buffLength); 66 while (contentLen != 0) 67 { 68 strm.Write(buff, 0, contentLen); 69 contentLen = fs.Read(buff, 0, buffLength); 70 } 71 strm.Close(); 72 fs.Close(); 73 } 74 catch (Exception ex) 75 { 76 throw new Exception(ex.Message); 77 } 78 } 79 /// <summary> 80 /// 上载 81 /// </summary> 82 /// <param name="strFilename">本地文件路径</param> 83 /// <param name="strSavePath">ftp服务器文件保存路径</param> 84 /// <param name="strStrOldName">ftp服务器文件保存的名字</param> 85 public void Upload(string strFilename, string strSavePath, string strStrOldName) 86 { 87 FileInfo fileInf = new FileInfo(strFilename); 88 FtpWebRequest reqFTP; 89 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strSavePath + strStrOldName)); 90 reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword); 91 reqFTP.Method = WebRequestMethods.Ftp.UploadFile; 92 reqFTP.KeepAlive = false; 93 reqFTP.UseBinary = true; 94 reqFTP.Proxy = null; 95 reqFTP.ContentLength = fileInf.Length; 96 int buffLength = 2048; 97 byte[] buff = new byte[buffLength]; 98 int contentLen; 99 FileStream fs = fileInf.OpenRead(); 100 try 101 { 102 Stream strm = reqFTP.GetRequestStream(); 103 contentLen = fs.Read(buff, 0, buffLength); 104 while (contentLen != 0) 105 { 106 strm.Write(buff, 0, contentLen); 107 contentLen = fs.Read(buff, 0, buffLength); 108 } 109 strm.Close(); 110 fs.Close(); 111 } 112 catch (Exception ex) 113 { 114 throw new Exception(ex.Message); 115 } 116 } 117 /// <summary> 118 /// 下载 119 /// </summary> 120 /// <param name="strFilePath">本地保存路径</param> 121 /// <param name="strFileName">文件名</param> 122 /// <param name="strFileName">本地临时名称</param> 123 public void Download(string strFilePath, string strFileName, string strLocalName) 124 { 125 try 126 { 127 FileStream outputStream = new FileStream(strFilePath + strLocalName, FileMode.Create); 128 FtpWebRequest reqFTP; 129 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strFileName)); 130 reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword); 131 reqFTP.Method = WebRequestMethods.Ftp.DownloadFile; 132 reqFTP.UseBinary = true; 133 reqFTP.UsePassive = true; 134 reqFTP.Proxy = null; 135 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 136 Stream ftpStream = response.GetResponseStream(); 137 long cl = response.ContentLength; 138 int bufferSize = 2048; 139 int readCount; 140 byte[] buffer = new byte[bufferSize]; 141 readCount = ftpStream.Read(buffer, 0, bufferSize); 142 while (readCount > 0) 143 { 144 outputStream.Write(buffer, 0, readCount); 145 readCount = ftpStream.Read(buffer, 0, bufferSize); 146 } 147 ftpStream.Close(); 148 outputStream.Close(); 149 response.Close(); 150 } 151 catch (Exception ex) 152 { 153 //记录日志 154 Common.LogHelper.WriteLog("文件下载异常:" + ex.Message); 155 } 156 } 157 /// <summary> 158 /// 下载 159 /// </summary> 160 /// <param name="strFilePath">本地保存路径</param> 161 /// <param name="strFileName">文件名</param> 162 public void Download(string strFilePath, string strFileName) 163 { 164 try 165 { 166 FileStream outputStream = new FileStream(strFilePath + strFileName, FileMode.Create); 167 FtpWebRequest reqFTP; 168 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strFileName)); 169 reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword); 170 reqFTP.Method = WebRequestMethods.Ftp.DownloadFile; 171 reqFTP.UseBinary = true; 172 reqFTP.UsePassive = true; 173 reqFTP.Proxy = null; 174 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 175 Stream ftpStream = response.GetResponseStream(); 176 long cl = response.ContentLength; 177 int bufferSize = 2048; 178 int readCount; 179 byte[] buffer = new byte[bufferSize]; 180 readCount = ftpStream.Read(buffer, 0, bufferSize); 181 while (readCount > 0) 182 { 183 outputStream.Write(buffer, 0, readCount); 184 readCount = ftpStream.Read(buffer, 0, bufferSize); 185 } 186 ftpStream.Close(); 187 outputStream.Close(); 188 response.Close(); 189 } 190 catch (Exception ex) 191 { 192 //记录日志 193 Common.LogHelper.WriteLog("文件下载异常:" + ex.Message); 194 } 195 } 196 /// <summary> 197 /// 删除文件 198 /// </summary> 199 /// <param name="strFileName">文件名</param> 200 public void Delete(string strFileName) 201 { 202 try 203 { 204 FtpWebRequest reqFTP; 205 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strFileName)); 206 reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword); 207 reqFTP.Method = WebRequestMethods.Ftp.DeleteFile; 208 reqFTP.KeepAlive = false; 209 string result = String.Empty; 210 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 211 long size = response.ContentLength; 212 Stream datastream = response.GetResponseStream(); 213 StreamReader sr = new StreamReader(datastream); 214 result = sr.ReadToEnd(); 215 sr.Close(); 216 datastream.Close(); 217 response.Close(); 218 } 219 catch (Exception ex) 220 { 221 throw new Exception(ex.Message); 222 } 223 } 224 225 /// <summary> 226 /// 获取当前目录下明细(包含文件和文件夹) 227 /// </summary> 228 /// <returns></returns> 229 public string[] GetFilesDetailList() 230 { 231 try 232 { 233 StringBuilder result = new StringBuilder(); 234 FtpWebRequest ftp; 235 ftp = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI)); 236 ftp.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword); 237 ftp.Method = WebRequestMethods.Ftp.ListDirectoryDetails; 238 WebResponse response = ftp.GetResponse(); 239 StreamReader reader = new StreamReader(response.GetResponseStream()); 240 string line = reader.ReadLine(); 241 line = reader.ReadLine(); 242 line = reader.ReadLine(); 243 while (line != null) 244 { 245 result.Append(line); 246 result.Append("\n"); 247 line = reader.ReadLine(); 248 } 249 result.Remove(result.ToString().LastIndexOf("\n"), 1); 250 reader.Close(); 251 response.Close(); 252 return result.ToString().Split(‘\n‘); 253 } 254 catch (Exception ex) 255 { 256 throw new Exception(ex.Message); 257 } 258 } 259 260 /// <summary> 261 /// 获取FTP文件列表(包括文件夹) 262 /// </summary> 263 /// <param name="strUrl"></param> 264 /// <returns></returns> 265 private string[] GetAllList(string strUrl) 266 { 267 List<string> list = new List<string>(); 268 FtpWebRequest req = (FtpWebRequest)WebRequest.Create(new Uri(strUrl)); 269 req.Credentials = new NetworkCredential(strFtpPassword, strFtpPassword); 270 req.Method = WebRequestMethods.Ftp.ListDirectory; 271 req.UseBinary = true; 272 req.UsePassive = true; 273 try 274 { 275 using (FtpWebResponse res = (FtpWebResponse)req.GetResponse()) 276 { 277 using (StreamReader sr = new StreamReader(res.GetResponseStream())) 278 { 279 string s; 280 while ((s = sr.ReadLine()) != null) 281 { 282 list.Add(s); 283 } 284 } 285 } 286 } 287 catch (Exception ex) 288 { 289 throw (ex); 290 } 291 return list.ToArray(); 292 } 293 294 /// <summary> 295 /// 获取当前目录下文件列表(不包括文件夹) 296 /// </summary> 297 public string[] GetFileList(string strUrl) 298 { 299 StringBuilder result = new StringBuilder(); 300 FtpWebRequest reqFTP; 301 try 302 { 303 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strUrl)); 304 reqFTP.UseBinary = true; 305 reqFTP.Credentials = new NetworkCredential(strFtpPassword, strFtpPassword); 306 reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails; 307 WebResponse response = reqFTP.GetResponse(); 308 StreamReader reader = new StreamReader(response.GetResponseStream()); 309 string line = reader.ReadLine(); 310 while (line != null) 311 { 312 313 if (line.IndexOf("<DIR>") == -1) 314 { 315 result.Append(Regex.Match(line, @"[\S]+ [\S]+", RegexOptions.IgnoreCase).Value.Split(‘ ‘)[1]); 316 result.Append("\n"); 317 } 318 line = reader.ReadLine(); 319 } 320 result.Remove(result.ToString().LastIndexOf(‘\n‘), 1); 321 reader.Close(); 322 response.Close(); 323 } 324 catch (Exception ex) 325 { 326 throw (ex); 327 } 328 return result.ToString().Split(‘\n‘); 329 } 330 331 /// <summary> 332 /// 判断当前目录下指定的文件是否存在 333 /// </summary> 334 /// <param name="strRemoteFileName">远程文件名</param> 335 public bool FileExist(string strRemoteFileName) 336 { 337 string[] fileList = GetFileList("*.*"); 338 foreach (string str in fileList) 339 { 340 if (str.Trim() == strRemoteFileName.Trim()) 341 { 342 return true; 343 } 344 } 345 return false; 346 } 347 348 /// <summary> 349 /// 创建文件夹 350 /// </summary> 351 /// <param name="strDirName">目录名</param> 352 public void MakeDir(string strDirName) 353 { 354 FtpWebRequest reqFTP; 355 try 356 { 357 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strDirName)); 358 reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory; 359 reqFTP.UseBinary = true; 360 reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword); 361 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 362 Stream ftpStream = response.GetResponseStream(); 363 ftpStream.Close(); 364 response.Close(); 365 } 366 catch (Exception ex) 367 { Common.LogHelper.WriteLog("ftp服务器创建目录异常:" + ex.Message); } 368 } 369 370 /// <summary> 371 /// 获取指定文件大小 372 /// </summary> 373 public long GetFileSize(string strFilename) 374 { 375 FtpWebRequest reqFTP; 376 long fileSize = 0; 377 try 378 { 379 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strFilename)); 380 reqFTP.Method = WebRequestMethods.Ftp.GetFileSize; 381 reqFTP.UseBinary = true; 382 reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword); 383 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 384 Stream ftpStream = response.GetResponseStream(); 385 fileSize = response.ContentLength; 386 ftpStream.Close(); 387 response.Close(); 388 } 389 catch (Exception ex) 390 { throw ex; } 391 return fileSize; 392 } 393 394 /// <summary> 395 /// 更改文件名 396 /// </summary> 397 public void ReName(string strCurrentFilename, string strNewFilename) 398 { 399 FtpWebRequest reqFTP; 400 try 401 { 402 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(strFtpURI + strCurrentFilename)); 403 reqFTP.Method = WebRequestMethods.Ftp.Rename; 404 reqFTP.RenameTo = strNewFilename; 405 reqFTP.UseBinary = true; 406 reqFTP.Credentials = new NetworkCredential(strFtpUserID, strFtpPassword); 407 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 408 Stream ftpStream = response.GetResponseStream(); 409 ftpStream.Close(); 410 response.Close(); 411 } 412 catch (Exception ex) 413 { throw ex; } 414 } 415 416 /// <summary> 417 /// 移动文件 418 /// </summary> 419 public void MovieFile(string strCurrentFilename, string strNewDirectory) 420 { 421 ReName(strCurrentFilename, strNewDirectory); 422 } 423 424 /// <summary> 425 /// 切换当前目录 426 /// </summary> 427 /// <param name="bIsRoot">true:绝对路径 false:相对路径</param> 428 public void GotoDirectory(string strDirectoryName, bool bIsRoot) 429 { 430 if (bIsRoot) 431 { 432 strFtpRemotePath = strDirectoryName; 433 } 434 else 435 { 436 strFtpRemotePath += strDirectoryName + "/"; 437 } 438 strFtpURI = "ftp://" + strFtpServerIP + "/" + strFtpRemotePath + "/"; 439 } 440 }
Windows服务轮询
代码很简单,这里说明一下需要注意的地方,由于要调用c++动态链接库,并不是所有的异常信息都能catch到,所以在遇到bug的时候,比如dwg文件错误,就会造成服务停止,为了不让用户手动进入服务器进行手动启用,弄了一个exe程序,监听该服务是否启用,如果停用了,隔一段时间进行再次启用。
总结
由于该项目,客户只有管理员一个人使用,所以对项目的要求并不高,便宜我了,通过该项目,学到很多东西,之前也就负责功能模块,很没意思,不过这种从前端,到后台到数据库,都是自己弄的还是很有成就感的。
下周要去给客户部署了,最近一直在测试,一直在优化代码,轮询这块本来就是很费性能的,所以能想到的优化都用上了。
项目很小,也没什么要求只要能实现就可以,所以就随意发挥了。就当练练手了。