2020年4月6日 星期一

for java : pdfbox,為什麼文件呼叫了.load之後頁數一直都是0!?

pdfbox-2.0.19不錯用,大家最常用的是pdf to image這類需求
可是今天試了居然頁數是 0 !?
是這樣寫的
-------------------------------
PDDocument document=new PDDocument();
document.load(new File("E:\\download\\xxxx.pdf"));
PDFRenderer renderer = new PDFRenderer(document);
var pageCount=document.getNumberOfPages();  <--居然是「永遠的0」.....
for(var i=0;i<pageCount;i++){
    BufferedImage image = renderer.renderImage(i);
    ImageIO.write(image, "JPEG", new File("E:\\download\\pdf_"+i+".jpg"));
}
-------------------------------
厚,你嘛幫幫忙,load函數不是這樣用的啦
正確的寫法是這樣的
-----------------------------------
PDDocument document  = PDDocument.load(new File("e:\\download\\xxx.pdf"));
...
...
...
-----------------------------
這樣getNumberOfPages就會是正確的了

居家辦公很悶的,鬧個笑話給各位PG笑一下吧

2020年4月3日 星期五

for java,值為string type的 enum 類別

一般如果是用string做值的enum,比較直接是寫在interface
---------------------
 interface PlayserStatus {
    public final static String PLAY="play";
    public final static String STOP="stop";
}

class Player {
   String  _status;
   Player(String status){
       _status=status;
   }
....
....
}
然後再用
  var player=new Player(PlayserStatus.PLAY);

---------------------
問題是這樣就無法限制Player的建構元一定是要在PLAY/STOP這樣的範圍,太危險了
所以還是enum寫法比較安全
--------------.
enum  PlayerStatus {
     AXN_INIT("init"),
     AXN_PLAY("Play"),
     AXN_PAUSE("Pause"),
     AXN_FINISH("Finshed");

    private final String value;
    private PlayerStatus(String s) {
        value = s;
    }
    public String toString(){
        return value;
    }

}
class Player {
    private  PlayerStatus xntStatus;
    public Player(PlayerStatus status) {
        xntStatus=status;
    }
    @Override    public void setStatus(PlayerStatus s) {
        xntStatus=s;
    }
    @Override    public String getStatus() {
        return xntStatus.toString();
    }
}
....
...
 public void main(String[] args){
  ...  
   ...
   ...
   var player=new Player(PlayerStatus.AXN_INIT);
   System.out.println("status is "+player.getStatus());
   player.setStatus(PlayerStatus.AXN_PLAY);
   System.out.println("status is "+player.getStatus());
   ....
 }
----------------------------------------------------
這樣就可以更具體限制了
有關java enum 類型的更完整的介紹,請參考以下更精闢的好文
https://tpu.thinkpower.com.tw/tpu/articleDetails/1432

同場加映!!
如果是要切換狀態時的行為,不是在player裡大改, 而是由playerStatus決定呢?
------------原班人馬,加個狀態表------------------------------
//先定義行為
interface PlayerIsDoing{
  void doing();
}
class InitPlayer implements PlayerIsDoing{
    public void doing(){
        System.out.println("Doing Init Now");
    }
}
class PlayingPlayer implements PlayerIsDoing{
    public void doing(){
        System.out.println("Playing Now");
    }
}
//再定義行為對映表,順便了解一下直接給值的HashMap的寫法
class HtLolder{
  static PlayerIsDoing p1=new InitPlayer();
  static PlayerIsDoing p2=new  PlayingPlayer();
  static Map<String,PlayerIsDoing> ht=new HashMap<String,PlayerIsDoing>(){
      {
          put("init",p1);
          put("Play",p2);
      }
    };
 }
//改一下enum類別
enum  PlayerStatus {
      
      AXN_INIT("init"),
      AXN_PLAY("Play");
      Map<String,PlayerIsDoing>  ht=HtLolder.ht;
     private final String value;
     private PlayerStatus(String s) {
         value = s;
     }
     public String toString(){
         return value;
     }
     //重點來了!!
     public  void doPlaying(){
         ht.get(value).doing(); <-----------
     }

 }
class Player implements PlayerAction{
    private  PlayerStatus xntStatus;
    public Player(PlayerStatus status) {
        xntStatus=status;
    }
    @Override    public void setStatus(PlayerStatus s) {
        xntStatus=s;
    }
    @Override    public String getStatus() {
        xntStatus.doPlaying();<-----------
        return xntStatus.toString();
    }
}

//it's show time!!
public static void main(String[] args) throws IOException {
    var player=new Player(PlayerStatus.AXN_INIT);
    System.out.println("status is "+player.getStatus());
    player.setStatus(PlayerStatus.AXN_PLAY);
    System.out.println("status is "+player.getStatus());
    ...
    ....
}
--------------------------------------------------------------
這樣,有新行為,player不用改(小改啦),把新行為放在PlayerStatus跟行為對映表所在的套件中
會比較靈活些吧
大家加油吧!!



2020年4月2日 星期四

for ms-sql , 16進制字串轉int, 中文字to byte array,to int.....轉換

先講x0ab1234這類的資料轉int怎麼做吧

----------------
declare @R01 int ;
...
...
set @R01=convert(int, convert(varbinary,'0xE000',1));
--------------------------
其中,這個convert(varbinary,'要轉換的16進制字串',1)格式問題
請參考文件

https://docs.microsoft.com/zh-tw/sql/t-sql/functions/cast-and-convert-transact-sql?redirectedfrom=MSDN&view=sql-server-ver15

再來說中文字hi-byte low-byte怎麼轉成unicode整數
------------------------
declare @TestString nvarchar(1);
set @TestString='你'
print
sys.fn_varbintohexstr(substring(cast(@TestString as varbinary(2)),2,1))
 +replace(sys.fn_varbintohexstr(substring(cast(@TestString as varbinary(2)),1,1)),'0x','')
--顯示為"0x4f60"
--再套用 上例「convert(int.....)」

set @R01=convert(int,convert(varbinary, sys.fn_varbintohexstr(substring(cast(@TestString as varbinary(2)),2,1))+replace(sys.fn_varbintohexstr(substring(cast(@TestString as varbinary(2)),1,1)),'0x',''),1));

--R01為20320
----------------------------------------
驗證方式
請到「字碼查詢」
https://www.cns11643.gov.tw/search.jsp?ID=7&SN=&lang=tw
輸入4F60看看是不是得到「你」字

以上,大家加油了!!