2014年12月17日 星期三

iText pdf writer template

一般報表會用到pdf資訊,就表示是只能讀(不然報表用xls可以再做運算,是更好分析的)
所以會比較偏向,產出正式文件報告或是紙本列印的功能取向...
當然就少不了固定的格式,頁首頁尾,或是套表之類的~
這時候,當然就是用template囉~

iText在java界應該算是個有名的project...也不少年了~
而且還大改過版~不知道該高興或難過,資源太多~很容易找到過時的Orz...

所以版號很重要,使用的package要看清楚,使用的方式要看清楚,不然就會像我一樣一直被表一_一|||...

現在用的是新版5+...package在 com.itextpdf.text.xxxxxx..
主要用以產生pdf...先說手刻pdf,和使用template的方式,兩邊實作的寫法差很多...
雖然官方文件看起來寫得精美,但是因為一直看到手刻的作法不同,然後一直被誤導Orz..

要先說~基本常用的document.add(xxxx)在使用template後是無效的,所以一旦使用template,就得全都用template的解法處理同一頁面(也許是因為我的template本來就是一整頁了...動態資訊用套表的方式寫入)...而Font,BaseFont,基本上也只是對手刻有用~在PdfContentByte裡,只有部分有效...
Paragraph 和 PdfContentByte不同,請把PdfContentByte當成是canvas的Stoke來想,會合理一點Orz...

#基本的template import
import com.itextpdf.text.*;
import com.itextpdf.text.*;

// Create PDF
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(document, fos);
document.open();
PdfContentByte pcb = writer.getDirectContent();

// Load existing PDF(template)
PdfReader reader = new PdfReader(fis);
PdfImportedPage page = writer.getImportedPage(reader, 1);

// PDF new page
writer.setPageEmpty(true);
document.newPage();

// Add Template
pcb.addTemplate(page, 0, 0);

document.close();

#若在template裡面要加圖,其圖檔也要做成template才能匯入
//Read Image to template
Image img = Image.getInstance(img1);
img.scalePercent(imgscale);    //unit %
img.setAbsolutePosition(0, 0);    //must
PdfTemplate myimg1 = pcb.createTemplate(img.getWidth(), img.getHeight());
myimg1.addImage(img);

//Put Image into template position p(X,Y)
pcb.addTemplate(myimg1, p.getX(), p.getY());

#在template裡加文字(數字基本上就是自己轉好文字format加對齊方式丟進去)
#begin/EndText 是必須的,就跟open/closePath那種一樣~
#如果要換行時怎麼辦呢~基本上他是不認\n,所以,就自己算位置吧~囧/
pcb.beginText();     //must
pcb.setFontAndSize(bf, pis.getFontsize());
//number align right
//pcb.showTextAligned(Element.ALIGN_RIGHT, p.getValue(), p.getX(), p.getY(), 0);
//string align left
pcb.showTextAligned(Element.ALIGN_LEFT, p.getValue(), p.getX(), p.getY(), 0);
pcb.endText();    //must

#文字指定顏色,粗體(bold/strong)...這裡就很奸詐了,因為在這裡pcb調用的BaseFont,只有字型和字型大小有用。但是文字的顏色與特效就需要特別的方式來寫..去改BaseFont只會讓你一直翻桌而已一.一
#重點在於setTextRenderingMode要改,不過粗體字線要多粗,是自己設定的
#因為 PdfContentByte 運作的方式跟canvas的方式非常相似,所以顏色,線條,特效改過後,再下次使用要重設定,不然就會看到後面一整串字都一起紅通通了XD
//font color and bold
pcb.beginText();     //must
pcb.setFontAndSize(bf, pis.getFontsize());                           
pcb.setRGBColorFill(255, 0, 0); //for change color
pcb.setLineWidth(0.3f);  //for bold
pcb.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE);
pcb.endText();    //must

//reset to normal text
pcb.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL);

