TexasSwede
texasswede@gmail.com
  • About this blog
  • My Website
  • My Resume
  • XML Export Tool
  • Photos

Lotusscript Class for generating PDF files using N2PDF

Posted on November 13, 2010 by Karl-Henry Martinsson Posted in Old Blog Post

To make it easy to implement N2PDF in my applications/agents, I created a simple class, which I put in a script library called Class.PDF. Most of the code for teh actual PDF generation was taken straight from the example provided with the product.

In addition to the actual PDF creation, I also added functions to send the PDF file to a physical printer, and to send the PDF file to our internal document imaging system. I have removed the code for the latter, as it is very specialized code, calling a custom COM object we built, etc.

To send the PDF file to the printer, Acrobat Reader 9.0 is installed on the server (or client, depending on where the code is being executed). Due to limitations in AcroRD32.exe (it is not closing after it finish printing), I am using Acrobat Wrapper (AcroWrap.exe) from bioPDF.
You may also notice that I check two environment variables, this is to detect if the code is running on a 32-bit or 64-bit version of Windows.

I can not take credit for the ShellAndWait() function, I downloaded the code long ago from somewhere. It is used instead of the LotusScript Shell() function, and it will sit and wait until the called program finished executing before it continues.

Option Public
Option Declare
%INCLUDE "N2PDFDEF.SCR"

' *** Used for ShellAndWait()
Type STARTUPINFO
	cb As Long
	lpReserved As String
	lpDesktop As String
	lpTitle As String
	dwX As Long
	dwY As Long
	dwXSize As Long
	dwYSize As Long
	dwXCountChars As Long
	dwYCountChars As Long
	dwFillAttribute As Long
	dwFlags As Long
	wShowWindow As Integer
	cbReserved2 As Integer
	lpReserved2 As Long
	hStdInput As Long
	hStdOutput As Long
	hStdError As Long
End Type

' *** Used for ShellAndWait()
Type PROCESS_INFORMATION
	hProcess As Long
	hThread As Long
	dwProcessID As Long
	dwThreadID As Long
End Type


' *** Used for ShellAndWait()
Declare Function WaitForSingleObject Lib "kernel32" _
(Byval hHandle As Long, Byval dwMilliseconds As Long) As Long
Declare Function CreateProcessA Lib "kernel32" _
(Byval lpApplicationName As Long, Byval lpCommandLine As String, _
Byval lpProcessAttributes As Long, Byval lpThreadAttributes As Long, _
Byval bInheritHandles As Long, Byval dwCreationFlags As Long, _
Byval lpEnvironment As Long, Byval lpCurrentDirectory As Long, _
lpStartupInfo As STARTUPINFO, _
lpProcessInformation As PROCESS_INFORMATION) As Long
Declare Function CloseHandle Lib "kernel32" _
(Byval hObject As Long) As Long
Const NORMAL_PRIORITY_CLASS = &H20&
Const INFINITE = -1&	
Const tmpPath = "C:\N2PDF\"	' Directory to store files in


