2021年11月16日 星期二

iTEXT罕字處理

 

中文字博大精深尤其是姓名的使用,為了命好而擇用特殊的文字組合或筆劃值也不算罕見,不過系統列印要處理這類就狀況百出。幾個步驟備忘來留念下
1. 編碼:不管是大五碼還是簡字總之先轉碼成UNICODE為先。
2.字型:大概率要找免費的比較好,全字庫是可以考慮的範圍,底下是拿細明體+細明體ExtB來做範例,因為全字庫的罕字分三層,感覺卡麻煩。

部分罕字/特殊字的字碼會在65535使用4byte來儲存,故判斷上就不能只取3Byte不然會對不上字元,另外罕字不可能單純出現在最前或最後也可能藏在中間或單字以上,故處理上得一字字處理,底下的Method送入inStr 原始Unicode字串回傳Paragraph餵給iText來顯示....

private Paragraph getExtName(String inStr) {
Paragraph simplePara = new Paragraph();
BaseFont bf_name = null;
int i_char = 0;
try {
bf_name = BaseFont.createFont("c:\\windows\\fonts\\mingliu.ttc,1", "Identity-H", BaseFont.NOT_EMBEDDED);

int getCode;
int start=0;
int end=0;
String getstr = "";
for(int j=0;j<inStr.length();j++) 
{
getCode = inStr.codePointAt(j);
start=j;
end=start+1;
if(getCode > 65535) {
   j++;
   end=start+2;
}
getstr = inStr.substring(start, end);
boolean tmpc  = bf_name.charExists(getCode);
if(tmpc) {
Chunk Chunkid0 = new Chunk(getstr, font12_name);
simplePara.add(Chunkid0);
i_char++;
} else {
tmpc  = bf_name_ext.charExists(getCode);
if(tmpc) {
Chunk Chunkid1 = new Chunk(getstr, font12_name_ext);
simplePara.add(Chunkid1);
i_char++;
}
}
}
        } catch (Exception ex) {
        i_char = 0;
        log.error(ex.toString());
        }

if (i_char == 0) {
Phrase simplePhr1 = new Phrase(inStr, font12_name);
simplePara.add(simplePhr1);
}
return simplePara;
}

2021年11月4日 星期四

EDC2POS communication

 電子商務的軟體服務,經常需要有與週邊構聯的需求,今天就EDC裝置來做個備忘,可能若干年後會改變但近幾年碰到都還是如此吧!!


首先從規格書上會告知這個裝置的連線設定與通訊電文(文法),得符合這些規則那裝置就會依照命令(Command)作相對應的反應。


STX, ETX, ACK均為ASCII表所規範之字碼,這部分處理需已Byte array方式來塞值傳遞,Encode 是ASCII


LRC碼是將欲傳送之電文位元組(Bytes)各Byte做XOR後的結果用於檢核用。


LRC Method Sample Code:


刷1元回傳的電文範本,依照規格書上的來去一項項對應,取需要的即可!!





2021年9月30日 星期四

COBOL & DB2 中文字的處理

 古時候的DB2儲存中文字會在前後用0E跟0F框起來,但後人在改寫存取時沒處理好COBOL讀取時就會變成亂碼0E0F湊起來就佔了2 BYTES,也會讓欄位要塞好塞滿時得先扣掉2bytes才行,這部分要記好別踩坑。


直接更新下指令如果兩個TABLE長度不一樣,如TABLEA.CNNAME(14)而TABLEB.CNNAME2(20),就可以透過下列語法來塞值。

UPDATE TABLEA SET CNNAME=(SELECT CONCAT(LEFT(CNNAME2,13), X'''0F''') FROM TABLEB WHERE KEY=?) WHERE KEY2=?;

decodeURIComponent後把+號改空白顯示

前後端資料拋接要避開依些特殊符號的異常或資安檢核可透過URLEncoder來轉碼,不過特殊符號在decode後會變+號造成解譯上的困擾,這時候加上.replace(/\+/g, ' ') 即可。

JAVA端

rtnval.setDatas(URLEncoder.encode(gson.toJson(tablelist), "UTF-8" ));

JS端

call_ajax($('#QueryForm').attr('action'), $('#QueryForm').serialize(), e)

.done(function(data){

$('#rtn_tbody').html(decodeURIComponent(data.datas).replace(/\+/g, ' '));

})

.fail(function(){

alert('ajax call fail.');

});

}

2021年5月12日 星期三

MAVEN PDF to JPEG

PDF轉圖檔的需求,如果再iText7有現成的Method可以使用,不過可惜專案的Framework只能支援到iText 5.x ,底下是經測試可運行的,備忘囉!!

 AT POM.xml add

        <!--PDF to JPG-->
        <dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>1.8.3</version>
