2016年6月30日 星期四

使用擴充方法將Linq資料集合轉成DataTable

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
static class IQueryableExtension
{
    public static DataTable ToDataTable<T>(this IQueryable<T> data)
    {
        PropertyDescriptorCollection properties =
            TypeDescriptor.GetProperties(typeof(T));
        DataTable table = new DataTable();
        foreach (PropertyDescriptor prop in properties)
            table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
        foreach (T item in data)
        {
            DataRow row = table.NewRow();
            foreach (PropertyDescriptor prop in properties)
                row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
            table.Rows.Add(row);
        }
        return table;
    }
}

遠端資料夾、網路芳鄰存取檔案

網路上別人寫好的遠端資料夾、網路芳鄰存取檔案的程式碼

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
namespace MyNameSpace
{

    #region Using directives.
    // ----------------------------------------------------------------------

    using System;
    using System.Security.Principal;
    using System.Runtime.InteropServices;
    using System.ComponentModel;

    // ----------------------------------------------------------------------
    #endregion

    /////////////////////////////////////////////////////////////////////////

    /// <summary>
    /// Impersonation of a user. Allows to execute code under another
    /// user context.
    /// Please note that the account that instantiates the Impersonator class
    /// needs to have the 'Act as part of operating system' privilege set.
    /// </summary>
    /// <remarks> 
    /// This class is based on the information in the Microsoft knowledge base
    /// article http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158
    /// 
    /// Encapsulate an instance into a using-directive like e.g.:
    /// 
    /// ...
    /// using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
    /// {
    /// ...
    /// [code that executes under the new context]
    /// ...
    /// }
    /// ...
    /// 
    /// Please contact the author Uwe Keim (mailto:uwe.keim@zeta-software.de)
    /// for questions regarding this class.
    /// </remarks>
    public class Impersonator :
        IDisposable
    {
        #region Public methods.
        // ------------------------------------------------------------------

        /// <summary>
        /// Constructor. Starts the impersonation with the given credentials.
        /// Please note that the account that instantiates the Impersonator class
        /// needs to have the 'Act as part of operating system' privilege set.
        /// </summary>
        /// <param name="userName">The name of the user to act as.</param>
        /// <param name="domainName">The domain name of the user to act as.</param>
        /// <param name="password">The password of the user to act as.</param>
        public Impersonator(
            string userName,
            string domainName,
            string password)
        {
            ImpersonateValidUser(userName, domainName, password);
        }

        // ------------------------------------------------------------------
        #endregion

        #region IDisposable member.
        // ------------------------------------------------------------------

        public void Dispose()
        {
            UndoImpersonation();
        }

        // ------------------------------------------------------------------
        #endregion

        #region P/Invoke.
        // ------------------------------------------------------------------

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern int LogonUser(
            string lpszUserName,
            string lpszDomain,
            string lpszPassword,
            int dwLogonType,
            int dwLogonProvider,
            ref IntPtr phToken);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int DuplicateToken(
            IntPtr hToken,
            int impersonationLevel,
            ref IntPtr hNewToken);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool RevertToSelf();

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern bool CloseHandle(
            IntPtr handle);

        private const int LOGON32_LOGON_INTERACTIVE = 2;
        private const int LOGON32_PROVIDER_DEFAULT = 0;
        private const int LOGON32_LOGON_NETWORK = 3;
        private const int LOGON32_LOGON_BATCH = 4;
        private const int LOGON32_LOGON_SERVICE = 5;
        private const int LOGON32_LOGON_UNLOCK = 7;
        private const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8; // Only for Win2K or higher 
        private const int LOGON32_LOGON_NEW_CREDENTIALS = 9; // Only for Win2K or higher 


        // ------------------------------------------------------------------
        #endregion

        #region Private member.
        // ------------------------------------------------------------------

        /// <summary>
        /// Does the actual impersonation.
        /// </summary>
        /// <param name="userName">The name of the user to act as.</param>
        /// <param name="domainName">The domain name of the user to act as.</param>
        /// <param name="password">The password of the user to act as.</param>
        private void ImpersonateValidUser(
            string userName,
            string domain,
            string password)
        {
            WindowsIdentity tempWindowsIdentity = null;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;

            try
            {
                if (RevertToSelf())
                {//LOGON32_LOGON_NETWORK_CLEARTEXT通常是在Server為了配合多平台的檔案寫入(例如:linux)
                    //才會用這個降低安全性的選項,讓server允許直接帳號密碼登入並且寫入檔案系統
                    //LOGON32_LOGON_NEW_CREDENTIALS才是一般server會採用的安全性作法,使用者需利用帳密取得一組credential
                    //再用credential去登入server, 方可寫入server的檔案系統
                    //完整的LogonType解釋詳見msdn
                    //https://msdn.microsoft.com/en-us/library/windows/desktop/aa378184(v=vs.85).aspx
                    //Server的這個設定在 程式集=>系統管理工具=>本機安全性原則裡面,此設定為進階設定,非mis人員通常很少設定他
                    if (LogonUser(
                        userName,
                        domain,
                        password,
                        LOGON32_LOGON_NEW_CREDENTIALS,
                        LOGON32_PROVIDER_DEFAULT,
                        ref token) != 0)
                    {
                        if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                        {
                            tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                            impersonationContext = tempWindowsIdentity.Impersonate();
                        }
                        else
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }
                    }
                    else
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                }
                else
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
            finally
            {
                if (token != IntPtr.Zero)
                {
                    CloseHandle(token);
                }
                if (tokenDuplicate != IntPtr.Zero)
                {
                    CloseHandle(tokenDuplicate);
                }
            }
        }

        /// <summary>
        /// Reverts the impersonation.
        /// </summary>
        private void UndoImpersonation()
        {
            if (impersonationContext != null)
            {
                impersonationContext.Undo();
            }
        }

        private WindowsImpersonationContext impersonationContext = null;

        // ------------------------------------------------------------------
        #endregion
    }

