Fill PDF form and stamp programmatically

** 方法一:利用HTML自行創建PDF **

HTML製作表單很容易,HTML畫面轉PDF也很容易,但是當你要轉出的PDF內容格式很複雜時,刻HTML卻不那麼容易

例如這種

Pizza-Hut-Job-Application-Form-550x4942-550x494.png

或這種


Casual-Employee-Contract-Form.jpg

這種表格很明顯是為手寫而設計的,真的電子化的表單,根本不需要這麼複雜。而很不幸地,正式場合常常會遇到這種情況,而且對方也不太可能改變他們慣用的表單格式。這種複雜的表格要用HTML去刻真是挺累,刻完後轉換時格式會不會跑掉也是個大問題,總之看上去是條荊棘之路,再找找有沒有別的辦法。

** 方法二:解析PDF檔,再用PDF語法填入資料 **
有些工具可以幫你解析出PDF檔的內容,包括欄位、頁面尺寸、頁數...等等,例如

pdftk file.pdf dump_data

但不幸的是,很多時候會拿不到,或許因為該PDF是掃瞄而來,又或者是其他,反正我試了幾個總有些PDF拿不到表格欄位,也只能暫時先放棄這條路了。

方法三:合成PDF檔

這是最土炮的做法,但目前是最有效的。就是創造一個全新的PDF檔案,然後跟原本的底稿合成一個新的PDF檔,有點像兩張圖片疊起來變成第三張圖片。

優點是不用管底稿的格式,表格再複雜也無所謂,壓文字、圖片都沒問題,缺點也很明顯,只能透過x, y座標決定位置,像編輯圖片那樣。

安裝pdftk

Install pdftk first.

找到x, y座標

有了底稿,還必須知道要把文字或圖片壓在哪個位置,目前我找不到任何PDF閱讀器有提供座標的,所以有點hack

先用pdftk file.pdf dump_data找到頁面的長寬

安裝gimp,用gimp打開檔案,然後輸入頁面長寬,然後左下方就會顯示PDF頁面裡滑鼠的x,y座標。

用程式創建PDF檔

以nodejs為例,利用pdfkit套件,請自行google一下教學。

這邊的重點是,必須指定中文字體,才能夠正確產生中文,否則會是亂碼。不管是自己去download還是用系統內建的都行,建議用.ttf格式,官方說明有支援.ttc但我試不出來,用.ttf簡單一些。

ps. ttc是許多ttf檔的collection,為字型家族的集合(light, medium, bold....等等),使用ttc時,還必須額外指定明確的font名稱,但就是這個font名稱我根本不知道怎麼取得,用OSX的font book裡的名稱或是cmd+i裡顯示的font name也沒用,總之讓事情簡單一點,直接載一個中文ttf檔比較快。

懷源黑體不錯

app.js

const fs = require('fs')
const PDFDocument = require('pdfkit')
const pageOption = {
    size: [595.32, 842.04],
    margins: {
        top: 0,
        bottom: 0,
        left: 0,
        right: 0
    }
}
const doc = new PDFDocument(pageOption)
doc.pipe(fs.createWriteStream('text.pdf'))

doc.font('./KaiGenGothicTW-Medium.ttf') // 選個中文字體
    .fontSize(12)
    .text('劉德華', 148, 182)
    .text('A122000999', 476, 184, {width: 80})
    .text('0982333888', 148, 207)
    .text('75', 475, 207)
    .text('06', 504, 207)
    .text('05', 531, 207)
    .text('台北市中正區天堂路100巷82號', 148, 232)
doc.image('./stamp.png', 520, 150, { fit: [50, 50] })
    .rect(520, 150, 50, 50)

doc.end()

run

node app.js 
pdftk background.pdf multistamp text.pdf output merge.pdf;

注意

pdfkit有個bug,如果文字過長被自動wrap而此時剛好又在margin邊上要在wrap一次,就會進入無窮迴圈,建議把margin都設為0。

Nice Reference

PDFNetJS

https://blog.pdftron.com/2015/11/10/pdfnetjs-html5-pdf-viewer-and-editor/
showcase(also iOS, Android): https://www.xodo.com/#

adobe solution

https://forums.adobe.com/thread/741050

iText

http://itextpdf.com/
https://www.codeproject.com/Tips/679606/Filling-PDF-Form-using-iText-PDF-Library

Programatically Filling Out PDFs in Java
http://www.daedtech.com/programatically-filling-out-pdfs-in-java/

pdftk

https://superuser.com/questions/540388/how-can-i-stamp-every-page-of-a-pdf-except-the-first-one
more in detail: https://mitcho.com/blog/how-to/stamp-pdfs/
doc: https://www.pdflabs.com/tools/pdftk-server/
https://www.pdflabs.com/docs/pdftk-man-page/#dest-op-dump-data-fields-utf8

pdf-filler

server written by ruby, under the hood using pdftk
https://github.com/GSA/pdf-filler

stackoverflow
add stamp to pdf

C#
-http://www.debenu.com/kb/programmatically-add-watermark-stamp-pdf/

php
https://stackoverflow.com/questions/9705009/how-to-add-an-overlay-stamp-to-a-pdf-file-in-php

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • 提問的智慧 How To Ask Questions The Smart Way Copyright © 2001...
    Albert陈凯阅读 2,029评论 0 8
  • 为何叫做 shell ? shell prompt(PS1) 与 Carriage Return(CR) 的关系?...
    Zero___阅读 3,106评论 3 49
  • 第二章 爆笑愚人节 清晨,言志中学校门口尖叫声响起一波又一波。原因无它,今天是愚人节,是吓死...
    独孤无痕阅读 251评论 0 0
  • 我那时已经忘了什么皇宫的条条框框,只想欢欢喜喜的嫁给他,所以,我打算赶紧回府,找我哥哥,免得他担心。我去师父那里牵...
    Holyme阅读 164评论 0 0
  • 自身病痛与亲人离去的痛苦是真实的,其它痛苦并不是真实的。别人的眼光、世俗的看法并不重要,自己的内心感觉最重要...
    煜楠2016阅读 205评论 0 0