python-openxml / python-docx

Create and modify Word documents with Python
MIT License
4.62k stars 1.13k forks source link

feature: add multiple pictures in the same paragraph #235

Open zhongle opened 8 years ago

zhongle commented 8 years ago

Hi, Scanny,

For docx add_picture function, is it support add multiple pictures in the same paragraph?

in your pptx, add_picture(left, top, width, height) can add multiple graph to a single row

by input parameter. There are only width and height for docx.

Thanks, Le

scanny commented 8 years ago

@zhongle - not with the current API. But of course Word and the XML format support this. This page in the technical documentation may give you an idea how inline pictures in Word work. http://python-docx.readthedocs.org/en/latest/dev/analysis/features/shapes-inline.html

By going down to the lxml level you should be able to accomplish what you're after.

zhongle commented 8 years ago

Hi, Scanny,

I have solve the multi-pic issue by adding multi-inline shapes under drawing, thanks for your suggestions.

Thanks, Le

scanny commented 8 years ago

That's great @zhongle, glad you got it working. If you can share the code you developed as a Gist and link it here, that may be helpful to others who want to do this sort of thing :)

zhongle commented 8 years ago

Hi, Scanny,

Sure, glad to share, main flow code as below:

def add_picture_to_run(run, picture_file, width=None, height=None):
    """
    Add a picture at the end of a run.
    """
    rId, image = run.part.get_or_add_image(picture_file)
    cx, cy = image.scaled_dimensions(width, height)
    shape_id, filename = run.part.next_id, image.filename
    inline = CT_Inline.new_pic_inline(shape_id, rId, filename, cx, cy)
    run._r.add_drawing(inline) 

run = doc.add_paragraph().add_run()
picture = 'foobar.png'
add_picture_to_run(run, picture)

if want to add multi-picture in same row, use the same run instance.

Thanks, Le

scanny commented 8 years ago

Super, thanks @zhongle, nice job! :)

I cleaned up a couple aspects of the code. In particular there's no need for a self parameter since this is a free-standing function rather than a method on the Run object.

zhongle commented 8 years ago

No problem, agreed! :)

jackadam1981 commented 5 years ago

where is CT_Inline??

scanny commented 5 years ago

from docx.oxml.shape import CT_Inline

jackadam1981 commented 4 years ago

` def add_picture_to_run(run, picture_file, width=None, height=None): """ Add a picture at the end of a run. """ rId, image = run.part.get_or_add_image(picture_file) cx, cy = image.scaled_dimensions(width, height) shape_id, filename = run.part.next_id, image.filename inline = CT_Inline.new_pic_inline(shape_id, rId, filename, cx, cy) run._r.add_drawing(inline)

run = doc.add_paragraph().add_run() picture = 'foobar.png' add_picture_to_run(run, picture) `

It add picture after the line, how to add picture before the line? need cheng rId and shape_id?