Select to view content in your preferred language

Change font in current mxd using python

2380
3
05-18-2011 11:03 PM
George_ChandeepCorea
Occasional Contributor
Hi,

I want to change all the font styles in a number of mxd's from "Lucinda Sans" or whatever the current one is to "Arial" without changing the font size.

I wrote a simple script to find/replace text but can't figure out how to change the font except by adding html code as in the example below (see image as well). But this doesn't change the root font and also I want it to change the font of all text strings in the Text and Legend elements. No need to search/replace any text.

Thanks in advance. Screen capture and Code are below.

N.B. I was also trying to get it export to pdf if the option was on, but this was giving me an index error (code is commented out, the while loop gives the error but the export to pdf works fine).

![enter image description here][1]

    import os, arcpy, arcpy.mapping
    oldText = arcpy.GetParameterAsText(0)
    newText = arcpy.GetParameterAsText(1)
    pdf = arcpy.GetParameterAsText(2)
    mxd=arcpy.mapping.MapDocument("Current")
    
    # Loop through each text element in the map document
    for textElement in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT"):
        
        # Check if the text element contains the out of date text
        if textElement.text == oldText:
         
     # If out of date text is found, replace it with the new text
            textElement.text = '<FNT name="Arial">' + newText + '</FNT>'
    
    #while PDF = 1:
    # Export the updated map to a PDF
    #path = r'P:\2011\Job_031_TownPlanning_SeriesProduction\Working\draft_output\esri\2\wetland\'
    #arcpy.mapping.ExportToPDF(mxd, newText + "-TownPlanning_Wetlands_Overlay_Ver2.pdf")
    
    #arcpy.mapping.ExportToJPEG(mxd, outFile)
    #outFile = newText + df.name + ".pdf"
    
    # Clean up the MapDocument object by deleting it
    del mxd
     
    arcpy.RefreshActiveView()
    arcpy.RefreshTOC()



  [1]: http://i.stack.imgur.com/IUBtV.gif
Tags (2)
0 Kudos
3 Replies
chriss_
Emerging Contributor
Hi!

As far as I know the HTML-Style is the only way.

If you know the fontStyles and there are not to many different, you can exchange them see code below. In theory you could make a list of all fonts and step through the list, but I guess it would take quite long to step through all.
For the font size it depends. If the old text is set in HTML style it will not change. But if not it might. Also the position of the textfield might change, but this you can avoid using the TextElement properties, elementHeight,elementPositionX,elementPositionY,elementWidth.
The root font, I think you can not change it.
There is no access to the TextProperties of Legends. 😞

I hope that gives you some more ideas.

Good luck

import os, arcpy, arcpy.mapping
oldText = arcpy.GetParameterAsText(0)
newText = arcpy.GetParameterAsText(1)
PDF = arcpy.GetParameterAsText(2)
mxd=arcpy.mapping.MapDocument("Current")
OldFont='<FNT name="Vivaldi"'
NewFont='<FNT name="Arial"'
# Loop through each text element in the map document
for textElement in arcpy.mapping.ListLayoutElements(mxd,"TEXT_ELEMENT"):
    #Check if the text element contains the out of date text
    if str(oldText) in str(textElement.text):
        #If out of date text is found, replace it with the new text
        Text=str (textElement.text)
        Text=Text.replace(OldFont,NewFont)
        Text=Text.replace(oldText,newText)
        textElement.text=str(Text)    
        if PDF == "1":
            #Export the updated map to a PDF
            path = 'C:\Project'
            arcpy.mapping.ExportToPDF(mxd, path + "/TownPlanning_Wetlands_Overlay_Ver2.pdf")
             

#Clean up the MapDocument object by deleting it
del mxd
arcpy.RefreshActiveView()
arcpy.RefreshTOC()
0 Kudos
George_ChandeepCorea
Occasional Contributor
Thanks. It is really unfortunate that there is no way of changing the root font -this seems like a critically important function in editing/updating mxd's.

I have about 100+ mxd's for townplanning where different font styles (mostly Arial) have been used and we need to change all of them to the new corporate font (Lucinda Sans)...

Would I be able to change the fonts in one mxd and then as the other TextElements are the same in all the mxd's, simply replace all the old full text elements with the new ones?

>>> mxd_r=r'P:\2011\Job_031_TownPlanning_SeriesProduction\Working\mxd\B&L\2\1-7_TownPlanning_B&L.mxd'
>>> mxd_current=arcpy.mapping.MapDocument("Current")
>>> mxd_root=arcpy.mapping.MapDocument(mxdr)
>>> Textelm_root=arcpy.mapping.ListLayoutElements(mxd_root,"TEXT_ELEMENT")
>>> Textelm_current=arcpy.mapping.ListLayoutElements(mxd_current,"TEXT_ELEMENT")
>>> Textelm_current
[<TextElement object at 0x203f1430[0x203b6fa0]>, <TextElement object at 0x203f12f0[0x203b6d40]>, <TextElement object at 0x203f1450[0x203f1380]>, <TextElement object at 0x203a5310[0x203f13a0]>, <TextElement object at 0x203f14b0[0x203f1260]>, <TextElement object at 0x203f14f0[0x203f1060]>, <TextElement object at 0x203f1510[0x203f13c0]>]
>>> Textelm_root
[<TextElement object at 0x203f1250[0x203f10e0]>, <TextElement object at 0x203a5090[0x203f11c0]>, <TextElement object at 0x203f1050[0x203f10c0]>, <TextElement object at 0x203f1150[0x203f1180]>, <TextElement object at 0x203f12b0[0x203f11a0]>, <TextElement object at 0x203f12d0[0x203f11e0]>]


Then how would I do the equivalent of

>>> Textelm_current[1]=Textelm_root[1]
>>> arcpy.RefreshActiveView()


If this works then it can be in a while loop for each mxd Textelm_current can be replaced with Textelm_root

I referred the following but no mention of replacing the TextElement object...

http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/TextElement/00s30000000m000000/

and

http://docs.python.org/library/stdtypes.html
0 Kudos
chriss_
Emerging Contributor
Hi!

It might help to change ur system default font in microsoft or whatever you use. But it will change for all programms using those settings.  Besides I think it wil only affect new maps, though I am not sure about this.

1. Possibillity
How about using a template? It depends what unique elements u ve on each map. If ur maps only differ by mapname you could arrange all ur layout stuff in one map and use it as tmeplate. For the map name u use dynamic text. So it will automatically write the name of the map in this textfield.
2. Possibillity
U arrange your textfields using HTMl code and the copy the HTML containing text to your code. Loop through each layout element and replace the old text.

import os, arcpy, arcpy.mapping
mxd=arcpy.mapping.MapDocument("Current")
    
# Loop through each text element in the map document
for textElement in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT"):
    # Finds the right textelement 
     if textElement.name == "Text_Element1":
     #Replaces the old text by new
        textElement.text = '<FNT name="Arial" size = "10">' + "My New text" + '</FNT>' #plus whatever other HTML font style specification u did  

     elif textElement.name == "Text_Element1":
      textElement.text = '<FNT name="Aria2" size = "12">' + "My New text2" + '</FNT>'

     elif textElement.name == "Text_Element3":
      textElement.text = '<FNT name="Arial" size = "12">' + "My New text3" + '</FNT>'
    #etc.....
del mxd
0 Kudos