</dependency>


Add CLASS Method 

import java.awt.image.BufferedImage;
import java.io.File;
import java.util.List;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
//Filetype support jpg, jpeg, png, bmp, gif
public static int ConverPdf2Jpg(String s_path, String s_fname, String Filetype) {
String s_destname = s_fname + ".jpg";
int pageNumber = 1;
try {
        String sourceDir = s_path + s_fname + Filetype ;
        String destinationDir = s_path;
        File sourceFile = new File(sourceDir);
        File destinationFile = new File(destinationDir);
        if (!destinationFile.exists())   destinationFile.mkdir();
        if (sourceFile.exists()) {            
            PDDocument document = PDDocument.load(sourceDir);
            List<PDPage> list = document.getDocumentCatalog().getAllPages();
            String fileName = sourceFile.getName().replace(".pdf", "");                          
            for (PDPage page : list) {
            BufferedImage image = page.convertToImage();
                File outputfile = new File(destinationDir + fileName +"_"+ pageNumber + Filetype );
                ImageIO.write(image, "jpg", outputfile);
                pageNumber++;
            }
            document.close();            
        } 
    } catch (Exception e) {
        e.printStackTrace();
    }
    return pageNumber ;
}

2021年4月30日 星期五

ITEXT 5.5 合併文字的範例

最近有需求處理在PDF上加文字,有別於之前的浮水印使用的方式不太一樣,故備忘之...

X座標與Y座標可使用十分逼近法取得,無法像圖檔使用小畫家看座標,沒甚麼大學問就是苦功吧。

範例CODE 如下:

BaseFont font = BaseFont.createFont("c:\\windows\\fonts\\EUDCK.TTF", "Identity-H", BaseFont.NOT_EMBEDDED);

InputStream input =  new FileInputStream("templater.pdf");

OutputStream output= new FileOutputStream(new File("target.pdf"));

PdfReader reader = new PdfReader(input);

PdfStamper stamper = new PdfStamper(reader, output);

ColumnText ct = new ColumnText(stamper.getOverContent(1));  

Font FontChinese14 = new Font(font, 14, 0);

Paragraph iText = new Paragraph(Tpmienrol.getTpmi_Namec(), FontChinese14);

ColumnText.showTextAligned(stamper.getOverContent(1), Element.ALIGN_LEFT, iText, x座標, y座標, 0);   

stamper.setFormFlattening(true);

stamper.close();

reader.close();

因專案使用的是iTEXT 5.5版本,在iTEXT 7會更簡便些,BJ4就醬子吧~~改專案支援的FRAMEWORK施工更大,就向下延伸即可。

2021年4月9日 星期五

DB2 SP 中 LOOP Call SP Get Result

CREATE OR REPLACE PROCEDURE SCHEMANAME.SP_CALLER() DYNAMIC RESULT SETS 1

P1:BEGIN

DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE loc_cursor RESULT_SET_LOCATOR VARYING;
DECLARE CONTINUE HANDLER FOR SQLSTATE '23505' SET RET=SQLCODE;
SET PP = 1 ;
WHILE(PP < 5) DO
    CALL SCHEMANAME.SPNAME(PP);
    ASSOCIATE RESULT SET LOCATOR (loc_cursor) WITH PROCEDURE SCHEMANAME.SPNAME; 
    ALLOCATE cur CURSOR FOR RESULT SET loc_cursor;
    L1: LOOP 
        FETCH C1 INTO column1, column2, ...; 
        IF SQLSTATE<>'00000' THEN 
            LEAVE L1;  
         END IF; 
    END LOOP L1;
    CLOSE cur;

    SET PP = PP + 1 ;
END WHILE;

END P1
狀況:
DB2寫SP如果SP裡面又對另一個SP做多次呼叫,會一直抓到第一次呼叫SP的結果。
貌似因為DB2版本問題,所以原寫法建立到新的DB2就有問題,取值時須再LOOP即可!感謝辜狗大師。

2021年2月8日 星期一

WIN X BAT在工作排程器沒反應的調整

在批次作業要呼叫JAR時使用了相對路徑./xxx.jar方式呼叫,從Consloe執行OK可是設定上工作排程器就變成閃一下結束,參考了這網誌的說明就是卡在切換目錄上,實測加了後就可以跑了。

加了這個指令 CD /D "%~dp0" 就搞定了

/D 表示切換到執行的資料夾

"%~dp0" 表示當下的目錄


補充說明:本來也試過直接寫死絕對路徑不過考量到後續維護若干年後忘了或換位置會造成執行上的困擾,改成變數取得應該是比較好的做法。當然設定"開始位置"也是方法之一,但這個如果經手他人(MIS)如果對方忘了或疏忽掉也是隱患...