как узнать, когда новый абзац в python-docx вызывает новую страницу - PullRequest
0 голосов
/ 25 января 2019

Мне нужно динамически создавать текстовые документы, используя python-docx .Я делаю это путем динамического добавления строк таблицы, и нет способа узнать, сколько записей помещается на странице, поскольку это зависит от конкретных данных.

Мне нужно знать, когда новый элемент добавляется в документ (таблицастрока или абзац) вызывает новую страницу, поэтому я могу записать некоторые данные в базу данных в соответствии с информацией, содержащейся на каждой странице.

Это код для генерации документа Word с помощью python-docx :

def get_invoice_word_report(self, request, invoices_controllers):
    import unicodedata
    from django.core.files import File
    from docx import Document
    from docx.shared import Inches, Pt
    from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_BREAK
    from docx.enum.table import WD_ALIGN_VERTICAL
    from docx.enum.table import WD_TABLE_ALIGNMENT

    document = Document()

    section = document.sections[-1]
    section.left_margin = Inches(0.5)
    section.right_margin = Inches(0.5)

    style = document.styles['Normal']
    font = style.font
    font.name ='Arial'
    font.size = Pt(8)

    i = 0
    for invoices_controller in invoices_controllers:
        context = invoices_controller.get_context()
        if i > 0:
            run.add_break(WD_BREAK.PAGE)
            if i == len(invoices_controllers) - 1:
                last = context['invoices']['invoice_number']
        else:
            first = context['invoices']['invoice_number']

        document.add_paragraph("Invoice".format(context['invoices']['invoice_number'])).alignment = WD_ALIGN_PARAGRAPH.RIGHT
        document.add_paragraph("Folio {}".format(context['invoices']['invoice_number'])).alignment = WD_ALIGN_PARAGRAPH.RIGHT
        document.add_paragraph(context['invoices']['agency']['company']['name'])
        document.add_paragraph(context['invoices']['agency']['company']['address'])
        date = context['invoices']['period_end_date'].split('-')
        document.add_paragraph("{}      {}      {}".format(date[2], date[1], date[0])).alignment = WD_ALIGN_PARAGRAPH.RIGHT
        document.add_paragraph(context['invoices']['line'])
        document.add_paragraph(context['invoices']['text'])

        table = document.add_table(rows=1, cols=4)
        hdr_cells = table.rows[0].cells

        hdr_cells[0].width = Inches(0.1)
        hdr_cells[1].width = Inches(10)
        hdr_cells[2].width = Inches(1)
        hdr_cells[3].width = Inches(1)

        for entry in context['invoices']['entries']:
            row_cells = table.add_row().cells
            row_cells[0].text = str(entry['amount'])
            row_cells[1].text = entry['line']
            row_cells[2].text = entry['unit_price_label']
            row_cells[2].paragraphs[0].alignment= WD_ALIGN_PARAGRAPH.RIGHT
            row_cells[3].text = entry['subtotal']
            row_cells[3].paragraphs[0].alignment= WD_ALIGN_PARAGRAPH.RIGHT

            if entry['text']:
                text_cells = table.add_row().cells
                text_cells[1].text = entry['text']

        row_cells = table.add_row().cells
        row_cells[0].text = ''
        row_cells[1].text = ''
        row_cells[2].text = ''
        row_cells[3].text = context['total']
        row_cells[3].paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.RIGHT

        row_cells = table.add_row().cells
        row_cells[0].text = ''
        row_cells[1].text = ''
        row_cells[2].text = ''
        row_cells[3].text = '$0.00'
        row_cells[3].paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.RIGHT

        row_cells = table.add_row().cells
        row_cells[0].text = ''
        row_cells[1].text = ''
        row_cells[2].text = ''
        row_cells[3].text = context['total']
        row_cells[3].paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.RIGHT

        run = document.add_paragraph("Son {}".format(context['total_text'])).add_run()
        i += 1

    current_directory = settings.MEDIA_DIR
    if len(invoices_controllers) > 1:
        file_name = "Invoices {}-{}.docx".format(first, last)
    else:
        file_name = "Invoice {}.docx".format(first)
    document.save(current_directory + file_name)

    return request.get_host()+ settings.MEDIA_URL + file_name

Спасибо за помощь.

1 Ответ

0 голосов
/ 25 января 2019

Обнаружение автоматических (генерируемых рендерером) разрывов страниц в python-docx невозможно, поскольку эти разрывы ненадежно записываются в XML.

Возможно, вы сможете найти некоторую индикациюпоследнего обработанного разрыва страницы, в зависимости от того, откуда пришли ваши файлы .docx.В противном случае вам, вероятно, потребуется использовать интерфейс Microsoft VBA, чтобы получить доступ к живому рендереру, который может предоставить вам эту информацию.Обратите внимание, что местоположение разрыва страницы может меняться в зависимости от того, на каком компьютере работает Word, в зависимости от таких факторов, как метрики шрифта и драйверы принтера.

Это встречается в других вопросах и ответах.Это может быть хорошим местом для начала: Номер страницы python-docx

Чтобы увидеть остальное, поищите в «[python-docx] page break», и вы увидите, что естьдовольно много.Часть в квадратных скобках ограничивает результаты теми, которые помечены как «python-docx».

...