    /////////////////////////////////////////////////////////////////////////
}

使用方法:
1
2
3
4
5
6
7
8
string remotePath = @"\\RemoteIP\\Folder\\";
using (new Impersonator("yourUserName", "yourDomainName","yourPassword"))
{

 string[] Files = Directory.GetFiles(remotePath);

 File.Copy("localFile", "remoteFile", true);
}

參考資料:[.net]程式碼如何寫入網芳、網路磁碟、網路硬碟

2016年6月20日 星期一

[DateTime] Compare 回傳結果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
static void Main(string[] args)
{
    DateTime t1 = DateTime.Parse("2016-01-01");
    DateTime t2 = DateTime.Parse("2016-01-02");

    Console.WriteLine(t1.CompareTo(t2));  // DateTime.Compare(t1, t2);
    Console.WriteLine(t1.CompareTo(t1));  // DateTime.Compare(t1, t1);
    Console.WriteLine(t2.CompareTo(t1));  // DateTime.Compare(t2, t1);

    // t1 < t2 -> -1
    // t1 = t2 -> 0
    // t1 > t2 -> 1

    Console.ReadLine();
}

2016年6月4日 星期六

用描述屬性取得Enum的值

Using
1
2
using System.ComponentModel;
using System.Reflection;


Enum
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
    /// <summary>
    /// 權限類型
    /// </summary>
    public enum AuthType
    {
        [Description("Query")]
        Query,
        [Description("Add")]
        Add,
        [Description("Edit")]
        Edit,
        [Description("Delete")]
        Delete,
        [Description("Export")]
        Export,
        [Description("Import")]
        Import
    }


用描述屬性取得Enum的值
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
/// <summary>
/// 用描述屬性取得Enum的值
/// </summary>
/// <param name="value">Enum</param>
/// <returns></returns>
public string GetEnumDescription(Enum value)
{
    FieldInfo fi = value.GetType().GetField(value.ToString());
    DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
    return (attributes.Length > 0) ? attributes[0].Description : value.ToString();
}

