2013年10月24日 星期四

[轉貼] 如何利用C#產生條碼圖片

出處:http://www.dotblogs.com.tw/kyleshen/archive/2013/10/24/125365.aspx

前言

條碼的應用在生活上常常會遇到,其實對於程式來講,他讀出來就是一個字串,所以如果有購買掃描槍的話,等於是一個input裝置,可以把他想成是一個鍵盤,掃成功後等於是個複製貼上的動作,本篇將會Step by Step來實做C#產生條碼圖片。

安裝字型

要做成條碼其實很簡單,網路上有非常多的條碼免費字型可以下載,本篇字型使用的名稱為IDAutomationHC39M,從此連結下載,下載完後,應該會是個字型檔,直接點選安裝即可,這時候我們可以開個Word,會發現只要改變他的字型,就會變成條碼圖片。
b

開始實做

知道條碼其實是組字串後,程式也大概也有個方向可以朝向字串轉圖片的方式去實現。本篇將已WebForm的GridView來快速做個簡單的顯示:
Html頁面,需要注意的是,直接在Img指定寬度和高度並不會減小圖片的檔案大小,實際上在產生時要去做等比例縮放才是比較好的做法
01<asp:GridView ID="gv_data" runat="server" AutoGenerateColumns="False">
02    <Columns>
03        <asp:BoundField DataField="barcode" HeaderText="Barcode字串" />
04        <asp:TemplateField HeaderText="條碼圖片">
05            <ItemTemplate>
06                <img width="200" height="65" src='<%#Eval("Img") %>'  />
07            </ItemTemplate>
08        </asp:TemplateField>
09    </Columns>
10</asp:GridView>

後端在Page Load建立一個DataTable,創造5筆假資料
01//產生五筆資料顯示
02DataTable dt = new DataTable();
03dt.Columns.Add("Barcode");
04dt.Columns.Add("Img");
05 
06for (int i = 0; i < 5; i++)
07{
08    DataRow dr = dt.NewRow();
09    dr["Barcode"] = "BC000000" + i;
10    dr["Img"] = GetBarCodeImage("BC000000" + i);//產生條碼圖片
11    dt.Rows.Add(dr);
12}
13 
14gv_data.DataSource = dt;
15gv_data.DataBind();

GetBarCodeImage function主要在對圖片做一些處理,因為本範例為求方便,最終顯示在HTML上是用Base64的方法實現,實際上可以依照需求去修改此塊。
01public string GetBarCodeImage(string BarcodeStr)
02{
03    //產生圖片檔案
04    string SavePath = @"D:\barcode.png";
05    //Barcode條碼需在前後加上*字號代表開始與結束
06    Bitmap barcode = CreateBarCode("*" + BarcodeStr + "*");
07    barcode.Save(SavePath, ImageFormat.Png);
08    barcode.Dispose();
09 
10    //將圖片檔案轉成Base64字串
11    using (var fs = new FileStream(SavePath, FileMode.Open, FileAccess.Read))
12    {
13        var buffer = new byte[fs.Length];
14        fs.Read(buffer, 0, (int)fs.Length);
15        string base64String = Convert.ToBase64String(buffer);
16        string ImgBase64 = string.Format("data:image/png;base64,{0}'", base64String);
17        return ImgBase64;
18    }
19}

將字串轉為圖片:
01/// <summary>
02/// 將字串轉為Barcode圖片
03/// </summary>
04/// <param name="data"></param>
05/// <returns></returns>
06public Bitmap CreateBarCode(string data)
07{
08    Bitmap barcode = new Bitmap(1, 1);
09    Font threeOfNine = new Font("IDAutomationHC39M", 60,
10                            System.Drawing.FontStyle.Regular,
11                            System.Drawing.GraphicsUnit.Point);
12 
13    Graphics graphics = Graphics.FromImage(barcode);
14 
15    SizeF dataSize = graphics.MeasureString(data, threeOfNine);
16 
17    barcode = new Bitmap(barcode, dataSize.ToSize());
18    graphics = Graphics.FromImage(barcode);
19    graphics.Clear(Color.White);
20 
21    graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;
22 
23    graphics.DrawString(data, threeOfNine, new SolidBrush(Color.Black), 0, 0);
24 
25    graphics.Flush();
26    threeOfNine.Dispose();
27    graphics.Dispose();
28 
29    return barcode;
30 
31}

