PDF Exporter Class
Do you need some journal code to export your drawings as a .pdf file? A quick search on this site will yield this journal. That journal's only purpose in life is to export drawing sheets to a pdf file. It works as advertised, but if exporting a pdf is only a part of your project; incorporating this code can be difficult. To improve usability, I have converted the code to a more programmer friendly, self-contained class. I used this opportunity to clean up the code and add a few new features. The code was tested with NX 7.5, 8, 8.5, and 9.
Properties and Methods
Public Properties |
|||
Name |
Type |
Default Value |
Description |
ExportSheetsIndividually |
Boolean {read/write} |
False |
Flag indicating whether each sheet in the drawing should be output to an individual pdf file. When set to True, the output pdf file name will be the same as the sheet name. If the PreliminaryPrint flag is set to True, the name format will be [fileName_sheetName]{_preliminary}.pdf. |
ExportToTc |
Boolean {read/write} |
False |
flag indicating that the pdf should be output to the TC dataset, False value = output to filesystem |
IsTcRunning |
Boolean {read only} |
n/a |
True if NX is running under TC, false if native NX |
OpenPdf |
Boolean {read/write} |
False |
flag to indicate whether the journal should attempt to open the pdf after creation |
OutputFolder |
String {read/write} |
path to the output folder native: folder of specified part TC: user's Documents folder |
|
OutputPdfFileName |
String {read/write} |
Name of output pdf file (if exporting to filesystem); may contain the full path information or simply the desired base name of the pdf file. The full pdf file name will be built from the specified OutputFolder and OutputPdfFileName. The default value is: native: <folder of current part>\<part name>_<part revision>{_sheet name}{_preliminary}.pdf TC: <current user's Documents folder>\<DB_PART_NO>_ <DB_PART_REV>{_preliminary}.pdf |
|
OverwritePdf |
Boolean {read/write} |
True |
flag indicating that the pdf file should be overwritten if it already exists; currently only applies when exporting to the filesystem |
Part |
NXOpen.Part {read/write} |
N/A |
part that contains the drawing sheets of interest |
PartFilePath |
String {read only} |
native NX part files, the path to the part file TC: N/A |
|
PartNumber |
String {read only} |
native NX part files: part file name TC files: value of DB_PART_NO attribute |
|
PartRevision |
String {read only} |
native NX part files: value of part "Revision" attribute, if present TC files: value of DB_PART_REV |
|
PreliminaryPrint |
Boolean {read/write} |
False |
flag indicating that the pdf should be marked as an "preliminary"; when set to True, the output file will be named <filename>_preliminary.pdf |
SheetCount |
Integer {read only} |
N/A |
integer indicating the total number of drawing sheets found in the file |
ShowConfirmationDialog |
Boolean {read/write} |
False |
Flag indicating whether to show the user a confirmation dialog after pdf is created. If set to True and ExportToTc = False, user will be asked if they want to open the pdf file. If user chooses "Yes", the code will attempt to open the pdf with the default viewer |
SkipBlankSheets |
Bolean {read/write} |
True |
Flag indicating that any blank drawing sheets should not be output to the pdf file. When set to True (the default), the part must be set to the display part for the check to successfully complete. |
SortSheetsByName |
Boolean {read/write} |
True |
flag indicating that the sheets should be sorted by name before output to pdf |
TextAsPolylines |
Boolean {read/write} |
False |
flag indicating that text objects should be output as polylines instead of text objects |
UseWatermark |
Boolean {read/write} |
False |
flag indicating that watermark text should be applied to the face of the drawing |
WatermarkAddDatestamp |
Boolean {read/write} |
True |
flag indicating that today's date should be added to the end of the watermark text |
WatermarkText |
String {read/write} |
"PRELIMINARY PRINT NOT TO BE USED FOR PRODUCTION" |
watermark text to use |
Public Methods |
|
New () |
Create a new instance of the PDF Exporter class |
New (byVal thePart as Part) |
Create a new instance of the PDF Exporter class, specify the part to use at the time of creation. |
PickExportFolder () |
displays a FolderPicker dialog box, the user's choice will be set as the output folder |
PromptPreliminaryPrint |
displays a yes/no dialog box asking the user if the print should be marked as preliminary if user chooses "Yes", PreliminaryPrint and UseWatermark properties are set to True |
SortDrawingSheets () |
Sorts the drawing sheets alphabetically by sheet name. |
SortDrawingSheets(ByVal customSortFunction As System.Comparison(Of NXOpen.Drawings.DrawingSheet)) |
Sorts the drawing sheets by the user supplied custom sort function e.g. myPdfExporter.SortDrawingSheets(AddressOf myCustomFunction). |
PromptWatermarkText () |
displays an input box prompting the user to enter text to use for the watermark if cancel is pressed, the default value is used if Me.UseWatermark = True, an input box will appear prompting the user for the desired watermark text. Initial text = Me.WatermarkText if Me.UseWatermark = False, calling this method will have no effect |
Commit () |
using the specified options, export the given part's sheets to pdf |
Usage Examples
The examples shown below omit the class code for clarity, they are only to demonstrate how to call the properties and methods of the class. For full examples that can be run as journals, download the zip file. The zip file contains the full examples and also the class code as an independent file for those of you who want to include it as part of your own compiled project. If you intend to run your code as a journal, you will need to copy and paste the class code into your journal file (see the example code in the zip file). One of the limitations of journal files is that all the code must be in the one journal file; including other classes works, but it can make for a large journal file when you are done.
Bare minimum
The following example takes advantage of many of the class' default values to keep the code concise.
Option Strict Off
Imports System
Imports System.IO
Imports System.Collections.Generic
Imports System.Windows.Forms
Imports NXOpen
Imports NXOpen.UF
Module NXJournal
Sub Main()
Dim theSession As Session = Session.GetSession
If IsNothing(theSession.Parts.Display) Then
MessageBox.Show("Active Part Required", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End If
Dim workPart As Part = theSession.Parts.Work
Dim myPdfExporter As New NXJ_PdfExporter
myPdfExporter.Part = workPart
Try
myPdfExporter.Commit()
Catch ex As Exception
MessageBox.Show("Error:" & ControlChars.CrLf & ex.GetType.ToString & " : " & ex.Message, "PDF export error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
myPdfExporter = Nothing
End Try
End Sub
End Module
'### Class code omitted for brevity
Interactive Version
The following version uses the interactive options to prompt the user for values such as output folder, watermark text, etc.
Option Strict Off
Imports System
Imports System.IO
Imports System.Collections.Generic
Imports System.Windows.Forms
Imports NXOpen
Imports NXOpen.UF
Module NXJournal
Sub Main()
Dim theSession As Session = Session.GetSession
If IsNothing(theSession.Parts.Display) Then
MessageBox.Show("Active Part Required", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End If
Dim workPart As Part = theSession.Parts.Work
Dim myPdfExporter As New NXJ_PdfExporter
myPdfExporter.Part = workPart
'$ prompt user for output folder
myPdfExporter.PickExportFolder()
'$ preliminary print?
myPdfExporter.PromptPreliminaryPrint()
'$ desired watermark text (if preliminary print)
myPdfExporter.PromptWatermarkText()
myPdfExporter.WatermarkAddDatestamp = True
'$ show confirmation dialog box on completion
myPdfExporter.ShowConfirmationDialog = True
Try
myPdfExporter.Commit()
Catch ex As Exception
MessageBox.Show("Error:" & ControlChars.CrLf & ex.GetType.ToString & " : " & ex.Message, "PDF export error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
myPdfExporter = Nothing
End Try
End Sub
End Module
'### Class code omitted for brevity
Set options programmatically
If you want options other than the default values and do not want to prompt the user for input, you can set the values in code like in the following example.
Option Strict Off
Imports System
Imports System.IO
Imports System.Collections.Generic
Imports System.Windows.Forms
Imports NXOpen
Imports NXOpen.UF
Module NXJournal
Sub Main()
Dim theSession As Session = Session.GetSession
If IsNothing(theSession.Parts.Display) Then
MessageBox.Show("Active Part Required", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End If
Dim workPart As Part = theSession.Parts.Work
Dim myPdfExporter As New NXJ_PdfExporter
myPdfExporter.Part = workPart
'$ set output folder
myPdfExporter.OutputFolder = "C:\temp"
'$ set desired watermark text
myPdfExporter.UseWatermark = True
myPdfExporter.WatermarkText = "PREPRODUCTION DRAWING"
myPdfExporter.WatermarkAddDatestamp = True
'$ show confirmation dialog box on completion
myPdfExporter.ShowConfirmationDialog = True
Try
myPdfExporter.Commit()
Catch ex As Exception
MessageBox.Show("Error:" & ControlChars.CrLf & ex.GetType.ToString & " : " & ex.Message, "PDF export error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
myPdfExporter = Nothing
End Try
End Sub
End Module
'### Class code omitted for brevity
Code Download
Click the link below to download a zip file containing the class file and example journal code.
PDF Exporter Class
Conclusion
Hopefully, this class will provide an easy way to export pdf files from your own code. If you find any bugs or have ideas for features to add, please leave them in the comments below or email me: info@nxjournaling.com.
Comments
output file name
Hi, thank you for very usefull journal.
Is it possible to name PDF files "part atribut ID.pdf" instead of name from default folder ??
In other words How to make OutputFileName to contain part ID atribut ?
Thank you
re: attribute name
You can query the desired attribute and pass in the value to the pdf exporter's OutputPdfFileName property.
The following link has some code that shows how to get the value of a string attribute (NX 8 or higher).
http://nxjournaling.com/comment/2655#comment-2655
Attribute Name
Thank you for answer. But i am new to NX journaling and VB to.
Please can you give me little detailed advice ?
Basicly i understand the procedure which returns file name but i dont know how to modifi that to get desired result.
I always get an error "NXOpen.NXObject.AttributeInformation is not possible to convert to string" ...
I've made this ::
Private _outputPdfFile As String = ""
Public Property OutputPdfFileName() As String
Get
Return _outputPdfFile
End Get
Set(ByVal value As String)
lg.WriteLine("Set Property OutputPdfFileName")
lg.WriteLine(" value passed to property: " & value)
Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim lw As ListingWindow = theSession.ListingWindow
lw.Open()
Const attributeName As String = "ArticalID"
Dim attributeInfo As NXObject.AttributeInformation
If workPart.HasUserAttribute(attributeName, NXObject.AttributeType.String, -1) Then
_outputPdfFile = workPart.GetUserAttribute(attributeName, NXObject.AttributeType.String, -1)
lg.WriteLine("attribute value: " & attributeInfo.StringValue & ".pdf")
Else
lw.WriteLine("the work part does not have an attribute named: " & attributeName)
End If
End Set
End Property
Thank you
re: attribute value pdf name
Nope, sorry, that's not what I meant. You don't need to change any of the code in the class; imagine that it is a 'black box' that you don't know or care how it works. The code that you need to add is in the Sub Main routine. Here you can query your part for the attribute and assign it to the pdfExporter.OutputFileName property. See the example below.
Copy one of the sample files that was in the .zip file and edit the Main subroutine to the following:
Option Strict Off
Imports System
Imports System.IO
Imports System.Collections.Generic
Imports System.Windows.Forms
Imports NXOpen
Imports NXOpen.UF
Module use_attribute_for_pdf_name
Sub Main()
Dim theSession As Session = Session.GetSession
If IsNothing(theSession.Parts.Display) Then
MessageBox.Show("Active Part Required", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End If
Dim workPart As Part = theSession.Parts.Work
Const attributeName As String = "ArticalID"
Dim attributeInfo As NXObject.AttributeInformation
Dim myOutputName As String = Nothing
If workPart.HasUserAttribute(attributeName, NXObject.AttributeType.String, -1) Then
attributeInfo = workPart.GetUserAttribute(attributeName, NXObject.AttributeType.String, -1)
myOutputName = attributeInfo.StringValue
End If
Dim myPdfExporter As New NXJ_PdfExporter
myPdfExporter.Part = workPart
'$ prompt user for output folder
myPdfExporter.PickExportFolder()
'$ change output file name
If Not IsNothing(myOutputName) Then
myPdfExporter.OutputPdfFileName = myOutputName
End If
'$ preliminary print?
myPdfExporter.PromptPreliminaryPrint()
'$ desired watermark text (if preliminary print)
myPdfExporter.PromptWatermarkText()
myPdfExporter.WatermarkAddDatestamp = True
'$ show confirmation dialog box on completion
myPdfExporter.ShowConfirmationDialog = True
Try
myPdfExporter.Commit()
Catch ex As Exception
MessageBox.Show("Error:" & ControlChars.CrLf & ex.GetType.ToString & " : " & ex.Message, "PDF export error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
myPdfExporter = Nothing
End Try
End Sub
End Module
For this to work, the code above will need to be in the same file as the original pdf exporter class code. Any "imports" statements will need to be commented out in the class code. This should already be taken care of if you edit one of the original examples found in the .zip folder.
Attribute value pdf name
Hello, very thanks to you. Now it is almost working like i need, but there is a little glitch :D
I found that *dwg.prt doesnt contain my desired attribute. That attribute is in the child file .prt of drawing. Is there any way to take tha attribute from the child prt of displayed part ?
Thank you so much
re: pdf name based on component attribute
Below is code that will look for components of the current display part. If a component is found, it will use an attribute for the name of the exported pdf file.
Note: This journal only looks at the first component found. If the displayed part has multiple components, only the first one found is queried for the attribute.
Note 2: This code will need to be combined into a single file with the pdf exporter class code in the same way as the previous example.
Option Strict Off
Imports System
Imports System.IO
Imports System.Collections.Generic
Imports System.Windows.Forms
Imports NXOpen
Imports NXOpen.UF
Module use_master_model_attribute
Sub Main()
Dim theSession As Session = Session.GetSession
Dim lw As ListingWindow = theSession.ListingWindow
If IsNothing(theSession.Parts.Display) Then
MessageBox.Show("Active Part Required", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End If
lw.Open()
Dim workPart As Part = theSession.Parts.Work
'Get the 1st level child components of the display part
Dim dpc As Assemblies.Component = theSession.Parts.Display.ComponentAssembly.RootComponent
Dim dpcChildren() As Assemblies.Component = dpc.GetChildren
'Change the attribute name to search for
Const attributeName As String = "test"
Dim attributeInfo As NXObject.AttributeInformation
Dim myOutputName As String = Nothing
If dpcChildren.Length = 0 Then
'no components
lw.WriteLine("the display part has no components, default pdf output name will be used")
Else
If dpcChildren(0).HasUserAttribute(attributeName, NXObject.AttributeType.String, -1) Then
attributeInfo = dpcChildren(0).GetUserAttribute(attributeName, NXObject.AttributeType.String, -1)
myOutputName = attributeInfo.StringValue
Else
'no attribute found
lw.WriteLine("the first child component does not have the specified attribute, the default pdf output name will be used")
End If
End If
Dim myPdfExporter As New NXJ_PdfExporter
myPdfExporter.Part = theSession.Parts.Display
'$ prompt user for output folder
myPdfExporter.PickExportFolder()
'$ change output file name
If Not IsNothing(myOutputName) Then
myPdfExporter.OutputPdfFileName = myOutputName
End If
'$ preliminary print?
myPdfExporter.PromptPreliminaryPrint()
'$ desired watermark text (if preliminary print)
myPdfExporter.PromptWatermarkText()
myPdfExporter.WatermarkAddDatestamp = True
'$ show confirmation dialog box on completion
myPdfExporter.ShowConfirmationDialog = True
Try
myPdfExporter.Commit()
Catch ex As Exception
MessageBox.Show("Error:" & ControlChars.CrLf & ex.GetType.ToString & " : " & ex.Message, "PDF export error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
myPdfExporter = Nothing
End Try
End Sub
End Module
watermark color red
Is it possible to change the watermark from black to red?
re: watermark color
In this journal, changing the watermark color is not an option.
Can you specify the watermark color in the interactive NX options? I'm not in front of NX right now and I don't remember... If no, then it most likely won't be available through the API either.
Export sheets individually
Hello,
On native NX 10 I am using the export_pdf_test_set_options journal.
When the function "ExportSheetsIndividually"is set to true, we get filenames according to the sheet name. Exporting multiple parts will result in files with the same names. And next to that we lik to have the same name for the .PDF and .prt files. How can we add the part name as a prefix in the .pdf name when using "ExportSheetsIndividually"?
Example
part file name = M16.0123-456-789.prt
Contains 5 sheets; A4, A3, A2, A1, A0
PDF names should become
M16.0123-456-789_A4.pdf
M16.0123-456-789_A3.pdf
M16.0123-456-789_A2.pdf
M16.0123-456-789_A1.pdf
M16.0123-456-789_A0.pdf
re: export sheets individually
I've updated the code; please re-download from the link and try it out. If you run into any issues, let me know.
Perfect! Thanks for the fast
Perfect! Thanks for the fast response!
How to remove _dwg1 from file name PDF
I have tested this journal "export_pdf_test_all_parts_in_folder" an is very completly program to export PDF file from folder.
But Now I want export the file name whitout "_dwg1" but I don't be able to find the point to modify the code.
Have you a solution for delete _dwg1?
re: remove _dwg1
The .OutputPdfFileName property allows you to supply whatever name you want for the final PDF file. The code below will look for "_dwg" in the part name, strip it out if found, and use that for the PDF file name.
Change the "ExportPdfs" subroutine (around line 166) to the code shown below:
Sub ExportPdfs()
lw.WriteLine(displayPart.FullPath)
myPdfExporter.Part = displayPart
Const findIt As String = "_dwg"
If displayPart.Leaf.ToLower.Contains(findIt) Then
myPdfExporter.OutputPdfFileName = displayPart.Leaf.Substring(0, displayPart.Leaf.Length - displayPart.Leaf.IndexOf(findIt) + 1)
End If