使用反射取得物件屬性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/// <summary>
/// 用反射方式取得屬性
/// <para>Exception:屬性名稱不存在</para>
/// <para>Exception:屬性型態錯誤</para>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj">欲取得屬性的物件</param>
/// <param name="PropertyName">屬性名稱</param>
/// <returns></returns>
private T GetProperty<T>(object obj, string PropertyName)
{
    // 判斷有無該屬性名稱
    PropertyInfo propertyInfo = obj.GetType().GetProperty(PropertyName);
    if (propertyInfo == null)
    {
        throw new Exception("屬性名稱:" + PropertyName + ",不存在。");
    }

    // 判斷型態是否正確
    object tmp = propertyInfo.GetValue(obj);
    if (!(tmp is T))
    {
        throw new Exception("屬性型態錯誤。");
    }

    return (T)tmp;
}

2016年6月1日 星期三

AutoCompleteExtender By Ajax Using WebService

CSS
1
2
3
4
.CompletionListCssClass
{
    z-index:99999 !important;
}


aspx
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<asp:TextBox ID="TextBox_PY" runat="server"></asp:TextBox>
<asp:AutoCompleteExtender 
   ID="AutoCompleteExtender1"
   runat="server"
   MinimumPrefixLength="1"
   TargetControlID="TextBox_PY"
   ServiceMethod="GetCompletionList_PY"
   ServicePath="WebService/WebServiceTest.asmx"
   CompletionSetCount="20"
   CompletionListCssClass ="CompletionListCssClass"
/>


WebService.asmx.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace Project.WebService
{
    /// <summary>
    ///WebServiceTest 的摘要描述
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // 若要允許使用 ASP.NET AJAX 從指令碼呼叫此 Web 服務,請取消註解下列一行。
    [System.Web.Script.Services.ScriptService]
    public class WebServiceTest : System.Web.Services.WebService
    {
        [System.Web.Services.WebMethodAttribute(), System.Web.Script.Services.ScriptMethodAttribute()]
        //方法不可宣告static
        public string[] GetCompletionList_PY(string prefixText, int count)
        {
            //資料庫連線字串
            string connStr = @"Data Source=.;Initial Catalog=DatabaseName;User ID=id;Password=pw;";

            ArrayList array = new ArrayList();//儲存撈出來的字串集合

            using (SqlConnection conn = new SqlConnection(connStr))
            {
                DataSet ds = new DataSet();
                string selectStr = @"SELECT Top (" + count + ") [PY] FROM [View_PYList] Where [PY] Like '" + prefixText + "%' Order by [PY] ASC";
                SqlDataAdapter da = new SqlDataAdapter(selectStr, conn);
                conn.Open();
                da.Fill(ds);
                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    array.Add(dr["PY"].ToString());
                }
            }
            return (string[])array.ToArray(typeof(string));
        }
    }
}


AutoCompleteExtender參考:https://dotblogs.com.tw/shadow/archive/2011/05/08/24535.aspx

CSS參考:http://note.tc.edu.tw/598.html

2016年4月19日 星期二

Android - Universal-Image-Loader 加載網路圖片Lib

提供一個常用的第三方加載網路圖片的Lib 目前主流的好像是Universal-Image-Loader、Picasso、fresco,這幾個Lib都還蠻多人用的 這篇主要是介紹Universal-Image-Loader 簡單來說最簡單、支援度也很廣、又容易客製化,而且可以做Local端暫存 在開始前記得先把Jar檔import到專案裡 接著非常的簡單 基本上你什麼都不用設定就可以直接開始用了 因為套件本身有預設值
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//圖片網址
String mStrPicUrl="http://aaa.bbb.ccc/1234.jpg";

//ImageView呈現的元件
ImageView mImgView=findViewById(R.id.imageview); 

