Skip to content

Lists showing up as normal paragraphs #217

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
johnzupancic opened this issue Oct 16, 2015 · 6 comments
Open

Lists showing up as normal paragraphs #217

johnzupancic opened this issue Oct 16, 2015 · 6 comments

Comments

@johnzupancic
Copy link

I am trying to insert numeric and bulleted lists into an existing Word document, however they are showing up as normal paragraphs:

# Open up existing document
document = Document('existing_document.docx')

# Add style from example document
temp_doc = Document()
document.styles.add_style('List Number', temp_doc.styles['List Number'].type)

# Add bullet points from example document
p = document.add_paragraph()
p.style = 'List Number'
p.add_run('Item 1')
p = document.add_paragraph()
p.style = 'List Number'
p.add_run('Item 2')

# Save
document.save('new_doc_with_list.docx')

This results in 2 paragraphs. No indenting or numbering.

I have also tried to set up all the attributes the same, and then complete the runs, however this does not work either:

document.styles['List Number'].base_style = temp_doc.styles['List Number'].base_style
document.styles['List Number'].next_paragraph_style = temp_doc.styles['List Number'].next_paragraph_style
document.styles['List Number'].paragraph_format.alignment = temp_doc.styles['List Number'].paragraph_format.alignment
document.styles['List Number'].paragraph_format.first_line_indent = temp_doc.styles['List Number'].paragraph_format.first_line_indent
document.styles['List Number'].paragraph_format.keep_together = temp_doc.styles['List Number'].paragraph_format.keep_together
document.styles['List Number'].paragraph_format.keep_with_next = temp_doc.styles['List Number'].paragraph_format.keep_with_next
document.styles['List Number'].paragraph_format.left_indent = temp_doc.styles['List Number'].paragraph_format.left_indent
document.styles['List Number'].paragraph_format.line_spacing = temp_doc.styles['List Number'].paragraph_format.line_spacing
document.styles['List Number'].paragraph_format.line_spacing_rule = temp_doc.styles['List Number'].paragraph_format.line_spacing_rule
document.styles['List Number'].paragraph_format.page_break_before = temp_doc.styles['List Number'].paragraph_format.page_break_before
document.styles['List Number'].paragraph_format.right_indent = temp_doc.styles['List Number'].paragraph_format.right_indent
document.styles['List Number'].paragraph_format.space_after = temp_doc.styles['List Number'].paragraph_format.space_after
document.styles['List Number'].paragraph_format.space_before = temp_doc.styles['List Number'].paragraph_format.space_before
document.styles['List Number'].paragraph_format.widow_control = temp_doc.styles['List Number'].paragraph_format.widow_control
document.styles['List Number'].priority = temp_doc.styles['List Number'].priority
document.styles['List Number'].locked = temp_doc.styles['List Number'].locked
document.styles['List Number'].font.all_caps = temp_doc.styles['List Number'].font.all_caps
document.styles['List Number'].font.bold = temp_doc.styles['List Number'].font.bold
document.styles['List Number'].font.complex_script = temp_doc.styles['List Number'].font.complex_script
document.styles['List Number'].font.cs_bold = temp_doc.styles['List Number'].font.cs_bold
document.styles['List Number'].font.cs_italic = temp_doc.styles['List Number'].font.cs_italic
document.styles['List Number'].font.double_strike = temp_doc.styles['List Number'].font.double_strike
document.styles['List Number'].font.emboss = temp_doc.styles['List Number'].font.emboss
document.styles['List Number'].font.hidden = temp_doc.styles['List Number'].font.hidden
document.styles['List Number'].font.imprint = temp_doc.styles['List Number'].font.imprint
document.styles['List Number'].font.italic = temp_doc.styles['List Number'].font.italic
document.styles['List Number'].font.math = temp_doc.styles['List Number'].font.math
document.styles['List Number'].font.name = temp_doc.styles['List Number'].font.name
document.styles['List Number'].font.no_proof = temp_doc.styles['List Number'].font.no_proof
document.styles['List Number'].font.outline = temp_doc.styles['List Number'].font.outline
document.styles['List Number'].font.rtl = temp_doc.styles['List Number'].font.rtl
document.styles['List Number'].font.shadow = temp_doc.styles['List Number'].font.shadow
document.styles['List Number'].font.size = temp_doc.styles['List Number'].font.size
document.styles['List Number'].font.small_caps = temp_doc.styles['List Number'].font.small_caps
document.styles['List Number'].font.snap_to_grid = temp_doc.styles['List Number'].font.snap_to_grid
document.styles['List Number'].font.spec_vanish = temp_doc.styles['List Number'].font.spec_vanish
document.styles['List Number'].font.strike = temp_doc.styles['List Number'].font.strike
document.styles['List Number'].font.subscript = temp_doc.styles['List Number'].font.subscript
document.styles['List Number'].font.superscript = temp_doc.styles['List Number'].font.superscript
document.styles['List Number'].font.underline = temp_doc.styles['List Number'].font.underline
document.styles['List Number'].font.web_hidden = temp_doc.styles['List Number'].font.web_hidden
document.styles['List Number'].quick_style = temp_doc.styles['List Number'].quick_style
document.styles['List Number'].style_id = temp_doc.styles['List Number'].style_id

