Esta es la primera vez que publico aquí, quiero escribir un script que tome un docx como entrada y seleccione ciertos párrafos (incluidas tablas e imágenes) para copiar en el mismo orden en otro documento de plantilla (no al final). El problema que tengo es que cuando empiezo a iterar sobre los elementos, mi código no puede detectar las imágenes, por lo tanto, no puedo determinar dónde está una imagen en relación con el texto y las tablas ni qué imagen es. En resumen, obtuve doc1 con: TEXT IMAGE TEXT TABLE TEXT

Y con lo que termino es: TEXTO [FALTA DE IMAGEN] TEXTO TABLA TEXTO

Lo que llegué hasta ahora:

-Puedo iterar sobre los párrafos y las tablas:

def iter_block_items(parent):
"""
Generate a reference to each paragraph and table child within *parent*,
in document order. Each returned value is an instance of either Table or
Paragraph. *parent* would most commonly be a reference to a main
Document object, but also works for a _Cell object, which itself can
contain paragraphs and tables.
"""
if isinstance(parent, _Document):
    parent_elm = parent.element.body
    # print(parent_elm.xml)
elif isinstance(parent, _Cell):
    parent_elm = parent._tc
else:
    raise ValueError("something's not right")

for child in parent_elm.iterchildren():
    if isinstance(child, CT_P):
        yield Paragraph(child, parent)
    elif isinstance(child, CT_Tbl):
        yield Table(child, parent)

Puedo obtener una lista ordenada de las imágenes de un documento:

pictures = []
for pic in dwo.inline_shapes:
    if pic.type == WD_INLINE_SHAPE.PICTURE:
        pictures.append(pic)

Puedo insertar al final de un párrafo una imagen específica:

def insert_picture(index, paragraph):
    inline = pictures[index]._inline
    rId = inline.xpath('./a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip/@r:embed')[0]
    image_part = dwo.part.related_parts[rId]
    image_bytes = image_part.blob
    image_stream = BytesIO(image_bytes)
    paragraph.add_run().add_picture(image_stream, Inches(6.5))
    return

Yo uso la función iter_block_items () así:

start_copy = False
for block in iter_block_items(document):
    if isinstance(block, Paragraph):
        if block.text == "TEXT FROM WHERE WE STOP COPYING":
            break

    if start_copy:
        if isinstance(block, Paragraph):
            last_paragraph = insert_paragraph_after(last_paragraph,block.text)

        elif isinstance(block, Table):
            paragraphs_with_table.append(last_paragraph)
            tables_to_apppend.append(block._tbl)

    if isinstance(block, Paragraph):
        if block.text == ""TEXT FROM WHERE WE START COPYING":
            start_copy = True
2
RES 16 oct. 2018 a las 17:57

2 respuestas

La mejor respuesta

Encontré una manera de hacerlo, resulta que las imágenes que quería ordenar ya estaban dentro de los párrafos como inline.shape. Usé esto: enlace para extraer las imágenes, y luego las inserté usando una versión modificada de

def insert_picture(index, paragraph): 

Donde en lugar de índice usaría rId.

0
RES 17 oct. 2018 a las 14:23

Puede encontrar una implementación funcional de esto que hace exactamente lo mismo en el siguiente enlace:

Extracción de paras, tablas e imágenes en orden de documentos

0
Karthick Mohanraj 22 oct. 2019 a las 18:13