//使用方式,一般加載圖片
ImageLoader.getInstance().displayImage(mStrPicUrl,mImgView);
//使用方式,加載圖片,並加入顯示設定,在最下面會補充說明
ImageLoader.getInstance().displayImage(pic,mImgView,displayImageOptions );



//使用方式,加載圖片,並加入顯示設定及CallBack事件
ImageLoader.getInstance().displayImage(pic,mImgView,getImageLoaderOptions(), new ImageLoadingListener() {

                @Override
                public void onLoadingStarted(String s, View view) {
                    //開始loading時
                }

                @Override
                public void onLoadingFailed(String s, View view, FailReason failReason) {
                    //loading失敗時

}

                @Override
                public void onLoadingComplete(String s, View view, Bitmap bitmap) {
                   //loading完成時

}

                @Override
                public void onLoadingCancelled(String s, View view) {
                   //loading取消時
                }

            });
當然除了以上方法,還有其他呈現方式的組合,可以自行多嘗試 那如果想要在背景抓圖,不呈現在畫面 可以使用 //直接抓圖,但不顯示在畫面上,getImageLoaderOptionsWithLoading請參考最下面
ImageLoader.getInstance().loadImage(mStrPicUrl, getImageLoaderOptions(), callBackListenrs);
如果要進行客製化,其實步驟也很簡單 首先要有個Class,去繼承Application(相關用法及設定請自行google) 然後再該Class去Override繼承至Application的onCreate事件 並且在這邊去做一些Image-Loader的客製化設定
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class MyApplication extends Application {
    private static Context mContext;
    @Override
    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();
        initImageLoader();
  }

    private void initImageLoader() {
        ImageLoaderConfiguration config = new ImageLoaderConfiguration
                .Builder(mContext)
                .threadPoolSize(5) //執行序數,通常用預設就好
                .threadPriority(Thread.NORM_PRIORITY - 2) //執行續優先權
                .memoryCache(new LruMemoryCache(1 * 1024 * 1024)) 
                .memoryCacheSize(1 * 1024 * 1024) //記憶體暫存大小
                .discCacheSize(10 * 1024 * 1024) //儲存空間暫存大小
                .discCacheFileNameGenerator(new Md5FileNameGenerator())
                .tasksProcessingOrder(QueueProcessingType.LIFO) //佇列執行方式,預設是後進先出
//                .discCacheFileCount(100) //暫存檔案數量,如果需要設定檔案數量的話再設定
                .diskCache(new UnlimitedDiskCache(mContext.getCacheDir())) //設定暫存數量無上限
                .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) //預設的顯示圖片選項,可以再額外做設定,下面會補充
                .imageDownloader(new BaseImageDownloader(mContext, 5 * 1000, 30 * 1000)) //從網路抓取圖片時,timeout相關設定
                .build();
        // Initialize ImageLoader with configuration.
        ImageLoader.getInstance().init(config);

    }

}
詳細設定可以參考這篇文章 大陸人寫的,有更詳細的設定 http://www.eoeandroid.com/thread-318344-1-1.html 另外補充加載圖片時的顯示選項
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public static DisplayImageOptions getImageLoaderOptionsWithLoading() {
        DisplayImageOptions options = new DisplayImageOptions.Builder()
                .showImageOnLoading(R.mipmap.icon_loading) //開始Loading時要呈現的圖片
                .showImageForEmptyUri(R.mipmap.icon_is_empty) //圖片來源是null時要呈現的圖片
                .showImageOnFail(R.mipmap.icon_loading_fail)//load圖失敗時要呈現的圖片
//.displayer(new FadeInBitmapDisplayer(300)) //顯示時加入動畫效果,範例是指0.3秒淡入
                .cacheOnDisc(true) //是否暫存到本機端
                .cacheInMemory(true) //是否暫存到快取記憶體
                .imageScaleType(ImageScaleType.EXACTLY) //圖片呈現方式(會影響效能)
                .bitmapConfig(Bitmap.Config.RGB_565) //圖片品質 (會影響效能)
                .considerExifParams(true) //自動判斷圖片方向,並修正方向有問題的圖片
//                .resetViewBeforeLoading(true)  //是否再載入圖片前,把imageview元件重設(通常是listview在Reuse時會用到)
                .build();

        return options;
    }
