Search code examples
pythonvbams-wordpywin32caption

How to add images with figure captions to a word document


import win32com.client as win32
import os

#creating a word application object
wordApp = win32.gencache.EnsureDispatch('Word.Application') #create a word application object
wordApp.Visible = True # hide the word application
doc = wordApp.Documents.Add() # create a new application

#Formating the document
doc.PageSetup.RightMargin = 10
doc.PageSetup.LeftMargin = 10
doc.PageSetup.Orientation = win32.constants.wdOrientLandscape
# a4 paper size: 595x842
doc.PageSetup.PageWidth = 595
doc.PageSetup.PageHeight = 842


# Inserting Tables
my_dir="C:/Users/David/Documents/EGi/EGi Plots/FW_plots/Boxplots"
filenames = os.listdir(my_dir)
piccount=0
file_count = 0
for i in filenames:
    if i[len(i)-3: len(i)].upper() == 'JPG': # check whether the current object is a JPG file
        piccount = piccount + 1

print piccount, " images will be inserted"

total_column = 1
total_row = int(piccount/total_column)+2
rng = doc.Range(0,0)
rng.ParagraphFormat.Alignment = win32.constants.wdAlignParagraphCenter
table = doc.Tables.Add(rng,total_row, total_column)
table.Borders.Enable = False
if total_column > 1:
    table.Columns.DistributeWidth()

#Collecting images in the same directory and inserting them into the document


piccount = 1

for index, filename in enumerate(filenames): # loop through all the files and folders for adding pictures

    if os.path.isfile(os.path.join(os.path.abspath(my_dir), filename)): # check whether the current object is a file or not
        if filename[len(filename)-3: len(filename)].upper() == 'JPG': # check whether the current object is a JPG file
            piccount = piccount + 1
            print filename, len(filename), filename[len(filename)-3: len(filename)].upper()


            cell_column = (piccount % total_column + 1) #calculating the position of each image to be put into the correct table cell
            cell_row = (piccount/total_column + 1)
            #print 'cell_column=%s,cell_row=%s' % (cell_column,cell_row)

            #we are formatting the style of each cell
            cell_range= table.Cell(cell_row, cell_column).Range
            cell_range.ParagraphFormat.LineSpacingRule = win32.constants.wdLineSpaceSingle
            cell_range.ParagraphFormat.SpaceBefore = 0
            cell_range.ParagraphFormat.SpaceAfter = 3

            #this is where we are going to insert the images
            current_pic=cell_range.InlineShapes.AddPicture(os.path.join(os.path.abspath(my_dir), filename))


            #Currently this puts a lable in a cell after the pic, I want to put a proper ms word figure caption below the image instead.
            table.Cell(cell_row, cell_column).Range.InsertAfter("\n"+"Appendix II Figure "+ str(piccount-1)+": "+filename[:len(filename)-4]+"\n"+"\n"+"\n")


        else: continue

This code gets all the images in a chosen directory and puts them in a table in a word doc, and then puts the file name (stripped of the file extn) in the cell below. I would like a proper figure caption (so that these will update if I insert additional pictures) but everything I've tried has failed.

I just can't get the VB commands right, this:

table.Cell(cell_row, cell_column).Range.InsertAfter(InsertCaption(Label="Figure", Title=": "+filename[:len(filename)-4]))

gives me a list of figure captions at the end of the document, which isn't really what I want. I feel like I am close but I just cant quite get it. Thanks!


Solution

  • In order to use Word's built-in captioning instead of current_pic.InsertCaption use current_Pic.Range.InsertCaption. The InsertCaption method is a member of the Range not the InlineShape object. For me, this automatically inserts the caption below the picture, in its own paragraph. But if you want to specificy "below" use the Position argument, as well:

    current_pic.Range.InsertCaption(Label="Figure", Title=": "+filename[:len(filename)-4]), Position=win32.constants.wdCaptionPositionBelow
    

    Note: FWIW when I test the line of code (in VBA) that you say gives you a list of captions at the end of the document I do see the text in the same cell as the inserted picture.