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 欄位   

            }

            }

        }

    })

   

JSON 的完整語法 - JSON函式 - store2JSON

一.JSON stands for JavaScript Object Notation

JSON 的完整語法如下:

JSON = null

    or true or false
    or JSONNumber
    or JSONString
    or JSONObject
    or JSONArray

JSONNumber = - PositiveNumber
          or PositiveNumber
PositiveNumber = DecimalNumber
              or DecimalNumber . Digits
              or DecimalNumber . Digits ExponentPart
              or DecimalNumber ExponentPart
DecimalNumber = 0
             or OneToNine Digits
ExponentPart = e Exponent
            or E Exponent
Exponent = Digits
        or + Digits
        or - Digits
Digits = Digit
      or Digits Digit
Digit = 0 through 9
OneToNine = 1 through 9

JSONString = ""
          or " StringCharacters "
StringCharacters = StringCharacter
                or StringCharacters StringCharacter
StringCharacter = any character
                  except " or \ or U+0000 through U+001F
               or EscapeSequence
EscapeSequence = \" or \/ or \\ or \b or \f or \n or \r or \t
              or \u HexDigit HexDigit HexDigit HexDigit
HexDigit = 0 through 9
        or A through F
        or a through f

JSONObject = { }
          or { Members }
Members = JSONString : JSON
       or Members , JSONString : JSON

JSONArray = [ ]
         or [ ArrayElements ]
ArrayElements = JSON
             or ArrayElements , JSON
二.JSON函式用法
A common use of JSON is to exchange data to/from a web server.
When sending data to a web server, the data has to be a string.
Convert a JavaScript object into a string with JSON.stringify()

Ex:1
const obj = {name: "John", age: 30, city: "New York"};
const myJSON = JSON.stringify(obj)

Ex2: 畫面的 store 轉成 JSON String
function mySub1_OkBtn_click() {                
        //0 > 將目前畫面的store資料, 存成 np(多筆資料) 當參數, 傳給 處理 url
        console.log("0 mySub1_OkBtn_click - 列印包裝標籤.確定");
        var Tmp_sub_store = Ext.getCmp('sub_Grid').store;
        var cur_rec;
        var Tmp_SAPNO, Tmp_PN, Tmp_QTY, Tmp_EOCND, Tmp_RMK;
        var Tmp_data_JSON = "";  //將store資料轉成 JSON 的字串
        var Tmp_sub_np = {};        
        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);            
        }
        console.log("Tmp_DataAry1:", Tmp_DataAry1);        
        let Tmp_DataString1 = JSON.stringify(Tmp_DataAry1);
        console.log("Tmp_DataString1:", Tmp_DataString1);

        var Tmp_CHKDT = Ext.getCmp("sub_DT").getValue();
        console.log("Tmp_CHKDT:", Tmp_CHKDT);
        var np = {};
        np = {
            DataString1: Tmp_DataString1,  //將子畫面的資料(store)轉成 JSON字串
            CHKDT: Tmp_CHKDT,
        };        

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