#其他要補充的就是,PDF的坐標計算方式,是每一頁的左下角為0,0(第一象限)...和一般程式以左上角為0,0(第四象限)不同~~
#還有其實偶搞不太懂他的計算單位為何(反正每個lib用的單位都不一樣,誰記得那麼多鬼單位!!),所以對位置時,可以先用程式在每100單位的地方做標記或先畫格線出來看一下~應該就很清楚是要加要減...
#圖片的px在讀進來轉換也是,可能是dpi的關係~先試寫縮圖看看效果,再想下一步,才不會在最後一刻才發現圖跟鬼一樣XD...

2014年12月14日 星期日

jquery ui drag on android web browser

可能是因為觸控板的關係~
所以在pad的瀏覽器下~jquery的拖拉會有問題~
還好這時候~只要加入一隻修正就好了^O^b...

好心的stackoverflow
http://stackoverflow.com/questions/5796109/jquery-drag-and-drop-on-touch-devices-ipad-android

以及
http://touchpunch.furf.com/

2014年12月9日 星期二

apache poi 3.2 hssf xls

因為某案用poi 3.2,是有點舊就是,但也發現apache poi在xls這一塊深耕了很久~
功能相當豐富,另外這個版本有個bug,就是塗Cell的背景色,所以很堅持要塗色改色的功能,就請使用新的版本吧~

但~其實xls全部硬刻是還蠻硬的沒錯!!
容易卡在很多的Font/Style/Format,很亂,要刻最好先規劃再寫會比較好...
一般大家都會推,先讀一個templet進來再替換變數來長資料進去~
不過~因為刻出來了就用吧XD...

以下大概是基本的功能匯整與smaple

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.*;

//產生主要XLS
HSSFWorkbook workbook = new HSSFWorkbook();

//產生一個XLS sheet
HSSFSheet sheet = workbook.createSheet(sheetName);


//設定字型,FontHeightInPoints (px) 會比FontSize好
HSSFFont fontTitle = workbook.createFont();
fontTitle.setFontName("標楷體");
fontTitle.setFontHeightInPoints((short)18);
fontTitle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

//設定Cell的style,包含框線(上,下,左,右)客置與型式,內容(置左/中/右)
HSSFCellStyle rowBorderRight = workbook.createCellStyle();
rowBorderRight.setBorderBottom((short)1);
rowBorderRight.setBorderLeft((short)1);
rowBorderRight.setBorderRight((short)1);
rowBorderRight.setBorderTop((short)1);
rowBorderRight.setWrapText(true);     //若資料內容有換行
rowBorderRight.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
rowBorderRight.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

//隱藏指定的欄(開發時常會漏看這個,被害死Orz)
sheet.getSheet().setColumnHidden(col, true);

//合併儲存格
CellRangeAddress craxy = new CellRangeAddress(minX,maxX,minY,maxY);
sheet.addMergedRegion(craxy);

//儲存格數字格式
//為了排版框線會出現非常多的樣式,可建一個基本的,然後大家一起cloneStyleFrom ,就會快一點點
HSSFCellStyle rowNumber = workbook.createCellStyle();
rowNumber.cloneStyleFrom(rowBorderRight);
rowNumber.setDataFormat( workbook.createDataFormat().getFormat("###,###,##0.####"));
//儲存格數字格式 %,內建%已經自動幫你*100了,所以要記得先腦補
rowPa.setDataFormat( workbook.createDataFormat().getFormat("0.00%"));  //-->0.0001


儲存格的表示方式,其實可以先在xls上面開儲存格試打,再貼到程式裡,可以省一些預覽時間~記得儲存格式會綁在CellStyle底下,所以...這個CellStyle別拿去給不同型態的用!

//數字負要轉紅字

//顏色可以用英文寫,到xls上時,會發現他自動翻譯成中文了~
rowNumber.setDataFormat( workbook.createDataFormat().getFormat("###,###,##0.####;-[Red]###,###,##0.####"));

//格子填數字
HSSFRow row = sheet.createRow((short)rowIdx);
HSSFCell cell2 = row.createCell(colIdx);
cell2.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
cell2.setCellValue(d.doubleValue());
cell2.setCellStyle(rowNumber);