Did I miss anything for indenting or numbering? I'd also be interested in learning how to do this for an unordered list too.

@panoptical
Copy link

John,
I was able to create bullet and numbered lists using this code:

from docx import Document
from docx.shared import Inches
from docx.oxml import OxmlElement
from docx.oxml.ns import qn

def create_list(paragraph, list_type):
    p = paragraph._p #access to xml paragraph element
    pPr = p.get_or_add_pPr() #access paragraph properties
    numPr = OxmlElement('w:numPr') #create number properties element
    numId = OxmlElement('w:numId') #create numId element - sets bullet type
    numId.set(qn('w:val'), list_type) #set list type/indentation
    numPr.append(numId) #add bullet type to number properties list
    pPr.append(numPr) #add number properties to paragraph

ordered = "5"
unordered = "1"

document = Document()

paragraph = document.add_paragraph("Hello", "List Paragraph")
create_list(paragraph, unordered)

paragraph = document.add_paragraph("Hello Again", "List Paragraph")
create_list(paragraph, unordered)

paragraph = document.add_paragraph("Goodbye", "List Paragraph")
create_list(paragraph, unordered)

paragraph = document.add_paragraph("Hello", "List Paragraph")
create_list(paragraph, ordered)

paragraph = document.add_paragraph("Hello Again", "List Paragraph")
create_list(paragraph, ordered)

paragraph = document.add_paragraph("Goodbye", "List Paragraph")
create_list(paragraph, ordered)

document.save("bullet list demo.docx")

The list style is called "List Paragraph" and the type of bullet is set by adding the appropriate XML elements. python-docx apparently creates a default "numbering" XML document which governs the styles and indentation of list items; the list_type I put into numId is a reference to that document.

YMMV, I don't know that this is the best way to do this, but it works...

@berezovskyi
Copy link

And thanks for the great work, @scanny!

@scanny
Copy link
Contributor

scanny commented Nov 18, 2015

:)

@andrewcardno
Copy link

This is wonderful and works.
I have one question, I notice that the bullets are always on the left hand margin. Do you know how to indent them?

@Hendrik-Rummens
Copy link

Hendrik-Rummens commented May 30, 2022

Both 'ordererd' and 'unordered' give me an Ordered list in return. Any idea why this is happening?

@grosin-deloitte
Copy link

Both 'ordererd' and 'unordered' give me an Ordered list in return. Any idea why this is happening?

Switching the number ids from "1" to "6" for unordered version gave me bullet points correctly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants