scanny / python-pptx

Create Open XML PowerPoint documents in Python
MIT License
2.42k stars 522 forks source link

TextFrame.fit_text exceptions #168

Open mfellows opened 9 years ago

mfellows commented 9 years ago

I realize this feature is still under development and has some constraints (as per https://python-pptx.readthedocs.org/en/latest/dev/analysis/features/txt-fit-text.html) --

I'm using python-pptx to populate a template, mostly with long decimal numbers, and fit_text runs into some problems when called on TextFrames with long strings that can't be broken up; it looks like it happens in the part of the library that calculates the text that can fit on the current line and the remainder.

If you use a PowerPoint template similar to the attached image, the following script reproduces the problem:

from pptx import Presentation

def get_target_shape(slide, name):
    for shape in slide.shapes:
        if shape.name == name:
            return shape

    raise Exception("Shape '{0}' not found in slide {1}"
                    .format(name, slide.name))

def set_autofit(shape):
    text_frame = shape.text_frame
    for paragraph in text_frame.paragraphs:
        paragraph.font.name = "Calibri"
    text_frame.fit_text(font_file=r"c:\windows\fonts\calibriz.ttf")

if __name__ == "__main__":
    ppt = Presentation("template.pptx")
    slide = ppt.slides[0]
    shape = get_target_shape(slide, "Oval 3")

    # This works, although the font size is still too big:
    shape.text = "this string is too long and needs to be resized"

    # This crashes:
    #shape.text = "thisstringistoolongandneedstoberesized"

    # This also crashes:
    #shape.text = "thisstring is toolong and needs toberesized"

    set_autofit(shape)
    ppt.save("template_populated.pptx")

(oops, attachments don't seem to work - template.pptx is a single slide containing an oval autoshape with dimensions H: 0.75", W: 1")

jackson-ml commented 6 years ago

I've got a fix for this now that I'm working a PR for.