java 电子签章_PDF开发+电子签章,如何实现真正地脱离硬件的无纸化办公体验(实战篇)?...
上一篇中我們主要介紹了PDF的一些基本格式,讓大家入門有一個初步的了解,接下來我們進行PDF的開發(fā)和電子簽章的實戰(zhàn)。
【PDF文檔修改】
上篇文章中了解了PDF的基本格式,我們要實現(xiàn)無紙化辦公,勢必要修改現(xiàn)有的PDF文檔,往里面填寫具體的數(shù)據(jù)。那如果我們要對去解析修改PDF的具體內(nèi)容,那只有上面的基本了解,是遠遠不夠的,就算借助第三方開發(fā)包要去解析修改,也是一個龐大復(fù)雜的工程。那我們怎么樣可以最方便快捷的實現(xiàn)對PDF文檔的修改呢?
這里我們可以借助PDF自身的特性,因為它是由很多對象組成的結(jié)構(gòu)化的格式,所以我們不需要去解析現(xiàn)有的數(shù)據(jù)內(nèi)容,只要往里面增加一個新的數(shù)據(jù)對象就可以,至于排版描述信息,也是現(xiàn)成支持的可覆蓋模式。簡單的說就是增加一個對象,告訴它排版位置,來覆蓋原來的內(nèi)容就可以達到我們的目的。當(dāng)然還是要借助開源的第三方開發(fā)包來實現(xiàn),可以更加的方便,現(xiàn)在比較成功的開源免費的開發(fā)包有itext和PDFbox,基本功能大概都可以實現(xiàn),這里我們選取itext來使用和說明。
Itext有java和C#版,本文檔說明都使用java版,以下用到的功能已經(jīng)在研發(fā)中心的SDK中都已實現(xiàn),包括java和C#版的。
根據(jù)上面的思路,我們會碰到和需要解決的幾個問題如下:
1、找到區(qū)域先覆蓋白色背景色
為了讓我們的修改不至于和原來的內(nèi)容一起顯示出來,造成混雜難看的效果,所以我們在覆蓋新內(nèi)容之前,先對修改區(qū)域內(nèi)做一層白色背景色的覆蓋,以確保我們填充的內(nèi)容可以正常清晰的顯示。
那如何簡單方便的可視化的確定我們要填充覆蓋的區(qū)域。最簡單的方法就是我們打開現(xiàn)有的PDF文件,在里面直接用光標(biāo)畫出我們要修改填充的區(qū)域,這里涉及到屏幕視圖坐標(biāo)和PDF的自己的坐標(biāo)系之間的轉(zhuǎn)換問題需要解決。pdf頁面的位置坐標(biāo),一般原點為pdf頁面左下角,水平為x軸,高度為y軸,所以在屏幕上選取區(qū)域得到的坐標(biāo)和PDF修改使用的坐標(biāo)之間需要做對應(yīng)的轉(zhuǎn)換。當(dāng)然在這之前,我們要先確定要修改的頁碼是第幾頁。
2、填充手寫簽名圖片或者文字內(nèi)容
新建一個段落Paragraph,往Paragraph里面設(shè)置手寫簽名圖片,或者文字內(nèi)容,再設(shè)置相應(yīng)的邊框?qū)傩?border),邊距屬性(margin)和間隙屬性(padding)來調(diào)整顯示效果即可。但是這里如果是圖片不需要特殊處理,如果是文字內(nèi)容的話,還需要涉及到換行顯示的效果問題。
因為PDF的排版需求都會比較美觀,所以在控制文字排版時,而如果采用簡單共通的處理,在面對多種多樣的情況時,勢必會影響排版美觀,而無法達到要求。所以很多時候我們都需要對單行文本,多行文本,左右上下對齊格式,當(dāng)文本超出顯示范圍時,使用縮小字體加換行顯示來達到更好的效果等等情況做出區(qū)分處理。
處理方式為,先做字體由大到小的循環(huán),在循環(huán)判斷本區(qū)域里能否顯示得下這么多字。判斷邏輯有兩種,第一種為使用itext提供的函數(shù)判斷如下:
LayoutResult的值有FULL(填滿狀態(tài)),PARTIAL(部分填充狀態(tài)),NOTHING(無填充狀態(tài))。這個是itext帶的可以拿來判斷區(qū)域填充狀態(tài)的方法,使用起來比較方便,不過可能會由于itext的版本不同,它的使用方法也會發(fā)生改變。然后如果有什么特殊的格式需求的話,可能需要分情況另加處理來實現(xiàn)。
第二種根據(jù)字體,自己計算顯示文本所需的寬度,計算字體的高度,然后再跟顯示區(qū)域的寬度和高度對比,計算每一行合適的字數(shù),填入每行的內(nèi)容。這個方法可以自己控制里面更多的顯示格式,但是相對來說計算起來比較復(fù)雜。主要幾個地方說明一下:
具體的計算和處理方式,需要根據(jù)各個項目要求自己進行循環(huán)比對,和顯示控制。
3、中文字體顯示
PDF在支持中文顯示上,需要導(dǎo)入中文字體庫,如果沒有的話,中文的地方會顯示空白。在導(dǎo)入中文字體庫上,一般有三種方法:
三種方法的優(yōu)缺點如下:
? 第一種方法,適合Windows操作系統(tǒng),如果要夸平臺使用,就需要加入不同的平臺判斷,引入不同的路徑來適配。
?第二種方法,使用起來比較簡單方便,導(dǎo)入iTextAsian.jar包就可以,不需要再去考慮其它的,不過現(xiàn)在iTextAsian.jar里面的宋體,不支持制表符(\t),如果有內(nèi)容中有制表符(\t)的話,還是要導(dǎo)入Windows自帶的宋體才可以解決。
?第三種方法,自己帶上了字體,能解決有什么特殊要求的情況,也不需要考慮系統(tǒng)平臺相關(guān)性,不過就是發(fā)包里面需要帶入字體庫文件。
4、字體顏色可能的問題
在我們對原有內(nèi)容進行覆蓋時,需要注意的是,最好對我們填充內(nèi)容的字體顏色進行顯式的設(shè)置。如果我們沒有顯式的設(shè)置的話,itext去覆蓋的時候會使用默認匹配的顏色,這樣在對不同PDF文檔進行填充時,可能會使用不同的顏色,如果恰好使用了白色的話,那有時候就會發(fā)生看不見文字內(nèi)容的情況,因為雖然文字是填充進去了,背景和字體都使用了白色,就什么都看不見了,所以最好還是要自己顯式的設(shè)置好顏色為好。
5、PDF的各種頁面視圖框
當(dāng)我們用PDF的各種閱讀器,打開一個PDF文檔的時候,我們看到的頁面內(nèi)容,與實際文件里面包括的內(nèi)容是不一樣的。換句話說,也就是我們看到的只是這個PDF創(chuàng)建者想給我們看到的東西,其實里面還可能隱藏了很多內(nèi)容,只是沒顯示出來。
這里涉及到幾個PDF上面的視圖框的概念:
? MediaBox:媒體框,是頁面上最大的一個框,包含一個頁面的全部對象,包括頁面上的文本、圖片和標(biāo)記等。媒體框定義了頁面上需要印刷的物理介質(zhì)的范圍,除圖文內(nèi)容外,還包括裁切標(biāo)記、色控條等。?MediaBox是一個頁面中最大的box。其他的box可以和它一樣大,但絕不可以比它大。
?CropBox:裁取框,定義了頁面在顯示或打印出來以后,要裁取的部分。Adobe Acrobat軟件使用這個來顯示和打印頁面。
?BleedBox:出血框,定義了當(dāng)用于生產(chǎn)環(huán)境時頁面內(nèi)容將被裁剪到的區(qū)域。通常BleedBox比TrimBox大3到5毫米。默認情況下,BleedBox與CropBox相等。
TrimBox:成品裁切框,成品裁切框確定頁面在印刷和裁切之后的最終有效尺寸。成品裁切框?qū)?yīng)著頁面的實際尺寸(成品尺寸),如果一個PDF文檔包含一個裁切框,那么裁切框的尺寸與最終成品尺寸相等。
ArtBox:內(nèi)容框,有點特殊。它定義了某些特殊用途的頁面中的區(qū)域。它很少被程序用到。有一種情況會使用到它是在控制頁面廣告。如果一個頁面有廣告,那么ArtBox定義了廣告區(qū)域的大小。
初看到上面五個框,可能大家會疑惑,為什么要這么復(fù)雜,這就跟PDF一開始定義的作用有關(guān),PDF是為內(nèi)容的初版和發(fā)布準(zhǔn)備的,也是為它服務(wù)的,所以里面用到很多出版印刷屆的一些術(shù)語。作為程序處理,我們要知道的是,這五個框的定義會影響到我們實際看到的PDF頁面的大小,自然也就會影響到位置坐標(biāo)的計算。
作為電子文檔來說我們需要多關(guān)注的應(yīng)該是MediaBox和CropBox。MediaBox是包含整個頁面所有的內(nèi)容,我們程序控制位置的坐標(biāo)原點,也以MediaBox的左下角為原點。但是我們通過PDF閱讀器看到的頁面大小,是經(jīng)過CropBox裁剪后的內(nèi)容,這就涉及到你眼睛看到的視圖坐標(biāo)和程序操作的視圖坐標(biāo)之間的轉(zhuǎn)換計算了。之前碰到過有幾個PDF文檔,我們通過閱讀器看到的都是幾頁規(guī)則的A4紙,但是實際上它中間有幾頁的大小可能是兩張A4紙那么大,也就是他的MediaBox的大小是有兩張A4紙,而通過CropBox來裁剪出一半顯示出來給我們看。這種情況在我們做內(nèi)容填充渲染的時候,勢必要知道CropBox的具體坐標(biāo),不然我們就有可能填充到CropBox之外隱藏的內(nèi)容上面,而再打開PDF上面確實什么更改都沒有顯示。
【PDF電子簽章】
PDF電子簽章的作用為,可以驗證PDF在蓋章后內(nèi)容有沒有做修改,保證內(nèi)容真實性和完整性,可以驗證簽章人信息,保證簽章人不可否認性。那它是如何做到的呢?
首先數(shù)字證書可以是一本個人或企業(yè)證書,里面包含簽章人的身份信息、簽章人的公鑰和私鑰。我們使用PDF的簽章對象,將數(shù)字證書里面的身份信息設(shè)置進簽章對象,然后使用簽章人的私鑰對PDF文檔進行算法簽名,再設(shè)置簽章對象的顯示信息為簽章人的印章圖片,即可實現(xiàn)我們想要的效果。
至于內(nèi)容有無修改的驗證的話,一般的PDF閱讀器都可以做到,驗證的功能,所以這個簽章效果可以是通用的,當(dāng)然它的簽名算法需采用國際流行的SHA和RSA等,如果使用國密算法的話,那驗簽工具就也得自己實現(xiàn)了(PDF閱讀器),因為adobe 的PDF標(biāo)準(zhǔn)里沒有國密算法。
這里itext使用的簽名接口主要有下面幾步(itext5.5.0):
相當(dāng)于先對PDF文檔進行取摘要,再對摘要進行簽名,這主要也是為了提高簽名效率。
使用PDF閱讀器打開后的驗簽效果如下圖:
上面說的使用的證書都是pfx文件證書,自帶簽章人的私鑰的證書,不過現(xiàn)在很多都是要求使用UsbKey來實現(xiàn)里面的簽名過程,更安全的保護用戶的私鑰信息。那如果是使用UsbKey該如何實現(xiàn)呢?這時候我們需要實現(xiàn)上面的簽名算法接口:
可以參考PrivateKeySignature類,將里面的成員變量私鑰不要,然后sign()函數(shù)調(diào)用UsbKey里面的簽名算法就可以。
由于簽章對象顯示時,印章圖片的寬高格式和簽章區(qū)域不一定能完美匹配,如果想對印章區(qū)域后面的內(nèi)容進行覆蓋的話,可以給印章區(qū)域設(shè)置背景圖片來覆蓋。
簽章使用圖片,為了更好的貼合現(xiàn)實情況,在使用前最好對印章圖片進行背景色透明的處理。如果要蓋多個印章,需要注意印章的名字不能重名,否則簽章會失敗。在多個印章的情況下,先蓋的印章能夠驗證文檔里面的內(nèi)容有沒有被修改,也能夠知道整個PDF文檔其實是被修改過,因為加了后面的簽章對象。
此處使用的數(shù)字證書,如果是正式面向外部的文檔,那肯定要是第三方CA發(fā)放的正式數(shù)字證書,需要花錢申請購買,每個證書都有其有效期。如果是內(nèi)部資料,倒是可以使用內(nèi)部認可的自簽名證書。
以上幾個部分結(jié)合,基本上可以實現(xiàn)無紙化電子文檔(PDF)格式的修改,以及文檔的防偽造,還能記錄有誰授權(quán)同意的這個文檔,這樣就和實際紙質(zhì)文檔具有了相同的效果,隨著信息化,自動化技術(shù)的提高,相信這將是辦公環(huán)境升級的必經(jīng)之路。
總結(jié)
以上是生活随笔為你收集整理的java 电子签章_PDF开发+电子签章,如何实现真正地脱离硬件的无纸化办公体验(实战篇)?...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: U分布、T分布、z分位数
- 下一篇: [练习]QQ登陆界面-测试用例的编写