2017-01-10 29 views
9

Jako przykład, mam rodzajowe skrypt, który wyprowadza domyślne style tabeli przy użyciu python-docx (ten kod działa poprawnie):Jak zachować wiersze tabeli w python-docx?

import docx 
d=docx.Document() 
type_of_table=docx.enum.style.WD_STYLE_TYPE.TABLE 

list_table=[['header1','header2'],['cell1','cell2'],['cell3','cell4']] 
numcols=max(map(len,list_table)) 
numrows=len(list_table) 

styles=(s for s in d.styles if s.type==type_of_table) 


for stylenum,style in enumerate(styles,start=1): 
    label=d.add_paragraph('{}) {}'.format(stylenum,style.name)) 
    label.paragraph_format.keep_with_next=True 
    label.paragraph_format.space_before=docx.shared.Pt(18) 
    label.paragraph_format.space_after=docx.shared.Pt(0) 
    table=d.add_table(numrows,numcols) 
    table.style=style 
    for r,row in enumerate(list_table): 
     for c,cell in enumerate(row): 
      table.row_cells(r)[c].text=cell 


d.save('tablestyles.docx') 

Dalej, otworzyłem dokument, podkreślił tabelę podziału i pod formatu akapitu, wybrany „Trzymaj się z następnym”, która skutecznie zapobiega tabelę przed podzielone w poprzek strony:

enter image description here

Oto kod XML non-złamane tabeli:

enter image description here

Zobaczysz, że podświetlona linia pokazuje właściwość akapitu, która powinna przechowywać tabelę razem. Więc napisałem tę funkcję i wsadził go w kodzie powyżej d.save('tablestyles.docx') line:

def no_table_break(document): 
    tags=document.element.xpath('//w:p') 
    for tag in tags: 
     ppr=tag.get_or_add_pPr() 
     ppr.keepNext_val=True 


no_table_break(d)  

Kiedy sprawdzać kod XML tag nieruchomość ustęp jest ustawiony prawidłowo i gdy otwieram dokument słowem, „Keep z next” pole jest zaznaczone dla wszystkich tabel, ale tabela jest nadal podzielona na strony. Czy brakuje mi tagu XML lub czegoś, co uniemożliwia mu prawidłowe działanie?

+0

Myślę, że będziesz musiał dokładniej opisać, czym jest "osierocony" wiersz. Następnym krokiem będzie sprawdzenie, czy możesz osiągnąć wynik, po użyciu aplikacji/interfejsu użytkownika programu Word. Jeśli możesz zawęzić to w ten sposób, możesz określić element/atrybut XML, który robi różnicę. 'w: cantSplit' może określić, czy komórka jest podzielona na strony (oczywiście z jej rzędem). – scanny

+0

@scanny Wszystko co mam na myśli przez osierocony rząd, to ta część stołu znajduje się na jednej stronie, a druga część stołu na innej. – LMc

+0

Pytanie dotyczy tego, czy przerwa znajduje się na granicy równego rzędu, czy jest zerwana w rzędzie, podobnie jak część wiersza na jednej stronie, a reszta na górze następnej strony. Są to różne (złe) zachowania. – scanny

Odpowiedz

1

Możesz sprawdzić, czy tabela zostanie przecięta z podziałem strony i wymusić nową przed utworzeniem nowej tabeli.

import docx 

MAX_PAGE_SIZE = 80 

d=docx.Document() 
type_of_table=docx.enum.style.WD_STYLE_TYPE.TABLE 

list_table=[['header1','header2'],['cell1','cell2'],['cell3','cell4']] 
numcols=max(map(len,list_table)) 
numrows=len(list_table) 

styles=(s for s in d.styles if s.type==type_of_table) 

current_page_row = 0 

for stylenum,style in enumerate(styles,start=1): 
    # calc the last row for this new style 
    next_last_row = current_page_row + numrows + 1 

    # add page break if needed and reset the page row 
    if next_last_row > MAX_PAGE_SIZE: 
     d.add_page_break() 
     current_page_row = 0 

    label=d.add_paragraph('{}) {}'.format(stylenum,style.name)) 
    # update the current page row counter 
    current_page_row += 1 

    label.paragraph_format.keep_with_next=True 
    label.paragraph_format.space_before=docx.shared.Pt(18) 
    label.paragraph_format.space_after=docx.shared.Pt(0) 

    table=d.add_table(numrows,numcols) 
    table.style=style 
    for r,row in enumerate(list_table): 
     for c,cell in enumerate(row): 
      table.row_cells(r)[c].text=cell 

    # update the current page row counter with the table size 
    current_page_row += numrows 

d.save('ctablestyles.docx')