最終結果
image

其他應用

學會字串轉圖片,就可以去網路上找很多免費字型,例如這個網站,來產生一些特殊圖案!

Reference

2013年10月9日 星期三

[轉貼] JqGrid—功能強大的jQuery Grid Control

出處:http://www.cc.ntu.edu.tw/chinese/epaper/0021/20120620_2109.html

作者: 唐瑤瑤 / 臺灣大學計資中心程式設計師

jqGrid 是目前極受歡迎的jQuery表格套件(Grid Control),其免費的版本完全在使用者瀏覽器端執行,與伺服器端使用何種語言開發無關,只要會開發CSS 及jQuery即可,所以無論是PHP、Java Servlets、JSP、ColdFusion、Perl.或ASP.NET的網頁應用程式都可以採用這個套件。
jqGrid 是目前極受歡迎的jQuery表格套件(Grid Control),其免費的版本完全在使用者瀏覽器端執行,與伺服器端使用何種語言開發無關,只要會開發CSS 及jQuery即可,所以無論是PHP、Java Servlets、JSP、ColdFusion、Perl.或ASP.NET的網頁應用程式都可以採用這個套件。以筆者開發的校內行政E化系統來說,訪客中心導覽系統(PHP)及導生綜合資料系統(ASP .NET)等,都是採用jQuery + jqGrid 的範例。
JqGrid 的特色有哪些?
  • AJAX-enabled:AJAX應用可以僅向伺服器非同步的發送並取回少量的數據,使得動態網頁頁面的產生可以十分的快速。它使用SOAP或其它一些基於XML的頁面服務介面,並在客戶端採用JavaScript處理來自伺服器的回應。因為在伺服器和瀏覽器之間交換的數據大量減少(大約只有原來的5%),我們就能看到伺服器回應得更快。同時很多的處理工作可以在發出請求的客戶端機器上完成,所以Web伺服器的處理時間也減少了。此外,AJAX所採用的技術皆為internet 標準,程式師不須擔心瀏覽器不相容之問題。有關AJAX 的介紹,請參考w3schools 網站http://www.w3schools.com/ajax/ajax_intro.asp
  • 完整的表格呈現與運算功能,包含換頁、欄位排序、grouping、新增、修改及刪除資料等功能。如下圖所示
2.1 客製化的工具列。
2.2 預設的Navigator 工具列,可以很容易的使用新增、刪除、編輯、檢視及搜尋等功能。
2.3 完整的分頁功能。
2.4 按下任一欄位的標頭,皆可以該欄位為排序項目。無論是升冪或降冪皆可。
2.5 預設的action formatter,可以快速而直覺地對每筆資料做運算。
2.6 除了jqGrid lib 所提供之formatter(包括email,link,select,checkbox,date 等) 外,開發者可以從資料來源自訂資料顯現方式,即所謂之custom formatter。
  • 採用CSS為佈景,搭配jQuery UI,程式設計師不再需要花精神於頁面設計。之前開發程式仍須仰賴美術設計師做畫面修改及圖示設計,往往一來一回就花費了許多時間。 UI CSS Framework 提供我們預設的版型、色系、圖示等可以直接套用,甚至隨時更換。又或者可以直接將預設的版型作客製化,十分方便。有關jQueryUI Theme的說明,請參考http://jqueryui.com/themeroller/
  • 跨瀏覽器:目前測試支援的瀏覽器有 IE 8.0+, FireFox 2.0+, Safari 3.0+, Opera 9.2+ 及Google Chrome。
  • 支援多種預設或自訂的資料格式。
  • 支援多種編輯功能,包括Inline editing、Form editing 及Cell editing。下圖為Form Editing 模式,使用者選擇新增或編輯資料時,程式會跳出一個對話框供使用者編輯,並聚焦於該表格。
下圖為Inline Editing 模式,使用者可直接於Grid表格上編輯,是一種更為直覺的使用方式。
  • 篩選與搜尋:於Navigator 工具列上提供任意欄位之篩選握搜尋功能,對資料量龐大的表格來說十分方便好用。
  • 容易自學:jqGrid 的學習門檻主要在jQuery+CSS 的使用,若已經熟習上述技術的開發者應該沒有入門的問題。也由於jqGrid 十分受歡迎,因此使用Google搜尋幾乎可以找到所有的使用及解決方案。當然,原提供者網站內容十分完整,包含Method、API、Event 及option說明文件及範例。
範例: 
接著我們用一個簡單的程式來說明jqGrid 的使用。
Step1:下載jqGrid插件,建議所有的元件都一次下載。下載網址http://www.trirand.com/blog/?page_id=6
Step 2:於HTML檔案中須將必要之css及js 檔案引用進來
<link rel="stylesheet" type="text/css" ref=" jquery-ui-1.8.13.custom.css"/>
<link rel="stylesheet" type="text/css" href="ui.jqgrid.css" />
<script src="jquery-1.7.1.min.js" type="text/javascript"></script>
<script src="grid.locale-zh.js" type="text/javascript"></script>
<script src="jquery.jqGrid.min.js" type="text/javascript"></script>
Step 3:HTML grid 程式碼
<table id="list"></table>
<div id="list_pager"></div> 
Step 4:java script 程式碼
伺服器端經由getdata.php產生XML 內容交給jqGrid 顯示
$("#list").jqGrid({
url:'getdata.php?act=initial',
datatype: 'xml',
mtype: 'GET',
Step 5:java script 程式碼
建立欄位名稱及屬性
colNames:['ID Number','Last Sales','Name', 'Stock', 'Ship via','Notes'],
colModel:[
{name:'id',index:'id', width:90, sorttype:"int", editable: true, xmlmap: "id" },
{name:'sdate',index:'sdate',width:90, editable:true, sorttype:"date", xmlmap: "sdate" },
{name:'name',index:'name', width:150,editable: true, editoptions:{size:"20",maxlength:"30"}, xmlmap: "name" },
{name:'stock',index:'stock',width:60,editable:true,edittype:"checkbox",editoptions:{value:"Yes:No"}, xmlmap: "stock" },
{name:'ship',index:'ship',width:90,editable:true,edittype:"select",editoptions:{value:"FE:FedEx;IN:InTime;TN:TNT;AR:ARAMEX"}, xmlmap: "ship" },
{name:'note',index:'note',width:200,sortable:false,editable:true,edittype:"textarea",editoptions:{rows:"2",cols:"10"}, xmlmap: "note"}],
Step 6:java script 程式碼
建立grid屬性,editurl 是指資料新增、編輯及刪除時的伺服器端程式
pager: '#list_pager',
autowidth:true,
height:'100%',
rownumbers: true,
rownumWidth:30,
toolbar: [true, "top"],
toppager: true,    
pgbuttons: true,
pginput: true,
rowNum: 15,
rowList: [10, 15, 20, 25, 30, 50, 100],
rowNum:15, 
viewrecords: true,
loadonce:true,
gridview: true,
editurl : 'setdata.php?q=dummy',
caption: '導覽員列表'
Step 7:java script 程式碼
事件處理函示
loadComplete: function () {
},
gridComplete: function () {
},
onSelectRow:function (id) {
}
})
Step 8:java script 程式碼
建立Navigator pager

$("#list").jqGrid('navGrid','#list_pager',{
cloneToTop: true, edit:false, add:true, del:false, view:true, addtext: "新增資料", addtitle: "新增資料",viewtext: "檢視資料", viewtitle: "檢視資料",searchtext: "搜尋...", searchtitle: "搜尋...", refreshtext: "更新", refreshtitle: "更新"},
{}, /*default settings for edit*/
{
url:'setdata.php?act=add',
closeAfterAdd:true,
closeOnEscape:true,
afterComplete: function (response, postdata, formid) {
if ($("#list").getGridParam("datatype") === "local") {
$("#list").setGridParam({ datatype: 'xml' });
}
$("#list").trigger("reloadGrid");},
beforeShowForm: function (form) {
}
}, /*default settings for add*/
{},  /*default settings for delete*/
{multipleSearch:true,closeOnEscape:true,closeAfterSearch:true,multipleGroup:true, showQuery: true},
/*default settings for search*/
{
closeOnEscape:true,
viewPagerButtons:false,
beforeShowForm: function (form) {
$('#viewmodlist').css('width', '450px');}
} /*default settings for view*/
);
參考資料:

[轉貼] 談談 Cookie 特性

出處:http://www.dotblogs.com.tw/jasonyah/archive/2013/10/06/explain-http-cookie-in-detail.aspx

前言
身為 Web 開發人員,不管你今天是寫 PHP、ASP.NET … 等,一定都有聽過 Cookie,正所謂「工欲善其事,必先利其器」,而常見的 Cookie 會用來記錄使用者的登入資訊,但又有多少人是真正了解 Cookie 的特性呢,我想每個網頁開發人員應該都要確切了解 Cookie 的特性,以免哪天寫的程式碼有了漏洞讓駭客成功竊取到相關資訊,或是存了太多 Cookie 在同一個頁面而拖慢了網站的速度,今天舊讓我們來談談 Cookie 吧!
概觀
簡單來說 Cookie 是將網站所需使用的資訊存放在 Client 端的瀏覽器上,而在每次瀏覽器和 Web 伺服器在進行資料交換時,同時也會將相關的 Cookie 傳到 Web 伺服器上,簡單來說 Cookie 的運作過程大致如下:
  1. Client 端向 Web Server 要求某個網頁,同時也會將符合的 Cookie 資訊傳送到 Server 端
  2. 當 Client 端取得 Server 端返回的網頁時,瀏覽器會將返回回來的 Cookie 資料記錄到電腦的資料夾中

利用開發工具可以看到每次瀏覽器請求網頁時,會一併將 Cookie 的資訊傳送到 Server 端
1
當 Server 端將網頁回傳給瀏覽器時,透過 Set-Cookie 這個 Header 來告訴 Client 端需要在瀏覽器中加入一或多個 Cookie,並且記錄該 Cookie 的隸屬網域(Domain)、存放目錄(Path)、過期時間(Expires) 等資訊。
2
假設 Brower 取得某網頁,且包含了 5 個 CSS 、2 個 Javascript 檔案,在這一次的 Request 中就會將同樣的 Cookie 送出 7 次,可想而知 Cookie 絕對不是越多越好,而是需要小心地使用它,另外也因為 Cookie 是儲存在 Client 端,我們就可以透過 Javascript 或是第三方軟體來取得或修改網頁裡的 Cookie,若你的 Cookie 中包含了帳號密碼等敏感性資訊,這樣一來駭客就可以輕而易舉的冒用他人的 Cookie 來登入你的網站,所以在開發 Web 系統時,針對 Cookie 部分也需要特別注意。
Cookie 限制
雖然 Cookie 是儲存在 Client 端中,但不代表就像儲存檔案一樣可以肆無忌憚的儲存,基於 RFC2965 的規範,定義了瀏覽器對於 Cookie 的最低儲存量,而因為每家瀏覽器的限制不同,但至少都須符合 RFC 規範,大致的定義為:
  1. 每個 Cookie 所能存放的大小為 4096 Bytes
  2. 每個網域至少可以儲存 20 個 Cookies,若儲存超過限制大小瀏覽器會捨棄最舊的 Cookie。
  3. 至少能儲存 300 個 Cookies
