Use ABCpdf to generate pdfs of multi-paged html documents
March 06, 2008
Most Popular | ASP | IIS Management | Javascript | Snippets | Web Building

I maintain a library of learning modules which are constantly under development and revision. Our users often want PDFs to print out or view off-line, but we can't maintain up-to-date PDF's of each module manually. We needed a way to make on-demand PDFs of whatever the current state of the module is when the pdf is requested.

After looking at many pdf solutions I settled on "ABCpdf ASP 6.0" by WebSuperGoo.com.

ABCpdf has the advantages of fairly low cost (about $400.00 for one server, or FREE if you link back to them), a better HTML-rendering engine than most, and an easy to learn API, so you can write custom dynamic PDF applications.


Ads by Google

Posted by ellen at March 06, 2008 10:19 PM

To dynamically generate our frameset-based modules, I needed a way to send the current page-list to the ASP script that would do the interfacing with ABCpdf.

A typical module is shown below.


In the toolbar at the top of each module, there is a PDF button.

Picture%2017.jpg

Clicking the button submits a form with fields containing a list of all the pages in the module, and the path to the module. ABCpdf uses this information to generate an image for every page. It does a very good job of rendering the HTML, complete with all the styles.

The HTML for the form containing the PDF button is shown below. The form field containing the list of pages is populated by a javascript that runs when the page loads so that it always contains the most current list, since the list can change while the module is being read depending on user interactions.

<form id="pdfForm" action="http://myserver.com/abcpdf.asp" method="post" target="_blank" name="pdfForm">
<a id="headerPDF" title="Create a printable PDF of this entire module. (takes time, please wait)" onclick="document.pdfForm.submit();" href="#">
<img id="pdfBtn" width="46" height="44" border="0" onmouseover="MM_swapImage('pdfBtn','','images/header/over/pdf_btn.jpg',1)" onmouseout="MM_swapImgRestore()" name="pdfBtn" alt="Download a Printable PDF of this module" src="http://thedesignspace.net/master/template/images/header/up/pdf_btn.jpg"/>
</a>
<input type="hidden" value="http://myserver.com/learningmodule/page01.htm" name="uPath"/>
<input type="hidden" value="page01.htm;page02.htm;page03.htm;page04.htm;page05.htm;page06.htm;page07.htm;page08.htm;page09.htm;page10.htm;page11.htm;page12.htm;page13.htm;page14.htm;page15.htm;page16.htm;page17.htm;page18.htm;page19.htm;page20.htm;page21.htm;scorePage.htm;" name="uUrl"/>
</form>

The code for the receiving page "abcpdf.asp" is shown below.

<% @Language="VBScript" %> <% Option Explicit Server.ScriptTimeout =500 %> <html> <body>

<% 'function to randomize a number Function RandomNumber(intHighestNumber) Randomize RandomNumber = Int(Rnd * intHighestNumber) + 1 End Function

Dim theDoc, i, theID, theData Dim theURLs() Dim inti Dim x, w, h, l, b Dim strPath Dim strValue dim intFind dim id Set theDoc = Server.CreateObject("ABCpdf6.Doc") theDoc.HtmlOptions.BrowserWidth = 1300 ' apply a rotation transform w = theDoc.MediaBox.Width h = theDoc.MediaBox.Height l = theDoc.MediaBox.Left b = theDoc.MediaBox.Bottom theDoc.Transform.Rotate 90, l, b theDoc.Transform.Translate w, 0

' rotate our rectangle theDoc.Rect.Width = h theDoc.Rect.Height = w

inti=0 i=1 'loop thru' the form elements and assign the url to the array elements and increment array each time for each x in request.form 'look for the field with the url in it concatenated if left(x, 4) = "uUrl" then strValue=request.form(x) intfind = instr(strValue,";") 'each url is separated by a ; look for that while intfind>0 'parse each item in the url redim preserve theURLs(i+1)'save the array theURLs(i) = strPath & left(strValue,intfind-1) & "?lll=" & RandomNumber(10) strValue=right(strValue,len(strValue)-intfind) 'new string is old string cut off intfind = instr(strValue,";") i=i+1 'increment array index wend elseif x="uPath" then strPath=request.form(x) intFind = instrrev(strPath,"/") 'look backwords..from end of string strPath=left(strpath,intFind) end if next

 

For i = (LBound(theURLs)+1) To (UBound(theURLs)-1) theDoc.Page = theDoc.AddPage() id = theDoc.AddImageUrl(theURLs(i)) Do While theDoc.Chainable(id) theDoc.Page = theDoc.AddPage() id = theDoc.AddImageToChain(id)

Loop
Next

theID = theDoc.GetInfo(theDoc.Root, "Pages")
theDoc.SetInfo theID, "/Rotate", "90"


For i = 1 To theDoc.PageCount
theDoc.PageNumber = i
theDoc.Flatten
Next


theData = theDoc.GetData()
Response.Clear
Response.ContentType = "application/pdf"
Response.AddHeader "content-length", UBound(theData) - LBound(theData) + 1
Response.AddHeader "content-disposition", "attachment; filename=MLearning.PDF"
Response.BinaryWrite theData
theDoc.Clear
%>


</body>
</html>

The resulting PDF of the module looks like this.

We chose to have ABCpdf render the HTML pages into landscape orientation (11" wide), since webpages can be a little wider than 8-1/2 x 11, and we got better results from this size.


Ads by Google

3 Comments

Ellen!
You have saved my life! I have been trying to do this for yonks and was having a hard time.
Thank you so very much.

Ellen nice tut. Is the template still available ? The download link doesn't seem to work.


Ads by Google

 RSS   |   Contact Me


Ads by Google