//格子填文字,HSSFRichTextString可以提供更多樣化的文字設定
HSSFRichTextString strTitle = new HSSFRichTextString(getTitle());
strTitle.applyFont(fontTitle);
celTitle.setCellValue(strTitle);
celTitle.setCellStyle(rowCenter);

//格子要變高,是改在HSSFRow裡面設定,不是Cell
row1.setHeightInPoints(30);

//使用公式,原則上就是把XLS上的公式貼來就對了,只是Word XLS copy &paste會小聰明依行數變化,poi可就要自己寫了~
cell2.setCellFormula("D2+F2");

另外說~能不能公式+合併儲存格呢~~
結論是可以的XD...

關於DataFormat
文件上寫說可以支援到4part,不過他有但書說...
Format a value according to the standard Excel behavior. This "standard" is not explicitly documented by Microsoft, so the behavior is determined by experimentation; see the tests.


打開咱們的xls 2010...會發現儲存格裡 的format2part以上...
測了一個小時多一u一a...還好情況不多,窮舉還可以...
第一個指正...
第二個為負...
第三個為0...
第四個看情況是可以不用給(若只給part3,打中文還是會顯示中文的說...。但可以用在"輸入錯誤",或是特別案例上不然只給 part3= part4 default @)
所以~這就是產品加密的好方法嗎=_=?


2014年12月7日 星期日

EC2 linux Postgresql9.3+phpPgAdmin

總算是要寫完了Orz..
到最後的Postgresql + phpPgAdmin...
身為postgresql的擁護者,就算沒用到也把它裝起來備用XDXD...

B. install postgresql 9.3
amz上提供的就到9.3而已,不過因為我也喜歡9.3,剛好~
要注意的是postgresql官網上只提供centos/紅帽/..etc的rpm...
但是~那些rpm..EC2都吃不進去!所以請用內建的就好,雖然rpm吃不進去,不過安裝設定方式都沒變,官網的資料還是可以參考~要注意的是名稱,跟以往的長得不太一樣!
https://wiki.postgresql.org/wiki/YUM_Installation

phpPgAdmin是真的找不到rpm安裝包了,但是還好~他的tar檔做得好~
只要先裝好php-pgsql後,再用tar解壓改設定,一次就過關了^_^b...

cd /etc/project
yum list postgres*
sudo yum install postgresql93-server.x86_64
sudo adduser postgres (if exist..ignore it)
sudo passwd postgres
su postgres
cd /var/lib/pgsql93/data (to check if ok)
exit (return to myuser)
chkconfig --list (check postgresql service name)
sudo service postgresql93 initdb (need sudo user to run service)
sudo su postgres
cd /var/lib/pgsql93/data
vim pg_hba.conf   (change ident to md5)
vim postgresql.conf  (listen_addresses='localhost')
exit (return user)
sudo service postgresql93 restart

B.0 create role/user
sudo su postgres
psql postgres
CREATE USER xxxuser WITH PASSWORD 'xxxpwd' CREATEDB;
CREATE DATABASE xxxdb OWNER xxxuser;
\q

B.1 install phpPgAdmin
sudo yum install -y php php-pgsql
sudo service httpd restart


cd /...somewhere..../www/html
wget http://downloads.sourceforge.net/phppgadmin/phpPgAdmin-5.1.tar.gz
tar -zxv -f phpPgAdmin-5.1.tar.gz
mv phpPgAdmin-5.1 phpPgAdmin
vim phpPgAdmin/conf/config.inc.php

host --> 127.0.0.1

##test php page

在最後的最後,環境安裝完後,要記得設定service開機啟動~~
和一般的linex操作一樣~
chkconfig --list
sudo chkconfig --level 5 postgresql93 on
sudo chkconfig --level 5 mysqld on
sudo chkconfig --level 5 httpd on

EC2 linux apache httpd+php+MySql+phpMySqlAdmin

