scanny / python-pptx

Create Open XML PowerPoint documents in Python
MIT License
2.26k stars 499 forks source link

add_textbox and PP_ALIGN is not 'taking affect' until I move the text box in powerpoint #914

Closed RamadiRat closed 9 months ago

RamadiRat commented 9 months ago

Following code is creating the text box, but the center alignment is not taking affect until/unless I resize the text box in PowerPoint

***

***** ADD Left Title

txBox = sl_1.shapes.add_textbox(Inches(.25), Inches(1), Inches(3), Inches(3)) tf = txBox.text_frame

print(tf.dir())

p = tf.paragraphs[0] p.alignment = PP_ALIGN.CENTER run = p.add_run() run.text = "Threat Assessment" font = run.font font.name = "Univers" font.size = Pt(32) font.bold = False font.color.rgb = RGBColor(255,255,255)

scanny commented 9 months ago

Have you tried setting the text_frame.auto_size property? https://python-pptx.readthedocs.io/en/latest/api/text.html#pptx.text.text.TextFrame.auto_size

To fully diagnose this you'd have to compare the shape XML before and after, which is actually not hard. Just something like this:

# -- make shape, then --
print(shape._sp.xml)
# -- save document and adjust shape to trigger alignment, then reopen it --
# -- locate shape --
shape = presentation.slides[0].shapes[0]
print(shape._sp.xml)

If you do that and post the before and after (nicely formatted please) I'll take a look.

RamadiRat commented 9 months ago

Appreciate the assist, this is my current code (not sure I implemented the auto_size property correctly)

Current code snippet txBox = sl_1.shapes.add_textbox(Inches(.25), Inches(1), Inches(3), Inches(3)) print(txBox._sp.xml) tf = txBox.text_frame

print(tf.dir())

p = tf.paragraphs[0] p.alignment = PP_ALIGN.CENTER run = p.add_run() run.text = "External Threat Assessment Summary" font = run.font font.name = "Univers" font.size = Pt(32) font.bold = False font.color.rgb = RGBColor(255,255,255) tf.auto_size = MSO_AUTO_SIZE.TEXT_TO_FIT_SHAPE

txBox = sl_1.shapes[0] print(txBox._sp.xml)

Here is the output from those print statements

<p:sp xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  <p:nvSpPr>
    <p:cNvPr id="3" name="TextBox 2"/>
    <p:cNvSpPr txBox="1"/>
    <p:nvPr/>
  </p:nvSpPr>
  <p:spPr>
    <a:xfrm>
      <a:off x="228600" y="914400"/>
      <a:ext cx="2743200" cy="2743200"/>
    </a:xfrm>
    <a:prstGeom prst="rect">
      <a:avLst/>
    </a:prstGeom>
    <a:noFill/>
  </p:spPr>
  <p:txBody>
    <a:bodyPr wrap="none">
      <a:spAutoFit/>
    </a:bodyPr>
    <a:lstStyle/>
    <a:p/>
  </p:txBody>
</p:sp>
<p:sp xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  <p:nvSpPr>
    <p:cNvPr id="2" name="Rectangle 1"/>
    <p:cNvSpPr/>
    <p:nvPr/>
  </p:nvSpPr>
  <p:spPr>
    <a:xfrm>
      <a:off x="0" y="0"/>
      <a:ext cx="2971800" cy="6300216"/>
    </a:xfrm>
    <a:prstGeom prst="rect">
      <a:avLst/>
    </a:prstGeom>
    <a:solidFill>
      <a:srgbClr val="072E42"/>
    </a:solidFill>
    <a:ln>
      <a:solidFill>
        <a:srgbClr val="072E42"/>
      </a:solidFill>
    </a:ln>
    <a:effectLst/>
  </p:spPr>
  <p:style>
    <a:lnRef idx="1">
      <a:schemeClr val="accent1"/>
    </a:lnRef>
    <a:fillRef idx="3">
      <a:schemeClr val="accent1"/>
    </a:fillRef>
    <a:effectRef idx="2">
      <a:schemeClr val="accent1"/>
    </a:effectRef>
    <a:fontRef idx="minor">
      <a:schemeClr val="lt1"/>
    </a:fontRef>
  </p:style>
  <p:txBody>
    <a:bodyPr rtlCol="0" anchor="ctr"/>
    <a:lstStyle/>
    <a:p>
      <a:pPr algn="ctr"/>
    </a:p>
  </p:txBody>
</p:sp>
RamadiRat commented 9 months ago

I seem to have figured this out, as my alignment/center was working, I needed tf.word_wrap = True

scanny commented 9 months ago

Mmm, that sounds vaguely familiar now that you mention it :)

The <a:bodyPr wrap="none"> wrap attribute seems to have been the culprit :)