Print PDF and rename the files

Hello everyone,

At work I am improving our work flow through Dynamo. I’ve already written a few things in Dynamo. But now I want a script that prints PDF and immediately gives it the correct name. I already have 95% of the script working, but unfortunately renaming the files fails. I only get a letter. And I saw that everyone else had this problem but I have already tried all possible solutions. but unfortunately I can’t
get it to work. I would like some help with my script. I’m using the Archi-lab rename node.


It spits out the error Errno 17, cant create file that already exists

this is my result, its a set of 3 sheets, does anyone know what i doing wrong?

Have you thought of using a ready made product like Xporter?

Are you using a cusom made script to print the sheets or are you using a pre-existing node from a package?

no, did not know that. but it is a viable solution but im more into fixing my one script

its a from a package i might help if is post a part of my code,

Is it by chance a archilab node? I can remember having some trouble getting that one to work myself so I wrote my own.

If you’re interested, see the code below.
I’m not sure if it exactly does what you want it to do, but it might help you find a solution to the problem.
I think that you should be able to make some small modifications to my code to have it so it takes a list of names and uses shortlacing to set the right name for your drawings. This would prevent having to rename them afterwards.

#Written by D.Kuurman
#FIMBLE print to pdf node
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)
import System


doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

printManager = doc.PrintManager	
printManager.PrintRange = PrintRange.Select
printManager.PrintToFile = True
viewSheetSetting = printManager.ViewSheetSetting


sheetlists = IN[0]
papersizes = IN[1]
combineFiles = IN[2]
fileName = IN[3]
fileLocation = IN[4]
printerName = IN[5]

output = list()
temp = list()

TransactionManager.Instance.EnsureInTransaction(doc)
#print the sheets
i = 0
for sublist in sheetlists:
	printlist = list()
	newViewSet = ViewSet()	
	printManager.Apply()
	setupName = 'temporary %s' %(i)
	
	if isinstance(sublist, list):
		for sheet in sublist:
			printlist.append(UnwrapElement(sheet))
	else:
		printlist.append(UnwrapElement(sublist))
	
	output.append(printlist)
	
	#build viewset for printing
	for item in printlist:
		newViewSet.Insert(item)
	temp.append(newViewSet)
	
	#setup print settings
	printManager.ViewSheetSetting.CurrentViewSheetSet.Views = newViewSet
	printManager.Apply()
	
	printManager.PrintSetup.CurrentPrintSetting = printManager.PrintSetup.InSession
	pParams = printManager.PrintSetup.CurrentPrintSetting.PrintParameters
	
	for size in printManager.PaperSizes:
		if size.Name == papersizes[i]:
			printManager.PrintSetup.CurrentPrintSetting.PrintParameters.PaperSize = size
			printManager.PrintSetup.CurrentPrintSetting.PrintParameters.ZoomType = printManager.PrintSetup.CurrentPrintSetting.PrintParameters.ZoomType.Zoom
			printManager.PrintSetup.CurrentPrintSetting.PrintParameters.Zoom = 100
			printManager.PrintSetup.CurrentPrintSetting.PrintParameters.PageOrientation = printManager.PrintSetup.CurrentPrintSetting.PrintParameters.PageOrientation.Landscape
			printManager.PrintToFileName = fileLocation + fileName + ".pdf"
			printManager.SelectNewPrintDriver(printerName)
			
			printManager.PrintSetup.SaveAs(setupName)
			printManager.Apply()
	i += 1	
	
	printManager.CombinedFile = combineFiles
	printManager.Apply()
	
	printManager.SubmitPrint()
		
	li = list()
	for p in printManager.PaperSizes:
		li.append(p.Name)
		
	
OUT = output, temp, li 

TransactionManager.Instance.TransactionTaskDone()
3 Likes

as much as would like to use ur code, but im not that much into python yet. so in other words in dont know how use the ur code. but the print part worked, but the renaming part does not.

If the problem is that now everything gets the same name (probably appended by a number following the former one) then I believe you could add “[i]” to the end of “filename” on line 82 to make it compatible for a list input. This then looks like this:

printManager.PrintToFileName = fileLocation + fileName[i] + ".pdf"

This should allow you to use a list of strings as the input of IN[3].
Goodluck!

Hi,