' *** Main class to create and print PDF files
Class PDF
	Private JobID As Long
	Private IsOnServer As Integer
	Public PrinterName As String
	Public testmode As Integer
	
	Public Sub New()
		Dim session As New NotesSession
		Dim txtrow As String
		Dim cmd As String
		Dim res As Integer
		' *** Fix registry settings for Acrobat 9.0 to not shrink/fit page
		Open tmpPath & "AcrobatSettings.reg" For Output As #1
		Print #1, "Windows Registry Editor Version 5.00"
		Print #1, ""
		Print #1, "[HKEY_CURRENT_USER\Software\Adobe\Acrobat Reader\9.0\AVGeneral]"
		Print #1, |"bprintExpandToFit"=dword:00000000|
		Print #1, |"iprintScaling"=dword:00000001|
		Close #1
		cmd = |regedit /s | & tmpPath & |AcrobatSettings.reg|
		res =  ShellAndWaitFunc(cmd)
		Kill tmpPath & "AcrobatSettings.reg"
		Me.IsOnServer = session.IsOnServer()	' True if code is running on server
		If InitN2PDF() = False Then
			Call printmsg( "Failed to initialize N2PDF. Exiting.")			
			Exit Sub
		End If
		testmode = False
	End Sub

	
	Sub Delete
		' *** Destructor
	End Sub

	
	' *** This function print to console on server but display message box if running in client
	Private Sub PrintMsg(text As String)
		If Me.IsOnServer Then
			Print text
		Else 
			Msgbox text,,"Class.PDF:" & Getthreadinfo(LSI_THREAD_CALLPROC)
		End If
	End Sub

	
	Private Function InitN2PDF() As Integer
		Me.JobID = N2PDFInit (0)
		If ( Me.JobID < 0 ) Then	' Make sure N2PDF was initialized successfully
			InitN2PDF = False
			Exit Function
		End If
		' *** Set N2PDF options
		Call N2PDFSetGlobalOption( N2PDFGLOBALOPTION_SHOW_MESSAGES, _
		N2PDFVALUE_False,"" )
		Call N2PDFSetOption ( Me.JobID, _
		N2PDFOPTION_SYSTEM_LAUNCH_VIEWER, N2PDFVALUE_FALSE, "" )
		Call N2PDFSetOption ( Me.JobID, _
		N2PDFOPTION_NOTES_LINK_DOC_MODE, N2PDFVALUE_NOTES_LINK_MODE_IMAGE_LINK, "" )
		Call N2PDFSetOption ( Me.JobID, _
		N2PDFOPTION_PDF_COMPRESSION_MODE, N2PDFVALUE_COMPRESSION_DEFLATE, "" )
		Call N2PDFSetOption ( Me.JobID, _ 
		N2PDFOPTION_PARAGRAPH_FONT_NAME, "Arial", N2PDFVALUE_DEFAULT_PARAGRAPH_NAME )
		Call N2PDFSetOption ( Me.JobID, _
		N2PDFOPTION_PARAGRAPH_FONT_SIZE, "8", N2PDFVALUE_DEFAULT_PARAGRAPH_NAME )
		Call N2PDFSetOption ( Me.JobID, _
		N2PDFOPTION_PARAGRAPH_FONT_COLOR, N2PDFVALUE_COLOR_BLACK, _
		N2PDFVALUE_DEFAULT_PARAGRAPH_NAME )
		Call N2PDFSetOption ( Me.JobID, _
		N2PDFOPTION_FORMAT_DELETE_TRAILING_SPACE, N2PDFVALUE_True, "" )
		Call N2PDFSetOption ( Me.JobID, _
		N2PDFOPTION_PAGE_FORMAT_STANDARD,N2PDFVALUE_PAGEFORMAT_LETTER, "" )		
		Call N2PDFSetOption ( Me.JobID, N2PDFOPTION_EXPORT_TABLE_GAP, "1", "" )
		InitN2PDF = True
	End Function

	
	Public Function AddDocToPDF(doc As NotesDocument)
		' *** Add doc to the PDF we are processing. 
		' *** Use trailing CRLF to avoid blank page at the end
		Call N2PDFAddRTContent ( JobID, N2PDFVALUE_CONTENT_BODY, _
		N2PDFVALUE_CRLF_AFTER, doc.ParentDatabase.Server, _
		doc.ParentDatabase.FilePath, doc.UniversalID, "")
	End Function

	
	Public Sub AddPageBreak()
		Call N2PDFAddContent( Me.JobID, N2PDFVALUE_CONTENT_BODY, _
		N2PDFVALUE_PAGEBREAK_AFTER," " )
	End Sub

	
	Public Sub AddLineBreak()
		Call N2PDFAddContent( Me.JobID, N2PDFVALUE_CONTENT_BODY, _
		N2PDFVALUE_CRLF_AFTER," " )
	End Sub

	
	Public Function CreatePDF(outfile As String)
		If Fulltrim(outfile) = "" Then
			Call PrintMsg("No filename provided provided for [outfile].")
			Exit Function
		End If
		Call N2PDFProcess ( Me.JobID, outfile, 0 )
	End Function
	
	
	Public Sub SetPrinter(printername As String)
		Me.PrinterName = printername
	End Sub
	

	Public Function PrintPDF(Byval filename As String) As Integer
		Dim printer As String
		Dim prg As String
		Dim cmd As String
		Dim success As Long
		Dim dirtemp As String
		Dim path As String 
		
		If Environ$("ProgramFiles(x86)") <> "" Then
			path = Environ$("ProgramFiles(x86)")
		Elseif Environ$("ProgramFiles") <> "" Then
			path = Environ$("ProgramFiles")
		Else
			path = "c:\Program Files"
		End If	
		dirtemp = path & "\bioPDF\Acrobat Wrapper\"
		prg = dirtemp & "acrowrap.exe"
		If Dir$(prg) = "" Then
			' *** File was  not found, we can't print to printer without it.
			Print "Failed to locate acrowrap.exe (bioPDF Acrobat Wrapper)."
			PrintPDF = -1
			Exit Function
		End If		
		prg = |"| & prg & |"|	' Add double quotes around file name
		If Me.PrinterName<>"" Then
			printer = " " & Me.PrinterName
		Else
			printer = ""	' This will use default printer
		End If
		filename = |"| & filename & |"|
		cmd = prg & | /t | & filename & printer
		success = ShellAndWaitFunc(cmd)
		PrintPDF = Cint(success)
	End Function
	

	Private Function ShellAndWaitFunc(Byval RunProg As String) As Long
		Dim RetVal As Long
		Dim RetvalClose As Long
		Dim proc As PROCESS_INFORMATION
		Dim StartInf As STARTUPINFO
		StartInf.cb = Len(StartInf)
	     ' Execute the given path
		RetVal = CreateProcessA(0&, RunProg, 0&, 0&, 1&, _
		NORMAL_PRIORITY_CLASS, 0&, 0&, StartInf, proc)
	     ' Disable this app until the shelled one is done
		RetVal = WaitForSingleObject(proc.hProcess, INFINITE)
		RetValClose = CloseHandle(proc.hProcess)
		ShellAndWaitFunc = RetValClose
	End Function
