2022年7月26日 星期二

V120502 - [列印包裝貼紙]鈕 - 1>下載 SS_FILES樣板檔, 2>填寫欄位值, 3>將該檔案傳送至前端

目的: 將資料內容印至標籤印表機

處理說明 : 1>Browser前端無法取得本機的印表機清單, 也無法設定本機印表機的頁面長寬

                   2>將資料寫入 xls檔案, 傳送至本機前端, 由使用者自行選擇標籤印表機後,列印

                       --> 如何將前端store的 3筆資料,送至後端去處理,將這3筆資料填入樣板檔

                   3>將檔案寫入 pdf檔案網頁 , 由使用者按右鍵列印, 仍要選擇印表機





一.自訂 class , 將store 資料變成 JSON字串, 再由 JSON字串轉成 Object,
      -JSON Serialize  & DeSerialize
1>js 將 store 的資料轉成  JSON String  - *.js  
   var Tmp_data_JSON = "";  //將store資料轉成 JSON 的字串
        var Tmp_sub_np = {};
        let Tmp_DataAry = [];
        var Tmp_Str="";
        for (i = 0; i < Tmp_sub_store.getCount(); i++) {
            cur_rec = Tmp_sub_store.getAt(i);
            Tmp_Str = "第" + i.toString() + "筆";
            console.log(Tmp_Str+"cur_rec:", cur_rec);
            Tmp_SAPNO = cur_rec.data['SAPNO'];
            Tmp_PN = cur_rec.data['PN'];
            Tmp_QTY = cur_rec.data['QTY'];
            Tmp_EOCND = cur_rec.data['EOCND'];
            Tmp_RMK = cur_rec.data['RMK'];  
            Tmp_sub_np = {
                SAPNO: Tmp_SAPNO,
                PN: Tmp_PN,
                QTY: Tmp_QTY,
                EOCND: Tmp_EOCND,
                RMK: Tmp_RMK,
            }
            console.log(Tmp_Str + "Tmp_sub_np:", Tmp_sub_np);
            Tmp_DataAry.push(Tmp_sub_np);
        }
        console.log("Tmp_DataAry:", Tmp_DataAry);
        let Tmp_DataString = JSON.stringify(Tmp_DataAry);
        console.log("Tmp_DataString:", Tmp_DataString);

        var np = {};
        np = {
            DataString: Tmp_DataString  //Tmp_DataString:  將目前子畫面的資料轉成 JSON字串
        };        

        Ext.getCmp('mySubForm').submit({
            //Ext.Ajax.request({
            url: '../../api/V120502API/DoPRNLIST',
            method: 'POST',
            async: false,
            standardSubmit: true, // 非 Ajax 的方式  //若要傳送檔案至前端, standardSubmit必需設為 true  
            params: np,
        });


2>c# - 將 np 參數的  JSON 字串, 轉 Object 
       public class DataCls
        {
            public string SAPNO { get; set; }         //SAP工號
            public string PN { get; set; }             //件號
            public int  QTY { get; set; }          //數量
            public string EOCND { get; set; }             //EO+CND
            public string RMK { get; set; }             //備註
        }

   [HttpPost]
        public void DoPRNLIST()
        {
            var c = HttpContext.Current;
            NameValueCollection nvc = c.Request.Form;
            // 1>將 SS_FILES.FBOLD 存成 Local檔案
            //取得目前子畫面的欄位值
            string Tmp_DataString = nvc["DataString"];    
List<DataCls> DataObjList = (List<DataCls>) JsonConvert.DeserializeObject(Tmp_DataString, (typeof(List<DataCls>)));

            string Tmp_SAPNO, Tmp_PN, Tmp_EOCND, Tmp_RMK;
            int Tmp_QTY;
            DataCls DataObj;
            for (var i=0;i<DataObjList.Count;i++)
            {
                DataObj = DataObjList[i];
                Tmp_SAPNO=DataObj.SAPNO;
                Tmp_PN = DataObj.PN;
                Tmp_EOCND= DataObj.EOCND;
                Tmp_RMK = DataObj.RMK;
            }



二.利用現有Table class,將 Table 資料(Object)轉成 JSON字串, 再將 JSON字串轉成 Table(Object)
1>js , 將Object資料(Table)轉成   JSON String , 當參數傳至後端
        let Tmp_DataAry1 = [];
        var Tmp_Str="";
        for (i = 0; i < Tmp_sub_store.getCount(); i++) {
            cur_rec = Tmp_sub_store.getAt(i);
            console.log(Tmp_Str + "cur_rec:", cur_rec);
            Tmp_DataAry1.push(cur_rec.data);
       }
        let Tmp_DataString1 = JSON.stringify(Tmp_DataAry1);
        var np = {};
        np = {
        DataString1: Tmp_DataString1  //Tmp_DataString:  將目前子畫面的資料(Table)轉成 JSON字串
        };        

        Ext.getCmp('mySubForm').submit({
            //Ext.Ajax.request({
            url: '../../api/V120502API/DoPRNLIST',
            method: 'POST',
            async: false,
     standardSubmit: true, // 非 Ajax 的方式  //若要傳送檔案至前端, standardSubmit必需設為 true 
            params: np,
        });



2>cs , 將參數(JSON String)轉成 Table(Object) , 讀取 Object 屬性值
//加入JSON格式轉換參考  , JsonConvert.DeserialObject(,)
using Newtonsoft.Json; 


public void DoPRNLIST()
        {
            var c = HttpContext.Current;
            NameValueCollection nvc = c.Request.Form;
            //取得目前子畫面的欄位值
string Tmp_DataString1 = nvc["DataString1"];//Tmp_DataString:  將目前子畫面的資料. JSON字串  DataTable DataTable1=(DataTable)JsonConvert.DeserializeObject(Tmp_DataString1, (typeof(DataTable)));

 string Tmp_SAPNO, Tmp_PN, Tmp_EOCND, Tmp_RMK;
            int Tmp_QTY;
            for (var i=0; i<DataTable1.Rows.Count;i++)
            {
                Tmp_SAPNO = DataTable1.Rows[i]["SAPNO"].ToString();
                Tmp_PN = DataTable1.Rows[i]["PN"].ToString();
                Tmp_QTY = int.Parse(DataTable1.Rows[i]["QTY"].ToString());
                Tmp_EOCND = DataTable1.Rows[i]["EOCND"].ToString();
                Tmp_RMK = DataTable1.Rows[i]["RMK"].ToString();
            }




2022年7月21日 星期四

C# 利用 iTextSharp 產生 PDF檔案

使用ASP .NET (C#) 產生PDF檔的好幫手—iTextSharp library (上)

 https://www.cc.ntu.edu.tw/chinese/epaper/0015/20101220_1509.htm

Question: Web程式 – 如何執行[標籤]的印表機列印 - 產生PDF檔的好幫手—iTextSharp

 

目的: 如何在 Web程式,如何執行[標籤]的印表機列印

說明:  1> 目前 Web程式(Browser端) 無法取得 本機印表機清單
           2>   是否可先產生 XLS檔案下載至前端, 再由使用者自行列印

目前問題: 1>網頁安全的條件下已不允許伺服器後端的程式去控制前端印表機,
                    連下載檔案以關聯方式啟動程式的方式都不被允許,
                    除非你能找到夠舊的IE透過ACTIVEX來做這些事,但....應該會被罵吧


處理說明:
    1>標籤大小: 100mm*60mm
        邊界: 上右下左  : 1.5mm*1.5mm*1.5mm*1.5mm 
    2>試著產生 xls 檔,並由使用者開啟 xls 後, 自行列印    


2022年7月20日 星期三

JSON.Parse 和 Ext.decode 的差異說明

 目的: 說明字串2Object 函式  ,  JSON.Parse   和   Ext.decode的差異

說明: 

          1>若為標準的JSON字串(含字串引號) , JSON.Parse Ext.decode均可正常解碼成 Object
               Ex: var Tmp_ObjAryStr = "{ "Key": "ABC" }";  //實際字串:  "{ \"Key\": \"ABC\" }"
          

         2>若為非標準的JSON字串(不含字串引號) , 
                         則Ext.decode可正常解碼成 Object 
                        JSON.Parse無法正常解碼成 Object 
              Ex: var Tmp_ObjAryStr2 = "{Key:  'ABC' }";  



c# 主機傳回 string vs. Http.StringContent vs. HttpResponseMessage 的差異說明 - Ext.Ajax.reuqest(

目的: 1>說明主機端傳回 string vs Http.StringContent vs  HttpResponseMessage 的不同(主機端)

         2>說明主機端傳回 string  vs Http.StringContent vs HttpResponseMessage , 在前端接收的結果

摘要:  

         1>string : 單純的資料型態 , 傳回至前端會含 字串引號("  ")
         2>StringContent 為 Object 含Header,content  , 真正的內容存在 content(以 byte 方式儲存)
         3>HttpStringMessage: 傳回至前端, response.responseText 不會含字串引號


1> *.cs  c# 主機端 *Controller:  

    1>>String Tmp_RtnStr;   //一般的字串



   2>>StringContent Tmp_StringContent  ;    // HTTP  的字串內容, 含 Header 
1) HTTP  的字串內容, 含 Header (說明 charset) , 
2) 真正的內容存在 [content] 屬性


2> *.js  JavaScript 前端 , 接收主機端(String及 Http.StringContent)的傳回結果

Case1: 接收主機傳回 string
     1>>string : 主機端傳回 string
         *.cs
        [HttpPost]        
        public String get_PRNLIST()
        {
                   String Tmp_RtnStr;         
                  Tmp_RtnStr = "{Key:" + myfunc.AA("ABC") + "}";
                 return Tmp_RtnStr
        }
     
   2>>前端接收 [主機端傳回 string]:




var np = {};
        np["CLS"] = Tmp_CLS;
        np["DITM"] = Tmp_DITM;
        var isOk = true;
Ext.Ajax.request({
            method: "POST",
            url: '../../api/V120103API/CHECK_CLS_DITM',
            params: np,
            async: false,
            success: function (response, opts) {
                console.log("0 response.responseText=", response.responseText);
                var Tmp_Obj = Ext.decode(response.responseText);
                console.log("1  Tmp_Obj=", Tmp_Obj);
                if (Tmp_Obj["success"] == false) {
                    var Tmp_Rtn_Msg = "類別(" + Tmp_CLS + ")排序項次(" + Tmp_DITM + ")已存在拆挪管制標準檔(AMM_FRO3F16STD)<br>"
                        + "請檢核<br>"
                        + Tmp_Obj["Rtn_Msg"];
                    mywarnalert(Tmp_Rtn_Msg);
                    isOk = false;
                }
            },  //end of success                
            failure: function (response, opts) {
                var Tmp_Obj = Ext.decode(response.responseText);
                var Tmp_Rtn_Msg = "類別(" + Tmp_CLS + ")排序項次(" + Tmp_DITM + ")已存在拆挪管制標準檔(AMM_FRO3F16STD)<br>"
                    + "請檢核<br>"
                    + Tmp_Obj["Rtn_Msg"];
                mywarnalert(Tmp_Rtn_Msg);
                isOk = false;
            }
        })  //end of Ext.Ajax.Request
        return isOk;
    } // end of CheckFormValue





Case2: 接收主機傳回 StringContent

    1>>string : 主機端傳回 StringContent         *.cs
        [HttpPost]        
        public StringContent get_PRNLIST()
        {
                   String Tmp_RtnStr;         
                  Tmp_RtnStr = "{Key:" + myfunc.AA("ABC") + "}";

                  StringContent Tmp_StringContent;
                 Tmp_StringContent = new StringContent(Tmp_RtnStr);
                 return Tmp_StringContent;              
        }

  2>>前端接收 [主機端傳回 StringContent]:   *.js

       console.log("0 response=", response);     
       var Tmp_ObjAryStr1 = response.responseText;
       console.log("1  response.responseText=", response.responseText);            
       var Tmp_Obj_decode1 = Ext.decode(response.responseText);
       console.log("1  Ext.decode(response.responseText)=", Tmp_Obj_decode1);            
       var Tmp_Obj_decode1_1 = Ext.decode(Tmp_Obj_decode1);
       console.log("1  Ext.decode_2(response.responseText)=", Tmp_Obj_decode1_1);            


Case3: 接收主機傳回 HttpResponseMessage

1>>HttpResponseMessage: 主機端傳回 HttpResponseMessage  
        public HttpResponseMessage get_PRNLIST()
      {
            Tmp_RtnStr = "{Key:" + myfunc.AA("ABC") + "}";
            var response = this.Request.CreateResponse();
            response.Content = new StringContent(Tmp_RtnStr);    // 回應內容
            return response;
         }



 console.log("1  response.responseText=", response.responseText);            
            var Tmp_Obj_decode1 = Ext.decode(response.responseText);
            console.log("1  Ext.decode(response.responseText)=", Tmp_Obj_decode1);            
            var Tmp_Obj_decode1_1 = Ext.decode(Tmp_Obj_decode1);
            console.log("1  Ext.decode_2(response.responseText)=", Tmp_Obj_decode1_1);   



