Search code examples
python-3.xpython-docx

Issues with font and table python-docx module


Python = 3.8.3 Python-Docx = 0.8.10

I'm currently trying to make a present/surprise for my wife by coding my first project which would ease her work load by automating her writing assessments (currently learning python since 6 months).

Long story short, she is writing assessments on word docx documents based on marks from different aptitudes. My idea is to make input template sorted by Aptitude ( A,B,C,D ...... ) and each template would contain the block of text according to the mark (low score , average, high score).

I did some research and find out the python-Docx module that I could use to automate a copy of my input document's template to a final output documents.

While doing my project I'm currently facing two big issues, first I can't keep the original font that she is using (Helvetica for titles and Garamond for text), the second issue is that, she has some tables in her documents that I can't copy either.

So far I managed to copy the correct block of text according to the mark and also keeping the bold, italic and underline but not the font nor the tables.

I've been reading the python-docx manual online but I don't really see where I could fix those 2.

here is a sample of my code:

import os
import sys
from docx import Document
from docxtpl import DocxTemplate

# Imports
inputM01acgti = Document(
    '/home/rvera/ubuntuShare/python_Projects/docx_tpl/M-01-ACG-TI-02.docx')


 # Output document
output_doc = Document()


# Function to get proper format of original templates
def get_para_data(output_doc_name, paragraph):

    output_para = output_doc_name.add_paragraph()
    for run in paragraph.runs:
        output_run = output_para.add_run(run.text)
        # Run's bold data
        output_run.bold = run.bold
        # Run's italic data
        output_run.italic = run.italic
        # Run's underline data
        output_run.underline = run.underline
        # Run's color data
        output_run.font.color.rgb = run.font.color.rgb
        # Run's font data
        output_run.style.name = run.style.name
        # Paragraph's alignment data
        output_para.paragraph_format.alignment = paragraph.paragraph_format.alignment


# Function for Male Assement
def maleAssement():
    print('Aptitude Cognitive Globale')
    acgMark = int(input('Please enter a number: '))
    if 0 <= acgMark < 2:
        paragraphs_acg = inputM01acgti.paragraphs

    elif 2 <= acgMark < 16:
        paragraphs_acg = inputM01acgmi.paragraphs

    elif 16 <= acgMark < 86:
        paragraphs_acg = inputM01acgm.paragraphs

    elif 16 <= acgMark < 98:
        paragraphs_acg = inputM01acgms.paragraphs

    elif 98 <= acgMark <= 100:
        paragraphs_acg = inputM01acgts.paragraphs

    else:
        print('Your number is not between 0 and 100, try again..')

    for para in paragraphs_acg:
        get_para_data(output_doc, para)

As you can see I'm going through different runs in order to keep my input document's style but I'm missing on the font and tables.

Is anyone could help me on this ?

Thanks a lot!

Xzi.


Solution

  • Here is the proper way to keep both font and font size :

    # Function to get proper format of original templates
    

    def get_para_data(output_doc_name, paragraph):

    output_para = output_doc_name.add_paragraph()
    for run in paragraph.runs:
        output_run = output_para.add_run(run.text)
        # Run's bold data
        output_run.bold = run.bold
        # Run's italic data
        output_run.italic = run.italic
        # Run's underline data
        output_run.underline = run.underline
        # Run's color data
        output_run.font.color.rgb = run.font.color.rgb
        # Run's font
        output_run.font.name = run.font.name
        # Run's font size
        output_run.font.size = run.font.size
        # Run's font data
        output_run.style.name = run.style.name
    
        # Paragraph's alignment data
        #output_para.style = paragraph.style
        #output_para.alignment = paragraph.alignment
        output_para.paragraph_format.alignment = paragraph.paragraph_format.alignment
        #output_para.paragraph_format.widow_control = paragraph.paragraph_format.widow_control