Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add Bullet list using python-pptx

I am using the python-pptx library for pptx manipulation. I want to add a bullet list in the pptx document.

I am using the following snippet to add list item:

p = text_frame.add_paragraph()
run = p.add_run()
p.level = 0
run.text = "First"

But it does not display bullet points; please guide.

like image 854
Navdeep Singh Avatar asked Jul 27 '26 17:07

Navdeep Singh


1 Answers

This question is still up to date on May 27, 2021. Following up on @OD1995's answer I would like to add a little more detail as well as my turn on the problem.

I created a new package with the following code:

from pptx.oxml.xmlchemy import OxmlElement


def getBulletInfo(paragraph, run=None):
    """Returns the attributes of the given <a:pPr> OxmlElement
    as well as its runs font-size.

    *param: paragraph* pptx _paragraph object
    *param: run* [optional] specific _run object
    """
    pPr = paragraph._p.get_or_add_pPr()
    if run is None:
        run = paragraph.runs[0]
    p_info = {
        "marL": pPr.attrib['marL'],
        "indent": pPr.attrib['indent'],
        "level": paragraph.level,
        "fontName": run.font.name,
        "fontSize": run.font.size,
    }
    return p_info


def SubElement(parent, tagname, **kwargs):
    """Helper for Paragraph bullet Point
    """
    element = OxmlElement(tagname)
    element.attrib.update(kwargs)
    parent.append(element)
    return element


def pBullet(
    paragraph,  # paragraph object
    font,  # fontName of that needs to be applied to bullet
    marL='864000',
    indent='-322920',
    size='350000'  # fontSize (in )
):
    """Bullets are set to Arial,
    actual text can be a different font
    """
    pPr = paragraph._p.get_or_add_pPr()
    # Set marL and indent attributes
    # Indent is the space between the bullet and the text.
    pPr.set('marL', marL)
    pPr.set('indent', indent)
    # Add buFont
    _ = SubElement(parent=pPr,
                   tagname="a:buSzPct",
                   val="350000"
                   )
    _ = SubElement(parent=pPr,
                   tagname="a:buFont",
                   typeface=font,
                   # panose="020B0604020202020204",
                   # pitchFamily="34",
                   # charset="0"
                   )
    # Add buChar
    _ = SubElement(parent=pPr,
                   tagname='a:buChar',
                   char="•"
                   )

The reason I did this is because I was frustrated that the bullet character was not of the same size as the original and the text was stuck to the bullet.

getBulletInfo() allows me to retrieve information from an existing paragraph. I use this information to populate the element's attributes (so that it is identical to the template).

Anyways the main add-on is the creation of a sub-element <a:buSzPct> (documentation here and here). This is a size percentage that can go from 25% to 350% (100000 = 100%).

like image 156
Nootaku Avatar answered Jul 29 '26 06:07

Nootaku



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!