Adobe PDF格式已經變成很多機構和公司進行跨平臺制表的通用媒體格式。盡管我不是這個產品的狂熱癡迷者,卻不得不接受這樣一個事實:用這個格式產生一個協定可能會比用Word還要好。
由于在一家雇用公司工作,我已經把我們所有早期的軟件寫成能在Internet上運行,這樣我們就能和小的子公司共享公用數據庫了。然而我們遇到的最大的問題就是制表。當一個申請人坐在信息站里在線填寫他們的就業申請時,我們如何取得當前的文檔(或申請等)?由于我們做了大量工作來獲取數據,我們還需要申請人手工填寫一份申請。
我試了各種辦法,但是看來都有一個很大的限制:
如果我能快速產生它,它就只能是一個HTML形式的衍生物,在打印時就會變得面目全非。如果設計的看起來美觀一些,它就會變得很慢。這是由于我選擇用RTF格式作為我的首選項,然后使用文件系統對象來完成基于模板的RTF文件,最后加入了我的信息。這個磁盤讀寫的過程會耗費很長時間。記住:我們這里不是在討論列表數據或者一個Excel電子表格。我們是想讓程序用我們自己的標志進行處理。
最后,我選擇了Adobe(很像一句廣告詞?——譯者)。我討厭它的瀏覽器所以希望自己不會和它糾纏上,然而它的格式看起來很不錯而且文件也不大。大部分用戶都在系統里裝上它,我們的客戶也不例外。
因此我一直在尋找把數據從HTML表單傳遞到PDF文件的方法。我試過使用Adobe表單,但是它不能真正有效運行,然后還要統計如何合并數據庫請求。這根本不是我想要的東西,我想直接把數據從我的HTML表單傳遞到數據庫,然后產生數據信息到PDF文件里作為瀏覽或打印。
最終我在UseNet發現了線索。一個叫Jeremy Hunter的提交的一個鏈接包含了我準備在這里講的很多東西——http://partners.adobe.com/asn/developer/acrosdk/forms.html。
首先必須在定義字段的工作站(不是服務器)上安裝有Adobe完全版。這個是一個指向Adobe Forms Acrobat Toolkit的鏈接,由此開始一切就容易了。
第一、下載這個套裝工具并把它解壓縮到指定目錄。
當你進行這一步操作時,你會發現所有源代碼都在VB或VC++中。我們這里不打算關注它,但是如果你需要代碼就在這里。
第二、注冊你的DLL。
有兩個DLL需要被復制到你的服務器上。一個在Visual Basic文件夾中叫fdfacx.dll,另一個在Visual C++文件夾中叫fdftk.dll。用regsvr32注冊fdfacx.dll文件。我把這兩個文件都放到c:winntsystem32下,并在當前路徑下輸入“regsvr32 fdftk.dll”。如果你遇到錯誤提示信息,請檢查確認這兩個文件確實在當前目錄下,沒有問題則進入下一步。
第三、建立表單。
我們將使用每個人對這個示范都很熟悉的表單。這在“http://www.irs.gov”隨意可得并為我們提供足夠的領域來展示我們能作的東西。
第四、定義Adobe表單字段。
在Adobe Acrobat中打開文檔后選擇表單工具,描述你的第一個表單字段(First Name)。
在你定義后它將讓你命名,我這里命名為“FirstName”。注意這里有幾個標準的附加格式選項,除了字體大小,我選擇進行合法性檢查和格式化我的ASP文檔。由于這是一個快速演示,我選擇跳過任何檢查,但是我將在客戶端的表單進行處理,并在傳遞變量前在服務端格式化ASP頁面。
繼續其他字段,每一個都要注意命名并可能格式化字體大小或屬性。
在服務器上保存你的修改。
第五、編寫ASP頁面。
在開始這一步之前你要注意到FDF套裝工具闡述的一個主要對象——“FDFApp.FDFApp”。它開放了許多方法,手冊上概述了其他的可能方法。我們主要關心兩個方法——fdfSetValue和fdfSetFile。接下來切入正題。
第六、沒有必要成為PDF專家,這是我目前的建議。套裝工具的用戶指導概述了所有方法,看上去在這個入門介紹之外還有很多可能的方法。就像你所看到的一樣,你可以很容易添加數據庫命令來收集數據或向數據庫記錄數據。
原作者簡介:
Ty Button就職于俄勒岡的一個名叫Cardinal Services的雇用公司。Cardinal Services公司曾被俄勒岡商業雜志評為1997和1998年度俄勒岡南部第一號雇用公司,同時被南海岸商業開發中心和美國銀行評為俄勒岡發展最快的公司。Button是MIS開發人員,也在網絡數據庫開發和生產過程自動化上花費了大部分時間
以下是英文原文
Creating a PDF with ASP
By Ty Button
print this article
email this article to a colleague
Introduction
Adobe's PDF format has become the lingua franca of cross-platform reporting for many agencies and companies. While I was no great fan of the product, I have to admit it probably does a better job of producing a compact document with loads of formatting than Word ever will.
Getting Started
Working for a staffing firm, I have written all of our front-end software to run over the Internet so we can share common databases with our smaller branch offices. The biggest problem we faced, however, was reporting. How do we get live documents (applications, etc.) to generate themselves when an applicant sits down at the kiosk and fills out their on-line employment application? While we're doing a great job of capturing the data, we still need an applicant to sign the application, W-4, etc.
I tried a number of things, but the limits seem to be:
If I could produce it fast, it was an HTML form derivative and looked terrible when printed.
If I could produce it looking right, it was clunky and slow. This is because I settled on RTF as my best initial option and ended up using the File System Object to write RTF files based on a template and parse my info into them. The disk reads and writes took their toll.
Remember, we抮e not talking about tabular data or an Excel spreadsheet. We want the application with our logo to be processed.
Finally, I settled on Adobe. I hate the viewer and wish I didn't have to mess with it. However, the formatting looks good and the files are thin. Most users have it on their system, and all my users do.
So I searched and searched for ways to pass data from HTML forms to PDF files. I tried using Adobe forms, but didn't really like working with the validation, etc., and then would still have to figure out how to incorporate the database calls. This wasn't at all what I wanted. I wanted to pass data directly from my HTML form to a database while generating the field data into the PDF file for display or printing.
Finally, there was a clue on UseNet. A link posted by Jeremy Hunter contained much of what I will address here. http://partners.adobe.com/asn/developer/acrosdk/forms.html
REQUIRED SOFTWARE
ADOBE (the full version) is required on the workstation defining the fields. (Not the server)
This is the link to the Adobe Forms Acrobat Toolkit. From there it was easy going.
Step 1. Download the toolkit and unzip it to your directory of choice.
When you do, you'll find that all the source code is included in VB and C++. We're not going to worry about that here, but the code is there if you need it.
Step 2. Register your dlls.
Two dlls need to be copied to your server. The first is in the Visual Basic sub folder and is named fdfacx.dll. The second is in the Visual C subfolder and is named fdftk.dll. Run refsvr32 on the fdfacx.dll file. It will take care of registering the other itself. I put both in c:\winnt\system32\ and from that directory typed regsvr32 fdftk.dll. If you get an error message, check to make sure both files are really there. If not, we're set to go.
Step 3. Create the form.
We'll use a form everyone is too familiar with for this demonstration - the W-4. This one is readily available on http://www.irs.gov and gives us enough fields to show what we can do.
<%@ Language=VBScript %>
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>
<BODY>
<H1>Adobe FDF Example</H1>
<FORM NAME=W4Help ACTION=W4.asp METHOD = POST>
<TABLE>
<TR>
<TD ALIGN=RIGHT VALIGN=TOP>First Name</TD>
<TD><INPUT TYPE=TEXT NAME=txtFirstName>
</TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=TOP>Middle Initial
</TD>
<TD><INPUT TYPE=TEXT NAME=txtMI>
</TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=TOP>LastName</TD>
<TD><INPUT TYPE=TEXT NAME=txtLastName>
</TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=TOP>Social</TD>
<TD><INPUT TYPE=TEXT NAME=txtSocial1 SIZE=3>-
<INPUT TYPE=TEXT NAME=txtSocial2 SIZE=2>-
<INPUT TYPE=TEXT NAME=txtSocial3 SIZE=2></TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=TOP>Street Address</TD>
<TD><INPUT TYPE=TEXT NAME=txtStreetAddress></TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=TOP>City
</TD>
<TD><INPUT TYPE=TEXT NAME=txtCity></TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=TOP>State</TD>
<TD><INPUT TYPE=TEXT NAME=txtState SIZE=2 MAXLENGTH=2></TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=TOP>Zip</TD>
<TD><INPUT TYPE=TEXT NAME=txtZip SIZE=10></TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=TOP>Filing Status</TD>
<TD>
<INPUT TYPE=RADIO NAME=radFilingStatus VALUE="1">Single
<BR>
<INPUT TYPE=RADIO NAME=radFilingStatus VALUE="2">Married
<BR>
<INPUT TYPE=RADIO NAME=radFilingStatus VALUE="3">
Married but withholding at the higher single rate.
<BR></TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=TOP>Allowances Claimed</TD>
<TD><INPUT TYPE=TEXT NAME=txtAllowances SIZE=2 MAXLENGTH=2> </TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=TOP>Additional amount to withhold (if any)</TD>
<TD><INPUT TYPE=TEXT NAME=txtAdditional SIZE=2 MAXLENGTH=2>
</TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=TOP>I want to file Exempt from Withholding
</TD>
<TD><INPUT TYPE=CHECKBOX NAME=chkExempt></TD>
</TR>
</TABLE>
<INPUT TYPE=SUBMIT>
</FORM>
</BODY>
</HTML>
Step 4. Define the Adobe form fields.
Open the document in Adobe Acrobat.
Click the form tool.
Paint your first form field (First Name).
As soon as you've defined it you are asked to name it. I named mine FirstName. Note that there are several additional formatting options. Other than font size, I choose to do my validation and formatting in my ASP document. As this is just a quick demo, I have opted to skip any validation. However, I would handle it on the client side in my form and any formatting server side in my ASP page before I pass the variables.
Continue with the remaining fields, naming each and possibly formatting the font size or attributes.
Save your work to wherever you want on your Web server.
Step 5. Write the ASP page.
Before you start, realize that there is one main object exposed by the FDF toolkit - "FDFApp.FDFApp." There are many methods exposed, and the manual outlines some other possibilities. We're mainly concerned with two methods, fdfSetValue and fdfSetFile. Here we go,
<%@ Language=VBScript %>
<% Response.Buffer = true%>
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<%
'
' Retrieve the user responses
'
FirstName = Request.form("txtFirstName")
MI = Request.form("txtMI")
LastName = Request.form("txtLastName")
SS1 = Request.form("txtSocial1")
SS2 = Request.form("txtSocial2")
SS3 = Request.form("txtSocial3")
StreetAddress = Request.form("txtStreetAddress")
City = Request.form("txtCity")
State = Request.form("txtState")
Zip = Request.form("txtZip")
FilingStatus = Request.form("radFilingStatus")
Allowances = Request.form("txtAllowances")
Additional = Request.form("txtAdditional")
Exempt = Request.form("chkExempt")
If Exempt = "on" Then
Exempt = "EXEMPT"
Else
Exempt = ""
End If
'
' Create an instance of the Object
'
Set FdfAcx = Server.CreateObject("FdfApp.FdfApp")
'
' Use the fdfApp to feed the vars
'
Set myFdf = FdfAcx.FDFCreate
'
' Stuff the variables
'
myFdf.fdfsetvalue "FirstName", FirstName, false
myFdf.fdfsetvalue "MI", MI, false
myFdf.fdfsetvalue "LastName", LastName, false
myFdf.fdfsetvalue "SS1", SS1, false
myFdf.fdfsetvalue "SS2", SS2, false
myFdf.fdfsetvalue "SS3", SS3, false
myFdf.fdfsetvalue "StreetAddress", StreetAddress, false
myFdf.fdfsetvalue "City", City, false
myFdf.fdfsetvalue "State", State, false
myFdf.fdfsetvalue "Zip", Zip, false
If FilingStatus = 1 Then
MyFdf.fdfsetValue "StatusSingle", "X", false
End If
If FilingStatus = 2 Then
MyFdf.fdfsetValue "StatusMarried", "X", false
End If
If FilingStatus = 3 Then
MyFdf.fdfsetValue "MarriedBut", "X", false
End If
myFdf.fdfsetvalue "Allowances", Allowances, false
myFdf.fdfsetvalue "Additional", Additional, false
myFdf.fdfsetvalue "Exempt", Exempt, false
'
' Point to your pdf file
'
myFDF.fdfSetFile "http://www.servername.com/workorder/w4.pdf"
Response.ContentType = "text/html"
'
' Save it to a file. If you were going to save the actual file past the point of printing
' You would want to create a naming convention (perhaps using social in the name)
' Have to use the physical path so you may need to incorporate Server.mapPath in
' on this portion.
'
myFDf.FDFSaveToFile "C:\inetpub\wwwroot\workorder\CheckThis.fdf"
' Now put a link to the file on your page.
Response.Write "<a href=http://www.servername.com/workorder/CheckThis.fdf>pdf</A>"
'
' Close your Objects
'
myfdf.fdfclose
set fdfacx = nothing
%>
Conclusion
Without having to be an expert at FDF or PDF, this is my answer for the moment. The users?guide that comes with the toolkit outlines all of the methods and looks like it has many possibilities beyond this rudimentary introduction. As you can see, you could just as easily add database commands to collect the data and log it to a database.
About the Author
Ty Button is employed by Cardinal Services, Inc., a staffing firm in Oregon. Cardinal Services has been named the #1 Staffing Firm in Southern Oregon for both 1997 and 1998 by Oregon Business Magazine, as well as Oregon's Fastest Planned Growth Company by the South Coast Business Development Center and U.S. Bank. Button is the MIS, but spends the bulk of his time on Web-database development and process automation. He can be reached at mailto:ty@ty-button.com.