V120502 - 加入本機印表機選項 (非主機端的印表機)

 


1>ComboBox 加入本地印表機選項 :
     *.js

{  //挑選印表機
xtype: "fieldcontainer", fieldLabel: "印表機", labelWidth: 60, layout: "hbox", flex: 15,
items: [
{
xtype: "combobox", id: "sub_PRINTER", name: "sub_PRINTER", width:250, padding: "0 4 0 0",
store: store_PRNLIST,
emptyText: "--請選擇--", displayField: "Name", valueField: "Value"
queryMode: "local"                                                  
},
]
},  // end of 挑選印表機

var np = {};
    Ext.Ajax.request({
        method: "POST",
        url: '../../api/V120502API/Get_PRNLIST',
        params: np,
        async: false,
        success: function (response, opts) {            
            console.log("0 response=", response);
            console.log("0 response.responseText=", response.responseText);            
            var Tmp_Obj = Ext.decode(response.responseText);
            //Ext.decode Array of Object  也可解碼 ,  Tmp_Obj : Array [{},{},..]
            var Tmp_Name, Tmp_Value;
            var cur_rec = {};
            for (i = 0; i <Tmp_Obj.length; i++)
    {        
                Tmp_Name = Tmp_Obj[i]["Key"];
                Tmp_Value = Tmp_Obj[i]["Value"];
                cur_rec = { Name: Tmp_Name, Value: Tmp_Value };
                //cur_rec = { Name: Tmp_Obj[i]["Key"], Value: Tmp_Obj[i]["Value"] };
                console.log("6  cur_rec= ", cur_rec);
                store_PRNLIST.add(cur_rec);                        
    }

//不可再  store_PRNLIST.load();  --> 會載入原始的 data , 後來新增item, 不會顯示


2>*.cs  c# 呼叫 get_PRNLIST() 取得 主機端的 印表機選項
 [HttpPost]
public HttpResponseMessage get_PRNLIST()
{
           String Tmp_PRNNM;
            String Tmp_RtnStr = "";
            for (int i = 0; i < PrinterSettings.InstalledPrinters.Count; i++)
            {
                Tmp_PRNNM = PrinterSettings.InstalledPrinters[i];
                PRNLIST.Add(Tmp_PRNNM, i.ToString());
                Tmp_RtnStr = Tmp_RtnStr
                                     + "{Key:" + myfunc.AA(Tmp_PRNNM) + ",Value:" + i.ToString() + "},";
             }        
             if (Tmp_RtnStr.Length > 0)
            {
                Tmp_RtnStr=Tmp_RtnStr.Substring(0, Tmp_RtnStr.Length-1);
                Tmp_RtnStr = "[" + Tmp_RtnStr + "]";
                    };    
            var response = this.Request.CreateResponse();
            response.Content = new StringContent(Tmp_RtnStr);    // 回應內容
            return response;        
}






2022年7月19日 星期二

store , json , 主機取得資料 以 JSON 格式傳回前端

 var store1 = Ext.create('Ext.data.Store', {

        id: 'store1',

        pageSize: 10,

        fields: par_Fields,

        autoLoad: true,

        proxy: {

            type: 'ajax',

            url: '../api/myAPI/SQLOPEN',

            extraParams: np,

            getMethod: function () { return 'POST'; },            

            async: false,

            reader: {                      // reader: The Ext.data.reader.Reader to use to decode the server's response or data read from client. 

                type: 'json',            //The JSON Reader is used by a Proxy to read a server response that is sent back in JSON format

  root: 'T1',              //The name of the property which contains the data items corresponding to the Model(s) for which this Reader is configured. For JSON reader it's a property name (or a dot-separated list of property names if the root is nested).

               totalProperty: 'T1C[0].TOTAL'   //Name of the property from which to retrieve the total number of records in the dataset.

//T1C必需有 TOTAL 欄位   

            }

            }

        }

    })