End Class

Here is a small code snippet showing how to call the class. Enjoy!

Option Public
Option Declare
Use "Class.PDF"

Dim pdf As PDF
Dim success As Integer
dim PDFfile As String

...set doc here
PDFfile = doc.UniversalID & ".pdf"	' Create file name based on document UNID

Set pdf = New PDF()		' Initialize PDF object
pdf.TestMode = False	' Set PDF object to test mode if desired
pdf.PrinterName ="CRP_Accounting_Color"	' Set the printer name for printouts
Call pdf.AddDocToPDF( doc )
Call pdf.CreatePDF( PDFfile )
success= pdf.PrintPDF( PDFfile )
If success = 1 Then
	MsgBox "Successfully printed " & PDFfile & "."
End If

 

« I am not Amish…
Fall in Texas »

Leave a comment Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Stack Exchange

profile for Karl-Henry Martinsson on Stack Exchange, a network of free, community-driven Q&A sites

Recent Posts

  • Domino 14 is now available
  • Domino 14 Early Access Program
  • Announced: Engage 2024
  • Integrate Node-RED with Notes and Domino
  • Notes and Domino v12 is here!

Recent Comments

  • Theo Heselmans on Announced: Engage 2024
  • Lotus Script Multi-thread Message Box [SOLVED] – Wanted Solution on ProgressBar class for Lotusscript
  • Viet Nguyen on Keep up with COVID-19 though Domino!
  • Viet Nguyen on Keep up with COVID-19 though Domino!
  • Mark Sullivan on Looking for a HP calculator? Look no further!

My Pages

  • How to write better code in Notes