Cookie 屬性介紹
  1. Expires – 設定 Cookie 的有效日期,若沒有設定預設 Cookie 會保存到瀏覽器關閉為止
       1: Response.Cookies["UserName"].Expires = DateTime.Now.AddDays(1);
  2. Secure - 設定 Cookie 僅在使用 HTTPS 時才會送出去 
       1: Response.Cookies["UserName"].Secure = true; // 是否是 Https 狀態下才能發送
  3. Path - 限制該 Cookie 只能由某個資料夾或應用程式存取 
       1: Response.Cookies["UserName"].Path = "/Web1";

    舉例來說點部落的網址為 www.dotblogs.com.tw ,若我們將 Path 屬性設定為 "/Web1" ,代表只有在www.dotblogs.com.tw/Web1 這個網站底下的網頁才能使用該 Cookie,若沒有設定預設為 "/" 根目錄,代表該網域底下的所有網站都能取得該 Cookie
     
  4. Domain - 限制 Cookie 的網域範圍 
       1: //直接指定網站的網域名稱,若沒有額外設定則該 Cookie 僅能被當前的網域所存取
       2: Response.Cookies["UserName"].Domain = "www.dotblogs.com";
       3:  
       4: // *.dotblogs.com 網域的所有網站都能接收此 Cookie
       5: Response.Cookies["LoginTime"].Domain = "dotblogs.com";
    PS:一般常見的 SSO (Single Sign-On) 機制,也會利用設定網域的方式來讓不同子網域的網站也能存取到同一個 Cookie 設定,以達到跨網域登入。
    PS:不能設定跟自己不一樣的網域,Ex: www.dotblogs.com.tw 的網站在設定 Cookie 時就不能指定 facebook.com 的 Cookie。

     
  5. HttpOnly - 設定 Cookie 是否能由 Javascipt 所存取,預設為 false 能被 Javascript 所存取 
       1: //設定為 true 代表該 Cookie 不能被 Javascript 存取
       2: Response.Cookies["UserInfo"].HttpOnly = true;

    依前面所講的 Cookie 能被 Browser 的 Javascript 所取得,也讓駭客又多了一種方法來取得網站 Cookie 的資料,若網站的 Cookie 不需要被 Browser 端的 Javascript 使用,建議將 HttpOnly 的屬性設為 true
利用 ASP.NET 來操作 Cookie
  1. 新增 Cookie ,並設定值 
       1: HttpCookie MyCookie = new HttpCookie("UserInfo"); //新增 Cookie 名稱為 UserInfo
       2: MyCookie.Value = "JasonYah"; //設定 Cookie 的值
       3: Response.Cookies.Add(MyCookie);
  2. 取得從 Browser 送過來的 Cookie 
       1: if (Request.Cookies["UserInfo"] != null)
       2: {
       3:     var UserName = Request.Cookies["UserInfo"].Value;
       4: }
  3. 更新 Cookie 的到期時間 
       1: if (Request.Cookies["UserInfo"] != null)
       2: {
       3:     Request.Cookies["UserInfo"].Expires = DateTime.Now.AddHours(1);
       4: }
  4. 刪除 Browser 端的 Cookie 
       1: //將 Cookie 的到期時間設定為昨天,就可成功刪除
       2: Request.Cookies["UserInfo"].Expires = DateTime.Now.AddDays(-1);
       3: //或是利用 Remove 的方法來移除該 Cookie
       4: Request.Cookies.Remove("UserInfo");
  5. 建立一個含有多個值的 Cookie 
       1: HttpCookie MyCookie = new HttpCookie("UserInfo");
       2: MyCookie.Values["Name"] = "JasonYah";
       3: MyCookie.Values["Language"] = "zh-Tw";
       4: Response.Cookies.Add(MyCookie);
    前面有說到因為 Cookie 有限制數量及大小,一個網站最少能存放 20 個 Cookie,所以我們可以利用在單一 Cookie 中儲存多個 key/value 的方式來將相同性質的資訊存放在同一個 Cookie 當中。
