1. 程式人生 > >數據交換運行狀況檢查

數據交換運行狀況檢查

根據 我只 ast off 郵件內容 ssl array 查看 form

我手上有關數據交換的項目比較多,而且比較分散. 最新業務量大到一定程度,我需要知道每個事項任務每天數據量交換的情況, 有一部分是用SSIS包執行的,有一部分是通過xml數據交換的,

還有一部分, 是通過pdf文件上傳做交換的,還有ftp文件下載等等,總之就是很雜.

我想寫一個工具, 把這些交換的東西全部整合一下,做一下統計,然後每天出一個報告. 我就開始準備我的程序.

我想要實現的功能包括如下幾個方面:

1.多數據庫連接 ,各個系統都在不同的數據庫裏面

2.要將結果生成到Excel裏面

3.為了轉發方便, 我需要生成郵件,然後群發,這樣就可以共享了.

首先我使用 EntityFrameWork 作為數據底層, 這樣也是為了方便操作數據庫, 然後 我希望對各表進行讀取,有一些復雜的查詢語句,我希望能夠直接執行,

因為要時常統計多個數據庫中的表信息,所以我做了如下的封裝. (我只希望有查詢的功能)

 public class SqlDBHelper<T> where T : class
    {

        DbContext context = null;
        

        public SqlDBHelper()
        {
            context = new DbContext("
defaultDBEntity"); } public SqlDBHelper(string dbEntityName) { context = new DbContext(dbEntityName); } /// <summary> /// 按條件查詢 /// </summary> /// <param name="where"></param> /// <returns></returns>
public IQueryable<T> FindList(Expression<Func<T, bool>> where) { var temp = context.Set<T>().Where(where); return temp; } /// <summary> /// 按條件查詢,排序 /// </summary> /// <typeparam name="S"><peparam> /// <param name="where"></param> /// <param name="orderBy"></param> /// <param name="isAsc"></param> /// <returns></returns> public IQueryable<T> FindList<S>(Expression<Func<T, bool>> where, Expression<Func<T, S>> orderBy, bool isAsc) { var list = context.Set<T>().Where(where); if (isAsc) list = list.OrderBy<T, S>(orderBy); else list = list.OrderByDescending<T, S>(orderBy); return list; } /// <summary> /// 按條件查詢,分頁 /// </summary> /// <param name="pageIndex"></param> /// <param name="pageSize"></param> /// <param name="rowCount"></param> /// <param name="where"></param> /// <returns></returns> public IQueryable<T> FindPagedList(int pageIndex, int pageSize, out int rowCount, Expression<Func<T, bool>> where) { var list = context.Set<T>().Where(where); rowCount = list.Count(); list = list.Skip(pageSize * (pageIndex - 1)).Take(pageSize); return list; } /// <summary> /// 按條件查詢,分頁,排序 /// </summary> /// <typeparam name="S"><peparam> /// <param name="pageIndex"></param> /// <param name="pageSize"></param> /// <param name="rowCount"></param> /// <param name="where"></param> /// <param name="orderBy"></param> /// <param name="isAsc"></param> /// <returns></returns> public IQueryable<T> FindPagedList<S>(int pageIndex, int pageSize, out int rowCount, Expression<Func<T, bool>> where, Expression<Func<T, S>> orderBy, bool isAsc) { var list = context.Set<T>().Where(where); rowCount = list.Count(); if (isAsc) list = list.OrderBy<T, S>(orderBy).Skip(pageSize * (pageIndex - 1)).Take(pageSize); else list = list.OrderByDescending<T, S>(orderBy).Skip(pageSize * (pageIndex - 1)).Take(pageSize); return list; } public IQueryable<T> ExecuteQuery(string sql) { //"select Name,Count(*) Count from T_Persons where Id>{0} and CreateDateTime<={1} group by Name" var q1 = context.Database.SqlQuery<T>(sql).AsQueryable(); return q1; } }

如果希望有 增刪改, 可以補上以下代碼. (統計,由於是正式庫,應該只賦予只讀的數據權限)

        /// <summary>
        /// 新增一個實體
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Add(T entity)
        {
            context.Entry<T>(entity).State = System.Data.Entity.EntityState.Added;
            return context.SaveChanges();
        }
        /// <summary>
        /// 刪除一個實體
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Remove(T entity)
        {
            context.Entry<T>(entity).State = System.Data.Entity.EntityState.Deleted;
            return context.SaveChanges();
        }
        /// <summary>
        /// 修改一個實體
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Update(T entity)
        {
            context.Entry<T>(entity).State = System.Data.Entity.EntityState.Modified;
            return context.SaveChanges();
        }
        /// <summary>
        /// 批量新增實體
        /// </summary>
        /// <param name="dbContext"></param>
        /// <returns></returns>
        public int AddList(params T[] entities)
        {
            int result = 0;
            for (int i = 0; i < entities.Count(); i++)
            {
                if (entities[i] == null)
                    continue;
                context.Entry<T>(entities[i]).State = System.Data.Entity.EntityState.Added;
                if (i != 0 && i % 20 == 0)
                {
                    result += context.SaveChanges();
                }
            }
            if (entities.Count() > 0)
                result += context.SaveChanges();
            return result;
        }
        /// <summary>
        /// 批量刪除實體
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public int RemoveList(Expression<Func<T, bool>> where)
        {
            var temp = context.Set<T>().Where(where);
            foreach (var item in temp)
            {
                context.Entry<T>(item).State = System.Data.Entity.EntityState.Deleted;
            }
            return context.SaveChanges();
        }

具體使用的時候, 指定數據庫實體,然後設置 實體表對象,進行查詢

       const string objEntName = "DBTest3Entities";

        public List<CheckDataModel> GetDataUploadDZ()
        {

            DBHelper<DataUploadDZ> helper1 = new DBHelper<DataUploadDZ>(objEntName);
            DataUploadDZ uploadDz = helper1.FindList(c => c.Id > 0).OrderByDescending(c => c.CreateTime).Take(1).FirstOrDefault();
            //省略 邏輯處理,以及 return 語句
        }

最後從 各個數據庫裏面,查詢出對應的信息, 整理成統一的格式, 進行 生成Excel 以及發送Html 郵件

          List<CheckDataModel> list12 = new List<CheckDataModel>();
            //省略邏輯處理
            list1.RemoveAll(c => c.LogicName == null || c.LogicName == "");

            for (int i = 0; i < list1.Count; i++)
            {
                list1[i].Xh = (i + 1).ToString();
            }
            //然後將數據List 寫入表格, 以及導出Excel

            //數據有了, 現在開始生成 Html頁面, 以及Excel附件

          

            DataTable table = TableListHelper.ToDataTable<CheckDataModel>(list1);
            DataRow newRow = table.NewRow();
            newRow[0] = " 序號 ";
            newRow[1] = "  運行時間設定  ";
            newRow[2] = "  業務名稱  ";
            newRow[3] = "  業務簡稱代碼  ";
            newRow[4] = "  最後一次運行時間  ";
            newRow[5] = "  運行狀態  ";
            newRow[6] = "  錯誤信息  ";

            //序號</th><th>運行時間設定</th><th>業務名稱</th><th>業務簡稱代碼</th><th>最後一次運行時間</th><th>運行狀態</th><th>錯誤信息</th>

            table.Rows.InsertAt(newRow, 0);

            string filePath = @"E:\ApplicationRun\CheckDataExcel\" + "每日數據交換運行狀況檢查" + DateTime.Now.ToString("yyyy-MM-dd") + ".xlsx";
            if (File.Exists(filePath))
            {
                FileInfo fi = new FileInfo(filePath);
                if (fi.Length < 1024)
                {
                    fi.Delete(); //如果文件小於1kb, 刪除該文件
                }
            }
            if (!File.Exists(filePath))
            {
                //如果文件不存在,就生成excel,並且發送郵件
                NpoiExcelHelper.CreateExcel(table, filePath);
            }
            string htmlContent = GetHtmlContent(list1);
            SendEmail(htmlContent, filePath);

首先將List轉換成 DataTable

public static DataTable ToDataTable<T>(IEnumerable<T> collection)
        {
            var props = typeof(T).GetProperties();
            var dt = new DataTable();
            dt.Columns.AddRange(props.Select(p => new DataColumn(p.Name, p.PropertyType)).ToArray());
            if (collection.Count() > 0)
            {
                for (int i = 0; i < collection.Count(); i++)
                {
                    ArrayList tempList = new ArrayList();
                    foreach (PropertyInfo pi in props)
                    {
                        object obj = pi.GetValue(collection.ElementAt(i), null);
                        tempList.Add(obj);
                    }
                    object[] array = tempList.ToArray();
                    dt.LoadDataRow(array, true);
                }
            }
            return dt;
        }

然後生成Html代碼,這裏生成一個Html,帶表格的頁面

        private string GetHtmlContent(List<CheckDataModel> listData)
        {
            StringBuilder sb = new StringBuilder(256);

            sb.Append("<!DOCTYPE html>");
            sb.Append("<html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">");
            sb.Append("<head> <meta charset=\"utf-8\" /> <title></title></head>");

            sb.Append("<style>").AppendLine();

            sb.Append("table { border-left: 1px solid black;border-top: 1px solid black;}").AppendLine();
            sb.Append("td { border-right: 1px solid black; border-bottom: 1px solid black;padding:0px 5px;}").AppendLine();
            sb.Append("th { border-right: 1px solid black; border-bottom: 1px solid black;padding:0px 5px;}").AppendLine();
            sb.Append("</style>").AppendLine();

            sb.Append("<html><body>").AppendLine();
            sb.Append("<table cellspacing=\"0\" cellpadding=\"0\">").AppendLine(); ;
            sb.Append(string.Format("<th>序號</th><th>運行時間設定</th><th>業務名稱</th><th>業務簡稱代碼</th><th>最後一次運行時間</th><th>運行狀態</th><th>錯誤信息</th>"));

            for (int i = 0; i < listData.Count; i++)
            {

                sb.Append(string.Format("<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td><td>{6}</td></tr>",
                    listData[i].Xh, listData[i].RunTimeSD, listData[i].LogicName, listData[i].LogicCode, listData[i].LastRunTime, listData[i].RunStatus, 
(
string.IsNullOrEmpty(listData[i].Remark) ? "&nbsp;" : listData[i].Remark))); } sb.Append("</table>").AppendLine(); sb.Append("</body></html>"); string result = sb.ToString(); return result; }

發郵件,使用QQ的 STMP3 ,這裏特別說一下, QQ現在不是直接使用郵箱密碼,而是要發送短信去生成一個 code,用這種方式可以保護郵箱密碼不被泄露

private void SendEmail(string htmlContent, string filePath)
        {
            try
            {
                var reciver = ConfigurationManager.AppSettings["EmailAddress"].ToString();
                 
                string mailfrom = "[email protected]";

                string mailPwd = "********";
                //mcyabgovpiuebbfd
                // var content = rtxt_Content.Text;
                MailMessage message = new MailMessage();
                //設置發件人,發件人需要與設置的郵件發送服務器的郵箱一致
                MailAddress fromAddr = new MailAddress(mailfrom);
                message.From = fromAddr;
                //設置收件人,可添加多個,添加方法與下面的一樣
                message.To.Add(reciver);
                //設置抄送人
                // message.CC.Add("[email protected]");
                //設置郵件標題
                message.Subject = "每日運行數據檢查" + DateTime.Now.ToString("yyyy-MM-dd");

                if (filePath != "")
                {
                    //如果有附件,添加附件
                    Attachment data = new Attachment(filePath, MediaTypeNames.Application.Octet);
                   
                    ContentDisposition disposition = data.ContentDisposition;
                    disposition.CreationDate = System.IO.File.GetCreationTime(filePath);
                    disposition.ModificationDate = System.IO.File.GetLastWriteTime(filePath);
                    disposition.ReadDate = System.IO.File.GetLastAccessTime(filePath);

                    message.Attachments.Add(data);
                    System.Net.Mime.ContentType ctype = new System.Net.Mime.ContentType();
                }

                message.IsBodyHtml = true; //是否為html格式
                //設置郵件內容
                message.Body = htmlContent;
                //設置郵件發送服務器,服務器根據你使用的郵箱而不同,可以到相應的 郵箱管理後臺查看,下面是QQ的
                SmtpClient client = new SmtpClient("smtp.qq.com");
                //設置發送人的郵箱賬號和密碼
                client.Credentials = new NetworkCredential(mailfrom, mailPwd);
                //啟用ssl,也就是安全發送
                client.EnableSsl = true;
                //發送郵件
                client.Send(message);

            }
            catch (Exception ex)
            {

                throw ex;
            }

        }

郵件內容,並且帶上附件Excel, 這裏生成Excel的方式, 我比較喜歡用 NPOI組件,這個不僅生成Excel 快速,而且可以不用安裝Office組件,依耐性低.

NPOI 組件, 是第三方 開源的, 可以到它的服務器上,去下載源代碼,這裏我只是簡單介紹下使用方式.

public class NpoiExcelHelper
    {
        public static void CreateExcel(DataTable table,string path)
        {
          
            XSSFWorkbook workbook2007 = new XSSFWorkbook();  //新建xlsx工作簿  
           
            ISheet sheet = workbook2007.CreateSheet("Sheet1");

            for (int i = 0; i < table.Rows.Count; i++)
            {
                IRow row = sheet.CreateRow(i); //i表示了創建行的索引,從0開始
                //創建單元格
                for (int j = 0; j < table.Columns.Count; j++)
                {
                    ICell cell = row.CreateCell(j);  //同時這個函數還有第二個重載,可以指定單元格存放數據的類型
                    cell.SetCellValue(table.Rows[i][j].ToString());
                }
            }
            FileStream file2007 = new FileStream(path, FileMode.Create);
            workbook2007.Write(file2007);
            file2007.Close();
            workbook2007.Close();  
        }
    }

這裏生成出來的是 xlsx的文件格式, 也就是 2007及以上版本.

嗯,好了,整個過程就是這樣了. 下面總結一下流程.

1.設置多個數據庫的Entity

2.進行查詢,封裝成統一的List<T>,顯示結果

3.為了友好的顯示,要生成Excel, 先將List<T>轉換成DataTable,再寫入Excel

4.根據DataTable,生成Html內容,然後作為郵件內容,發送出去.

5.郵件中順帶,將excel作為附件,一起發送.

6.按自己喜歡的方式, 我這裏是是配置成Windows計劃任務,這樣我每天上班打開電腦就能知道昨天的運行情況了.(一天檢查1次到2次)

說明: 不方便提供下載,所以進行了加密.

源代碼下載: ConDataCheck 下載 解壓密碼: 本機電腦PIN

數據交換運行狀況檢查