以上大概是這樣 寫得很冗長,有問題可以再詢問哦!

2016年4月15日 星期五

線上表格產生器

線上表格產生器:http://www.tablesgenerator.com/

PIVOT Table 統計每月生日人數

SQL:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
SELECT *
FROM (
 SELECT 
 DATEPART(MONTH,[Birthday]) AS [月份],
 count(DATEPART(MONTH,[Birthday])) AS 人數
 FROM [Employees]
 GROUP BY DATEPART(MONTH,[Birthday])
 ) AS Layer1
PIVOT(
 MAX(人數) 
 FOR 月份 
 IN ([01], [02], [03], [04], [05], [06], [07], [08], [09], [10], [11], [12])
) AS PivotTable


執行結果:

01 02 03 04 05 06 07 08 09 10 11 12
11 3 11 8 10 10 9 18 10 11 16 10

2016年3月14日 星期一

EPPlus 自訂擴充功能

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
static class EPPlusExtensions
{
    /// <summary>
    /// 水平 / 垂直 置中
    /// </summary>
    public static void HorizontalVerticalAlignmentCenter(this OfficeOpenXml.Style.ExcelStyle obj)
    {
        obj.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
        obj.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
    }
    /// <summary>
    /// 設定儲存格填滿顏色和格式
    /// </summary>
    public static void SetBackgroundColor(this OfficeOpenXml.Style.ExcelFill obj, System.Drawing.Color color,OfficeOpenXml.Style.ExcelFillStyle excelFillStyle = OfficeOpenXml.Style.ExcelFillStyle.Solid)
    {
        obj.PatternType = excelFillStyle;
        obj.BackgroundColor.SetColor(color);
    }
    /// <summary>
    /// 多列高度設定
    /// </summary>
    public static void Row(this OfficeOpenXml.ExcelWorksheet obj, int StartRow, int EndRow, double Height)
    {
        for (int i = StartRow; i <= EndRow; i++)
        {
            obj.Row(i).Height = Height;
        }
    }
    /// <summary>
    /// 多欄寬度設定
    /// </summary>
    public static void Column(this OfficeOpenXml.ExcelWorksheet obj, int StartCol, int EndCol, double Width)
    {
        for (int i = StartCol; i < EndCol; i++)
        {
            obj.Column(i).Width = Width;
        }
    }
}

取得各年度週數清單

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/// <summary>
/// 取得該年度週數清單,Key:W601, Value:2015/12/27 ~ 2016/01/02
/// </summary>
/// <param name="Year"></param>
/// <returns></returns>
public List<KeyValuePair<string,string>> WeekList(int Year) // 開始時間
{
    DateTime dt1 = new DateTime(Year, 1, 1);
    int week = (int)dt1.DayOfWeek;
    List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
    Calendar cal = DateTimeFormatInfo.CurrentInfo.Calendar;
    dt1 = dt1.AddDays(week * -1);
    int nweek;
    StringBuilder sb = new StringBuilder();
    while (dt1.Year <= Year)
    {
        if (dt1.Year < Year)
        {
            list.Add(new KeyValuePair<string,string>("W" + Year % 10 + "01" , dt1.ToString("yyyy/MM/dd" + " ~ " + dt1.AddDays(6).ToString("yyyy/MM/dd"))));
        }
        else
        {
            nweek = cal.GetWeekOfYear(dt1, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
            list.Add(new KeyValuePair<string,string>("W" + dt1.Year % 10 + nweek.ToString("00") , dt1.ToString("yyyy/MM/dd" + " ~ " + dt1.AddDays(6).ToString("yyyy/MM/dd"))));
        }
        dt1 = dt1.AddDays(7);
    }
    return list;

}