Data Mailer Finishing Touches
While this Data Mailer script is running, Acrobat will not respond to the user's input, and they may get confused. So, we want to show an hourglass. This can be done by adding one line at the beginning of our DataMailer() function:
w=acrobat.waitcursor()
This turns the mouse cursor into an hour glass. When our function returns, w passes out of scope and is destroyed, which turns the mouse cursor back into a pointer.
It would also be nice to display the progress of our script to the user using Acrobat's status bar. While this isn't important for our short little script that runs quickly, it is very important for larger, slower scripts.
PDF Snake provides a very simple mechanism to display status: the prange(). This function works exactly like Python's xrange() function, except that as elements are accessed, Acrobat's status bar is updated. Also, you can pass any sequence into prange(), and it will serve as a wrapper. So, just change two lines in the DataMailer() function to use prange():
docNew[:]=acrobat.prange(doc[0:1]*len(tupData))foriinacrobat.prange(len(tupData)):
And finally, now that we have thoroughly tested our code, we don't want to show the output page anymore. We can turn that off with this line:
debugOutput=0
All together, the final version of our script looks like this:
importacrobatimportsysimportos.pathfromNupimportFitSlot debugOutput=0# FORMAT:# NAME, FEATURE1, FEATURE2, FEATURE3, FEATURE4,# FEATURE5, FEATURE6, PICTUREFILEdata=(('Jeffrey','3 Bedrooms','2 Bathrooms','A Swimming Pool','','','','house1.pdf'),('Gary','5 Large Bedrooms','3 Bathrooms','3-Car Garage',"Lot's of Shady Trees",'Satelite Dish','Hot Tub','house2.pdf'))defMakeSubsDictionary(data):dictSubs={'/N':data[0],'/F1':data[1],'/F2':data[2],'/F3':data[3],'/F4':data[4],'/F5':data[5],'/F6':data[6]}returndictSubsdefFindTutorialFile(sFileName):sThisScriptFilePath=sys.argv[0]sTutorialDirectory=os.path.split(sThisScriptFilePath)[0]returnos.path.join(sTutorialDirectory,sFileName)defAddHouseToPage(page,sHouseFile):doc=acrobat.documentOpen(sHouseFile)# this is the rect where we want to put the picture of the houserectSlot=acrobat.rect(422,180,180,10)matrixSlot=FitSlot(page.inverseMatrix*rectSlot,doc[0].cropBox*doc[0].defaultMatrix)doc[0].contentsCopyToPage(page,matrixSlot*doc[0].defaultMatrix)doc.close()defDataMailer(sTemplateFile,tupData):w=acrobat.waitcursor()doc=acrobat.documentOpen(sTemplateFile)docNew=acrobat.documentNew()docNew[:]=acrobat.prange(doc[0:1]*len(tupData))foriinacrobat.prange(len(tupData)):dictSubs=MakeSubsDictionary(tupData[i])docNew[i].textrunReplace(dictSubs)AddHouseToPage(docNew[i],FindTutorialFile(tupData[i][7]))returndocNew doc=DataMailer(FindTutorialFile('template.pdf'),data)doc.forceVisible()
Now all that's left to do is to add a menu item to the PDFSnake menu to invoke our script.