總結
剛好前陣子有碰到,趁機會記錄起來,也希望能讓不理解 Cookie 的開發人員有一番認識,Cookie 在使用上也別記錄一些敏感性資訊,比如帳號密碼...等,就算真的記錄了也記得先經過加密,額外若 Cookie 是不會被 Javascript 給存取也記得加上 HttpOnly 的屬性,來增加你的網站安全。

參考連結

2013年10月4日 星期五

[轉貼] 透過檔案連結的方式達成多個專案整合以及程式碼共用 (使用Project Linker)

出處:http://www.thinkpower.com.tw/xamarin/Article_01.aspx?idx=01

程式碼共享:在設計時,將與平台無關的商業邏輯、服務存取、資料存取以及資料層從介面抽離出來,如下圖所示:
底下說明如何才能達成上述的專案整合以及程式碼共用,首先來看看架構示意圖:
從上述的示意圖,我們可以看到,左半邊是可以抽離出來的共用程式碼,這部份將獨立成一個專案,並只加入常用的組件(如Base Class Library),若有部份程式碼使用到與平台相關的組件或技術,可以在程式碼中加入條件式編譯的指示詞,供各平台直接使用,不需要進行修改。
而在各平台的專案中,可以透過檔案連結的方式,將共用程式碼的部份連結到各平台專案。但由於目前Visual Studio並沒有提供可以同時設定多個檔案或整個資料夾連結的方式,因此若每個檔案都要手動連結,其實是較不實際的。而且日後共用程式碼專案若有檔案的異動,如新增或刪除。各平台專案並不會同步更新。此時我們可以透過1個叫做”Project Linker 2012”的擴充功能進行協助(它也有對應Visual Studio 2010的版本).
安裝好Project Linker後,我們便可以在各平台專案點擊滑鼠右鍵=>Add project link
接著選擇來源專案,之後便會為來源專案的每個資料夾及檔案進行連結.
連結的檔案在Visual Studio中都會有個藍色箭頭的圖示
透過上述的設定後,便可以在各平台專案共用程式碼。在開發平台專案時,只要針對使用者介面以及針對控制項的操作撰寫程式即可。對於商業邏輯,資料存取的部份則可以在各平台共用

[轉貼] 快速產生具複雜樣式的 Office Open XML 程式碼

出處:http://www.dotblogs.com.tw/regionbbs/archive/2010/04/30/office.openxml.templated.document.productivity.tool.aspx

在前一篇說明 Open XML 不依賴 Office 即產生樣板與資料庫的資料整合的文章中有一段落落長的程式碼,那一段你覺得我花多久時間呢?一小時?半天?一天?都不是,只要一分鐘。
“啥米?”不用懷疑,真的只要一分鐘,這一分鐘我只要做建立樣板文件和使用工具來產生即可。這個工具就是 Office Open XML SDK 中提供的 Office Open XML SDK 2.0 Productivity Tool:
image

這個工具可以在 Microsoft Downloads 使用 Open XML SDK 2.0 為關鍵字找到,它大小是 106MB 左右,它可以讀取 Office 2007-2010 文件的內容,並且自動產生可產生符合格式的 C# 程式碼 (沒看到 VB 的程式碼的產生位置 …),當你的文件很複雜時,這個工具可以很快的幫你解決程式碼的問題,當然產生出來的程式可能還需要修改,但最起碼這麼大量的程式只要修小小幾個地方,光是時間成本就不知可以省多少了。
另外,這個工具還可以驗證 Office 文件的 Open XML 內容的完整性 (工具列上的 Validate 按鈕):
image

你也可以設定讓它檢查哪種格式的 XML schema:
image

有了這個工具,遇到複雜格式的 Office 文件樣板化,再也不用傷腦筋寫程式碼,交給它代勞即可囉。