You should use the Print PDF (multiple formats) node in Genius Loci package.
This is a variant of the Print PDF node. (Thanks to Konrad Sobon for making the original one.)
One of the input is the list of the final PDF names, so it is no longer necessary to rename PDF files afterward.

1 Like

Thank you very much, know its working. :grinning:

1 Like

Stumbled upon this thread…

For anyone who is interested:
I altered @Konrad_K_Sobon Konrad script a bit and was able to print and rename in the same run. So when i press run it starts plotting my sheets and when that’s done it renames them according to the parameters i have entered.

I use a wait function based on the amount of sheets I plot, not an ideal solution but it works.
Going to replace the wait function by a file counter so Dynamo waits with plotting the next file until the former was actually saved in the folder.

Code looks like this now:

 # Copyright(c) 2015, Konrad K Sobon
    # @arch_laboratory, http://archi-lab.net

    import clr
    import time

    clr.AddReference('ProtoGeometry')
    from Autodesk.DesignScript.Geometry import *

    # Import Element wrapper extension methods
    clr.AddReference("RevitNodes")
    import Revit

    clr.ImportExtensions(Revit.Elements)

    # Import geometry conversion extension methods
    clr.ImportExtensions(Revit.GeometryConversion)

    # Import DocumentManager and TransactionManager
    clr.AddReference("RevitServices")
    import RevitServices
    from RevitServices.Persistence import DocumentManager
    from RevitServices.Transactions import TransactionManager

    doc = DocumentManager.Instance.CurrentDBDocument
    uiapp = DocumentManager.Instance.CurrentUIApplication
    app = uiapp.Application

    # Import RevitAPI
    clr.AddReference("RevitAPI")
    import Autodesk
    from Autodesk.Revit.DB import *

    import sys

    pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
    sys.path.append(pyt_path)

    import os
    import System

    # The inputs to this node will be stored as a list in the IN variable.
    dataEnteringNode = IN

    # The sheets to print
    sheets = IN[0]
    # Set to select to print only the selected views/sheets
    pRange = System.Enum.Parse(Autodesk.Revit.DB.PrintRange, IN[1])
    # True if saving as a single combined file, false if saving as separate files
    combined = IN[2]
    # The printer/pdf creator to send the selected files to
    printerName = IN[3]
    # List of sheet sizes to print
    printInstellingen = IN[4]
    # String: A prefix to give to the files that are to be saved, like a project name. Leave empty if not desired.
    prefix = IN[5]
    # Sheet numbers
    identifiers = IN[6]
    # List of the new sheet names, to be given to the identifiers specified sheets
    newNames = IN[7]
    # String: Directory path to the folder in which the sheet files can be saved/renamed
    filePath = IN[8]
    # Reset the script when run with false, when true actually runs the script
    runIt = IN[9]

    if isinstance(sheets, list):
        viewSheets = []
        for viewset in sheets:
            viewSheets.append(UnwrapElement(viewset))
    else:
        viewSheets = UnwrapElement(sheets)

    if isinstance(printInstellingen, list):
        printSettings = []
        for viewset in printInstellingen:
            printSettings.append(UnwrapElement(viewset))
    else:
        printSettings = UnwrapElement(printInstellingen)

    TransactionManager.Instance.EnsureInTransaction(doc)
    printManager = doc.PrintManager
    printSetup = printManager.PrintSetup
    printManager.SelectNewPrintDriver(printerName)
    if isinstance(printInstellingen, list):
        printSetup.CurrentPrintSetting = printSettings[0]
    else:
        printSetup.CurrentPrintSetting = printSettings
    printManager.Apply()
    TransactionManager.Instance.TransactionTaskDone()

    #
    # Prints a given sheet as the provided filePathAndName, obeying the other parameters like printSettings about how to do so.
    #
    # param doc: The current revit document you're working in
    # param sheet: A view sheet to be printed/saved
    # param pRange: The range of which files are to be saved, "selected" in this case
    # param printerName: The printer name or pdf application to send the files to
    # param combined: Boolean - True if to be saved as a single file, false if to be saved separately
    # param filePathAndName: String - The full path and name, indicating where to save the file and under which name
    # param printSetting: PrintSetting - Represents the print setup within autodesk revit about how to save the files
    def PrintView(doc, sheet, pRange, printerName, combined, filePathAndName, printSetting):
        # create view set
        viewSet = ViewSet()
        viewSet.Insert(sheet)
        # determine print range
        printManager = doc.PrintManager
        printManager.PrintRange = pRange
        printManager.Apply()
        # make new view set current
        viewSheetSetting = printManager.ViewSheetSetting
        viewSheetSetting.CurrentViewSheetSet.Views = viewSet
        # set printer
        printManager.SelectNewPrintDriver(printerName)
        printManager.Apply()
        # set combined and print to file
        if printManager.IsVirtual:
            printManager.CombinedFile = combined
            printManager.Apply()
            printManager.PrintToFile = True
            printManager.Apply()
        else:
            printManager.CombinedFile = combined
            printManager.Apply()
            printManager.PrintToFile = False
            printManager.Apply()
        # set file path
        printManager.PrintToFileName = filePathAndName
        printManager.Apply()
        # apply print setting
        try:
            printSetup = printManager.PrintSetup
            printSetup.CurrentPrintSetting = printSetting
            printManager.Apply()

        except:
            pass
        # save settings and submit print
        TransactionManager.Instance.EnsureInTransaction(doc)
        viewSheetSetting.SaveAs("tempSetName")
        printManager.Apply()
        result = printManager.SubmitPrint()
        viewSheetSetting.Delete()
        TransactionManager.Instance.TransactionTaskDone()

        return result

    try:
        viewSets = FilteredElementCollector(doc).OfClass(ViewSheetSet)
        for viewset in viewSets:
            if viewset.Name == "tempSetName":
                TransactionManager.Instance.EnsureInTransaction(doc)
                doc.Delete(viewset.Id)
                TransactionManager.Instance.ForceCloseTransaction()
            else:
                continue

        errorReport = None
        message = "Success"
        if runIt:
            timeToWaitBeforeRenaming = 25
            if isinstance(viewSheets, list) and isinstance(printSettings, list):
                timeToWaitBeforeRenaming = max([25, len(viewSheets) * 4])
                for viewset, printSetting in zip(viewSheets, printSettings):
                    PrintView(doc, viewset, pRange, printerName, combined, prefix, printSetting)
            elif isinstance(viewSheets, list) and not isinstance(printSettings, list):
                timeToWaitBeforeRenaming = max([25, len(viewSheets) * 4])
                for viewset in viewSheets:
                    PrintView(doc, viewset, pRange, printerName, combined, prefix, printSettings)
            elif not isinstance(viewSheets, list) and not isinstance(printSettings, list):
                PrintView(doc, viewSheets, pRange, printerName, combined, prefix, printSettings)

            # Give the PDF Creator to save the files
            time.sleep(timeToWaitBeforeRenaming)

            for file in os.listdir(filePath):
                currentFileName = filePath + "\\" + file

                for identifier, newName in zip(identifiers, newNames):
                    newFileName = filePath + "\\" + newName

                    if identifier in file and currentFileName != newFileName:
                        os.rename(currentFileName, newFileName)

        else:
            message = "Set RunIt to True"

    except:
        # if error accurs anywhere in the process catch it
        import traceback

        errorReport = traceback.format_exc()

    # Assign your output to the OUT variable
    if errorReport == None:
        OUT = message
    else:
        OUT = errorReport

@ MVE1112 : Can you please re-upload the image of graph with better resolution ?

I have been working on similar task. Trying to print multiple sheets with dynamo.

Orchid:
I can print sheets with Orchid.common.print.Actions, this works fine, except that the name of file is not what i want. I already have string name ( with path ) still it does rename the file.

GeniusLoci.printing :
As mentioned above, does not yield any result. The script says Run Completed but I dont see any pdf in the location or anywhere.

Any help where am I making mistake. I updated, the packages as well. I just need to get the right file name. rest is working fine.

Hi Hassan,

I have edited the script multiple times. Looking back at my screenshot i must say im glad i found out what dictionaires are haha.

What printer are you using? I think ,most people who struggle with renaming a PDF file through dynamo when plotting a PDF are using the wrong printer.

I use PDF Creator with a special Dynamo profile to allow pdfs to be made with a name and directory input from the program calling the printer.

So, what printer are you using?

Hey,
I am using PDF-XChange Editor. Its not that easy to install new software taht easily so I am stuck with this printer.

I am already have created a perfect file name string, I just need to plug that string as pdf file name.