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 3 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.
Bulleted and Numbered lists in Word are more complicated than other styles. They need to be linked to a numbering format, which is quite complex in itself, and not yet supported at the API level in python-docx.
If you can use a "template" document as a starting point that has the list styles you need already defined, that will work, but of course that's not suitable for every use case.
I have not be able to find a solution that worked for my problem that was similar to this by editing or working with the styles and I do not understand why lists follow the formatting for paragraphs. I think they should have there own. Either way, I created a class that works around the issue and builds the list I want them. It is not perfect and I am sure that others can really improve what I have done, but I thought I would share.
import docx
class Paragraph_List(object):
def __init__(self,*args): #args are: doc,item1,ordered,style,fmt (style and fmt optional)
self.args = args
self.doc =self.args[0]
self.item1 = self.args[1]
self.ordered = self.args[2]
self.place = {}
List_dict = {'Roman':[['I','II','III','IV','V','VI','VII','VIII','IIX','IX','X'],['A','B','C','D','E','F',
'G','H','I','J','K','L'],['1','2','3','4','5','6','7','8','9','10'],['a','b','c','d','e','f','g','h',
'i'],['i','ii','iii','iv','v','vi','vii','viii','iix','ix','x']],'ABC':[['A','B','C','D','E','F','G',
'H','I','J','K','L'],['1','2','3','4','5','6','7','8','9','10'],['a','b','c','d','e','f','g','h','i'],
['i','ii','iii','iv','v','vi','vii','viii','iix','ix','x']],'123':[['1','2','3','4','5','6','7','8','9','10'
],['a','b','c','d','e','f','g','h','i'],['i','ii','iii','iv','v','vi','vii','viii','iix','ix','x']],'Bullet':[
['●','○','•','◦']]}
if self.ordered == True:
if len(self.args) < 4:
self.fmt = List_dict['Roman']
elif self.args[3] == 'Custom':
self.fmt = self.args[4]
else:
self.fmt = List_dict[self.args[3]]
self.p = self.doc.add_paragraph(self.fmt[0][0]+'. ' + self.item1 + '\n')
else:
self.fmt = List_dict['Bullet']
self.p = self.doc.add_paragraph(self.fmt[0][0]+ ' ' + self.item1 + '\n')
# self.doc.add_paragraph(item1, style=self.level)
def add_item(self, item, level):
self.level = level
self.place[1] = 0
if self.level ==1:
sp = ""
else:
sp = " "
sp = sp *(self.level -1)
if self.level in self.place:
self.place[self.level] += 1
else:
self.place[self.level] = 0
if self.ordered ==True:
self.p.add_run(sp + self.fmt[self.level - 1][self.place[self.level]] + '. ' + item + '\n')
else:
self.p.add_run(sp + self.fmt[0][self.level - 1]+ ' ' + item + '\n')
#Main Body==================================================================================================
document = docx.Document()
mylist = Paragraph_List(document, 'item 1', True)
mylist.add_item('Level 2 Item 1',2)
mylist.add_item('Level 2 Item 2',2)
mylist.add_item('Level 2 Item 3',2)
mylist.add_item('Level 3 Item 1',3)
mylist.add_item('Level 3 Item 2',3)
mylist.add_item('Level 3 Item 3',3)
mylist.add_item('Level 3 Item 4',3)
mylist.add_item('Level 3 Item 5',3)
mylist.add_item('Level 1 Item 2',1)
mylist2 = Paragraph_List(document, 'Bullet Level 1 Item 1', False)
mylist2.add_item('Level 1 Item2',1)
mylist2.add_item('Level 2 Item1',2)
mylist2.add_item('Level 1 Item3',1)
mylist2.add_item('Level 2 Item1',2)
mylist2.add_item('Level 2 Item2',2)
mylist2.add_item('Level 2 Item3',2)
mylist2.add_item('Level 3 Item1',3)
mylist2.add_item('Level 4 Item1',4)
mylist2.add_item('Level 4 Item2',4)
mylist2.add_item('Level 2 Item4',2)
document.save('new.docx')
来源:https://stackoverflow.com/questions/33158991/python-docx-lists-showing-up-as-normal-paragraphs