先說,EC2 linux 跟Centos不一樣,他的yum內容,是amz自己維護的,所以其實有很多東西有少,或者名字不一樣~所以~當初看到他的廣告宣傳說有MySQL...Postgresql就很高興的選了...然後就發生了一些事情|||Orz...

EC2上面好像沒有Centos,可能是怕搶到紅帽的飯碗,另一個要免費的就是ubuntu。
其實ubuntu也不是不好,最早一開始也是用ubuntu server...但是因為某次他跟kvm還是vitural box太不合,加上當時同事也吵著要用centos...所以後來就改centos了~

在EC2要 yum時,建議先用yum查詢一下~e.g. yum list postgres*
這樣才不會一直被騙XD..因為網路上的資源大都以CentOs為主...

1. Install apache httpd
apache和 php依然是相當的快樂和平順~
記得當初開instance時,防火牆要開80,預設只有22(ssh)
話說,為啥特別把document root搬家,因為原本那邊是root的領域,換到一般user的資料夾下,統一管理比較方便...
sudo yum -y install httpd
vim /etc/httpd/conf/httpd.conf
##change document root to somewhere...
sudo service httpd start

vim /...somewhere.../www/html/index.html
##write something in index.html
##test http://xxx.xxx.xxx.xxx/

2. Install php
sudo yum -y install php
vim /...somewhere.../www/html/index.php
##write something in index.php
sudo service httpd start

##test http://xxx.xxx.xxx.xxx/index.php

3. Install MySQL
MySQL 在上面,看起來最新就只到5.5,忍著點吧O_o|||,反正用MySQL的也不會要求什麼強大的功能,基本的能動不要有bug就好!
yum list mysql*
sudo yum install mysql55-server.x86_64
chkconfig --list (check mysql service name)
sudo service mysqld start
sudo service mysqld status  (check status)
## set mysql root password
/usr/bin/mysqladmin -u root password

4. Install phpMyAdmin
這個怪打超久的,中間還死了兩三次XD...網路上普遍是說,用tar的回來自己解,然後改設定檔...嗯,這種方式以前在win上玩過是ok,但是在EC2上試,就很鬼的一直白頁面。很不想還要去開php log來de的事情,還翻到了某個日文版的攻略...重點是還裝起來了(日文有漢字真好!)只是他是很舊的phpmyadmin...但是~能用就好XD...
(說到當年要裝python一個很鳥的套件,也是日文攻略來的,這要說台日友好嗎XD)

這個方法是用rpmforge的資源,其實我後來有去看一下他最新發布的,但是phpmyadmin還是在2版,社群資源還是有差...
wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.3-1.el7.rf.x86_64.rpm
rpm -Uvh rpmforge-release-0.5.3-1.el7.rf.x86_64.rpm
sudo vim /etc/yum.repos.d/rpmforge.repo

[rpmforge]
name = Red Hat Enterprise $releasever - RPMforge.net - dag
#baseurl = http://apt.sw.be/redhat/el5/en/$basearch/dag
mirrorlist = http://apt.sw.be/redhat/el5/en/mirrors-rpmforge
#mirrorlist = file:///etc/yum.repos.d/mirrors-rpmforge
enabled = 0                             <---edit
protect = 0
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rpmforge-dag
gpgcheck = 1
priority = 10                         <---edit

yum -y --enablerepo=rpmforge install phpmyadmin
sudo vim /usr/share/phpmyadmin/config.inc.php



$cfg['blowfish_secret'] = 'a8b7c6d';    <---原本是空白,隨便找一個範例塞的

sudo vim /etc/httpd/conf.d/virtualhost.conf
<VirtualHost *:80>
    alias /phpmyadmin /usr/share/phpmyadmin/
    <Directory "/usr/share/phpmyadmin">
        Options ExecCGI
        AllowOverride all
        Order Allow,Deny
        Allow from all
    </Directory>
</VirtualHost>

##restart httpd
sudo service httpd restart

在這個版本的phpmyadmin裡,他的phpmyadmin.conf,有寫了多重路徑都可以轉到,覺得有需要改就改吧:)



EC2 linux timezone, jdk6+tomcat7

這篇不太有營養,不過加減記錄一下...

大家都知到amz server的特色就是,因為主機在國外,然後台灣的市場是相對的小小小...
所以再怎樣,AMI(Amazon Machine Image)要找到台灣不用改就能用是非常的困難...
(想起當年裝windows時,亞洲版本少的可憐,裝到日文版的...日文介面是非常的新鮮,完全看不懂XD...還好跟win server2008還算熟,反正跟中文版項目順序是一樣的,拿著中文的畫面找日文的功能就是了...)

所以時區就很重要了~官方也有特別寫了一篇~驗證後他沒亂寫XD...
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/set-time.html
先確認一下timezone的全名與位置,台灣還是用台北Q_Q..就降子...
tzselect 最後會帶出UTC和地區時間,可以確認他時間有沒有對後再用。
## check timezone name and datetime
tzselect
## --> Asia/Taipei
vim /etc/sysconfig/clock

ZONE="Asia/Taipei"
UTC=true

sudo ln -sf /usr/share/zoneinfo/Asia/Taipei /etc/localtime
sudo reboot

裝jdk6...嗯,因為裝到爛了,基本上我jdk都是用bin檔裝的,然後在要起Java的sh檔上,加上指定jdk的執行,所以倒也不會搶了openjdk的飯碗...
Tomcat也習慣用zip(tar),就好像也沒啥特別好講的XD...

install jdk6
##use SFTP (use no pwd private key) to upload file
cd /etc/project/jdk
cp ~/software/jdk-6u45-linux-x64.bin .
chmod +x jdk-6u45-linux-x64.bin
./jdk-6u45-linux-x64.bin

change default jdk
alternatives --config java
#choose jdk-6xxx
java -version
javac -version

install Tomcat
## upload tomcat.tar to home
cd /etc/project
cp ~/apache-tomcat-7.0.26.tar.gz .
tar -zxv -f apache-tomcat-7.0.26.tar.gz
vim bin/startup.sh  (assign JAVA_HOME)
JAVA_HOME=/etc/project/jdk/jdk1.6.0_45
bin/startup.sh

EC2 linux user manager

當第一個user可以連上EC2 server時,接下來就得好好處理一下帳號問題~
每次建server時,都會生出一堆user和password...
好幾組的帳號密碼一定要先開txt記下來~不然一定會發生搞笑事情XD...

參照官方說法
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/managing-users.html

一開始的ec2-user是有sudo權限的~也只能先用他先把帳號跟設定的部份處理掉在說~

1. create account
##先改掉ec2-user的密碼,反正也不知道是什麼,先改個自己知道的
sudo passwd ec2-user

##建立自己需要的user
sudo adduser myuser
sudo passwd myuser

2. add myuser to sudoer (not sudo group)加入後馬上生效,不需要重開機
##先把自己的user加入sudoer,很重要!!
sudo vim /etc/sudoers
##append bottom
myuser ALL=(ALL) ALL

3.  create myuser rsa private key/public key
後來想一想,在公有雲上面,使用囉唆的RSA是相對的安全,所以就照原本的用法吧~
要注意的是,在os上限制登入者的憑證的權限必須是700/600,總之就是只能專屬原所有者使用!
3.a create myuser ssh authorized_key
sudo su myuser
mkdir .ssh
chmod 700 .ssh
touch .ssh/authorized_keys





3.b generator myuser's public/private key..
這個和EC2上面的key pair應該是一樣的,但是官網的寫法很奇怪,總之是用別的solution
##create tmp folder
mkdir pem
cd pem
ssh-keygen -b 1024 -f myuser -t dsa
##passphrase just ENTER (without password)
##myuser(private key), myuser.pub(public key)
ls -l  (will see myuser and myuser.pub)
chmod 600 myuser.pub
cd ~
cat pem/myuser.pub >> .ssh/authorized_keys

3.c create putty ppk
vim pem/myuser
##copy all text from terimal console to local pc txt, named myuser.pem
##run puttygen
##load myuser.pem
##generator and save private key(myuser.ppk)
在這邊就是做出私鑰來用,但是有一點是,若是有需要用SFTP...
因為我習慣使用的是FileZille Client,但是他的憑證不支援多一道密碼保護的,
所以若是要用SFTP,那就不要用passphrase,空白就好
還有就是公私鑰似乎會認檔名,檔名不能亂改,所以就用同名的就好~
連putty使用私鑰的方式就一樣了,但是注意只能用在此單一user...
(當初想偷懶全部user用同一套公私鑰~但就是一直有問題,分開各自設定就好了!)

3.d SFTP by FileZilleClient
test SFTP
編輯->設定->連線->SFTP  就是把ppk放進去

連線時,就會解開了,然後只要打user name就可以,跟平常的SFTP一樣~

4. ssh connect and test
因為我習慣使用pietty,pietty會記錄連線資料,所以要是確定平常用的那個user就可以用pietty設好,以後就很方便~
不過在東西還剛開始的時後,還是建議用putty...雖然他每次連都要重設,重新指定一次,
但是因為在一直測不同user...一直換key的檔案也沒差XD...這時putty就比較好用!

補一下putty的設定連線方式圖
檔案放進去後,再打ip


黑白畫面就是打帳號名稱就是了。
接下來就是確定myuser是否正常,而且要確定是否有sudo權限。
(千萬別還沒試出自己的sudo就去把ec2-user給砍了,那會很搞笑的XD)

5. disabled ec2-user sudo
記得先設定好自己的帳號,因為我不習慣用root,也不習慣開放root來用。
所以一向都是以sudoer在做處裡。EC2預設也是不能用root 登入,所以也不用特別去改~
反正RSA就在前面會先踢人了!沒設定RSA的user連第一關都到不了XD...就不管他了~
確定自訂的user都能動之後,就準備把ec2-user給降級了~是說可以砍了他...
不過我是覺得倒也不用這麼狠...而且他本來就是一般user,amz做了點手腳讓他有sudo而已~只要把他的設定檔弄走就好了,重開機後才會生效,所以要是想保有ec2-user的sudo在還沒重開之前還是有救的~~
## here is ec2-user can be sudoer
sudo cat /etc/sudoers.d/cloud-init
## rename/remove or delete the file...
sudo mv /etc/sudoers.d/cloud-init xxxxxxx
##  disabled sudo after reboot
sudo reboot

## login ec2-user to check if sudoer


2014年12月6日 星期六

Linex EC2 Connect

最近打算研究一下amazon的EC2...
之前也有小玩過~不過都是跑WinServer...

因為錢錢的問題...所以~也是該研究一下linex怎麼弄低~

建instance的方式都差不多~很快的就生出instance...
但~是~~

怎麼連上去開始出問題了Orz..他沒像Win會給你Administrator的密碼...
為了搞出這個畫面,又奮鬥了一個小時Orz...

大概幾個要注意的地方是~

### get .gem file
在建instance的最後Review畫面,它會問你要不要給一組key...為了安全性的問題,記得一定要選自訂的... 或是自動產生一組,會拿到一個xxx.gem 的檔案。

### .gem -> .ppk
把gem存起來~要用putty系列工具...
http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
這裡除了putty外,還有 puttygen.exe
利用puttygen.exe Load .gem檔,然後另存為 private key
我習慣都會打密碼,因為這些公開的流程大家都知道,想什麼保護都不做就太天真了!

### putty import .ppk
打開putty...Connection->SSH->Auth,基本的勾勾不用什麼改
在底下的檔案位置把.ppk 擺上去,確定

### connect server
雖然看到網路文章連的位置是dns還什麼的,不過我就直接連IP...
不知道default user是什麼,總之先從amz給我的提式開始猜一_一|||
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html

矇對後,會再跳出一行要打key的密碼,就用.gem轉.ppk時的那組,登登~~
總算看到歡迎畫面了Orz...

接下來~繼續奮鬥,但是至少~應該就有規則一點了吧XD...