Archives

  • December 2023 (1)
  • October 2023 (2)
  • September 2023 (1)
  • June 2021 (1)
  • April 2021 (2)
  • March 2021 (1)
  • August 2020 (3)
  • July 2020 (2)
  • April 2020 (2)
  • March 2020 (1)
  • December 2019 (2)
  • September 2019 (1)
  • August 2019 (2)
  • July 2019 (2)
  • June 2019 (3)
  • April 2019 (2)
  • December 2018 (1)
  • November 2018 (1)
  • October 2018 (5)
  • August 2018 (2)
  • July 2018 (3)
  • June 2018 (2)
  • May 2018 (1)
  • April 2018 (2)
  • March 2018 (1)
  • February 2018 (2)
  • January 2018 (4)
  • December 2017 (3)
  • November 2017 (2)
  • October 2017 (2)
  • September 2017 (1)
  • August 2017 (2)
  • July 2017 (6)
  • May 2017 (4)
  • February 2017 (1)
  • January 2017 (2)
  • December 2016 (2)
  • October 2016 (3)
  • September 2016 (4)
  • August 2016 (1)
  • July 2016 (2)
  • June 2016 (2)
  • May 2016 (3)
  • April 2016 (1)
  • March 2016 (4)
  • February 2016 (2)
  • January 2016 (4)
  • December 2015 (3)
  • November 2015 (2)
  • October 2015 (1)
  • September 2015 (2)
  • August 2015 (1)
  • July 2015 (5)
  • June 2015 (2)
  • April 2015 (2)
  • March 2015 (3)
  • February 2015 (2)
  • January 2015 (10)
  • December 2014 (1)
  • November 2014 (3)
  • October 2014 (3)
  • September 2014 (13)
  • August 2014 (6)
  • July 2014 (5)
  • May 2014 (3)
  • March 2014 (2)
  • January 2014 (10)
  • December 2013 (5)
  • November 2013 (2)
  • October 2013 (5)
  • September 2013 (4)
  • August 2013 (7)
  • July 2013 (3)
  • June 2013 (1)
  • May 2013 (4)
  • April 2013 (7)
  • March 2013 (8)
  • February 2013 (9)
  • January 2013 (5)
  • December 2012 (7)
  • November 2012 (13)
  • October 2012 (10)
  • September 2012 (2)
  • August 2012 (1)
  • July 2012 (1)
  • June 2012 (3)
  • May 2012 (11)
  • April 2012 (3)
  • March 2012 (2)
  • February 2012 (5)
  • January 2012 (14)
  • December 2011 (4)
  • November 2011 (7)
  • October 2011 (8)
  • August 2011 (4)
  • July 2011 (1)
  • June 2011 (2)
  • May 2011 (4)
  • April 2011 (4)
  • March 2011 (7)
  • February 2011 (5)
  • January 2011 (17)
  • December 2010 (9)
  • November 2010 (21)
  • October 2010 (4)
  • September 2010 (2)
  • July 2010 (3)
  • June 2010 (2)
  • May 2010 (3)
  • April 2010 (8)
  • March 2010 (3)
  • January 2010 (5)
  • November 2009 (4)
  • October 2009 (7)
  • September 2009 (1)
  • August 2009 (7)
  • July 2009 (1)
  • June 2009 (4)
  • May 2009 (1)
  • April 2009 (1)
  • February 2009 (1)
  • January 2009 (3)
  • December 2008 (1)
  • November 2008 (1)
  • October 2008 (7)
  • September 2008 (7)
  • August 2008 (6)
  • July 2008 (5)
  • June 2008 (2)
  • May 2008 (5)
  • April 2008 (4)
  • March 2008 (11)
  • February 2008 (10)
  • January 2008 (8)

Categories

  • AppDev (10)
  • Blogging (11)
    • WordPress (5)
  • Design (5)
    • Graphics (1)
    • UI/UX (2)
  • Featured (5)
  • Financial (2)
  • Food (5)
    • Baking (3)
    • Cooking (3)
  • Generic (11)
  • History (5)
  • Hobbies (10)
    • LEGO (4)
    • Photography (4)
  • Humor (1)
  • IBM/Lotus (178)
    • #Domino2025 (14)
    • #DominoForever (8)
    • #IBMChampion (46)
    • Administration (7)
    • Cloud (7)
    • CollabSphere (9)
    • Community (49)
    • Connect (33)
    • ConnectED (12)
    • Connections (3)
    • HCL (15)
    • HCL Master (1)
    • IBM Think (1)
    • Lotusphere (46)
    • MWLUG (25)
    • Notes/Domino (99)
      • Domino 11 (7)
    • Sametime (8)
    • Verse (14)
    • Volt (3)
    • Watson (6)
  • Life (8)
  • Microsoft (7)
    • .NET (2)
    • C# (1)
    • Visual Studio (1)
  • Movies (3)
  • Old Blog Post (259)
  • Personal (23)
  • Programming (84)
    • App Modernization (11)
    • Formula (4)
    • Lotusscript (47)
    • NetSuite (4)
      • SuiteScript (3)
    • node.js (4)
    • XPages (4)
  • Reviews (9)
  • Sci-Fi (4)
  • Software (24)
    • Flight Simulator (2)
    • Games (4)
    • Open Source (2)
    • Utilities (6)
  • Technology (37)
    • Aviation (3)
    • Calculators (2)
    • Computers (6)
    • Gadgets (7)
    • Mobile Phones (7)
    • Science (3)
    • Tablets (2)
  • Travel (7)
    • Europe (1)
    • Texas (2)
    • United States (1)
  • Uncategorized (16)
  • Web Development (50)
    • Frameworks (23)
      • Bootstrap (14)
    • HTML/CSS (12)
    • Javascript (32)
      • jQuery (23)

Administration

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

Tracking

Creeper
MediaCreeper
  • Family Pictures
© TexasSwede 2008-2014